Store flag for artificial bounary edges and walk border nodes in ebg
This commit is contained in:
parent
5015e12d59
commit
e589ab814d
@ -23,7 +23,7 @@ struct EdgeBasedGraphEdgeData
|
|||||||
NodeID edge_id : 31;
|
NodeID edge_id : 31;
|
||||||
// Artificial edge used to fixup partitioning, see #3205.
|
// Artificial edge used to fixup partitioning, see #3205.
|
||||||
// These artificial edges have invalid weight / duration.
|
// These artificial edges have invalid weight / duration.
|
||||||
std::uint32_t is_boundary_arc : 1;
|
bool is_boundary_arc : 1;
|
||||||
EdgeWeight weight;
|
EdgeWeight weight;
|
||||||
EdgeWeight duration : 30;
|
EdgeWeight duration : 30;
|
||||||
std::uint32_t forward : 1;
|
std::uint32_t forward : 1;
|
||||||
@ -140,7 +140,6 @@ struct EdgeBasedGraphReader
|
|||||||
forward_edge.data.forward = reverse_edge.data.backward = true;
|
forward_edge.data.forward = reverse_edge.data.backward = true;
|
||||||
forward_edge.data.backward = reverse_edge.data.forward = false;
|
forward_edge.data.backward = reverse_edge.data.forward = false;
|
||||||
|
|
||||||
|
|
||||||
// remove parallel edges
|
// remove parallel edges
|
||||||
while (i < edges.size() && edges[i].source == source && edges[i].target == target)
|
while (i < edges.size() && edges[i].source == source && edges[i].target == target)
|
||||||
{
|
{
|
||||||
|
@ -156,8 +156,7 @@ int Partitioner::Run(const PartitionConfig &config)
|
|||||||
|
|
||||||
const auto &partition_ids = recursive_bisection.BisectionIDs();
|
const auto &partition_ids = recursive_bisection.BisectionIDs();
|
||||||
|
|
||||||
// Keyed by ebg node - stores flag if ebg node is border node or not.
|
std::vector<NodeID> edge_based_border_nodes;
|
||||||
std::vector<bool> is_edge_based_border_node(edge_based_graph->GetNumberOfNodes());
|
|
||||||
|
|
||||||
// Extract edge based border nodes, based on node based partition and mapping.
|
// Extract edge based border nodes, based on node based partition and mapping.
|
||||||
for (const auto node_id : util::irange(0u, edge_based_graph->GetNumberOfNodes()))
|
for (const auto node_id : util::irange(0u, edge_based_graph->GetNumberOfNodes()))
|
||||||
@ -170,45 +169,41 @@ int Partitioner::Run(const PartitionConfig &config)
|
|||||||
if (partition_ids[u] == partition_ids[v])
|
if (partition_ids[u] == partition_ids[v])
|
||||||
{
|
{
|
||||||
// Can use partition_ids[u/v] as partition for edge based graph `node_id`
|
// Can use partition_ids[u/v] as partition for edge based graph `node_id`
|
||||||
is_edge_based_border_node[node_id] = false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Border nodes u,v - need to be resolved. What we can do:
|
// Border nodes u,v - need to be resolved.
|
||||||
// - 1) Pick one of the partitions randomly or by minimizing border edges.
|
edge_based_border_nodes.push_back(node_id);
|
||||||
// - 2) Or: modify edge based graph, introducing artificial edges. We do this.
|
|
||||||
is_edge_based_border_node[node_id] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto num_border_nodes =
|
util::Log() << "Fixing " << edge_based_border_nodes.size() << " edge based graph border nodes";
|
||||||
std::count(begin(is_edge_based_border_node), end(is_edge_based_border_node), true);
|
|
||||||
|
|
||||||
util::Log() << "Fixing " << num_border_nodes << " edge based graph border nodes";
|
std::vector<std::pair<NodeID, EdgeBasedGraphEdgeData>> incoming_edges;
|
||||||
|
|
||||||
// Keyed by ebg node - stores associated border nodes for nodes
|
for (const auto border_node : edge_based_border_nodes)
|
||||||
std::unordered_map<NodeID, NodeID> edge_based_border_node;
|
|
||||||
edge_based_border_node.reserve(num_border_nodes);
|
|
||||||
|
|
||||||
// For all edges in the edge based graph: if they start and end in different partitions
|
|
||||||
// introduce artificial nodes and re-wire incoming / outgoing edges to these artificial ones.
|
|
||||||
for (const auto source : util::irange(0u, edge_based_graph->GetNumberOfNodes()))
|
|
||||||
{
|
{
|
||||||
for (auto edge : edge_based_graph->GetAdjacentEdgeRange(source))
|
for (const auto edge : edge_based_graph->GetAdjacentEdgeRange(border_node))
|
||||||
{
|
{
|
||||||
const auto target = edge_based_graph->GetTarget(edge);
|
const auto &data = edge_based_graph->GetEdgeData(edge);
|
||||||
|
|
||||||
const auto opposite_edge = edge_based_graph->FindEdge(target, source);
|
if (data.backward)
|
||||||
|
{
|
||||||
if (!is_edge_based_border_node[source] || !is_edge_based_border_node[target])
|
incoming_edges.emplace_back(edge_based_graph->GetTarget(edge), data);
|
||||||
continue;
|
edge_based_graph->DeleteEdge(border_node, edge);
|
||||||
|
}
|
||||||
// TODO: assign and store partition ids to new nodes
|
|
||||||
|
|
||||||
const auto artificial_node = edge_based_graph->InsertNode();
|
|
||||||
|
|
||||||
EdgeBasedGraphEdgeData dummy{SPECIAL_EDGEID, /*is_boundary_arc=*/1, 0, 0, false, false};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto artificial = edge_based_graph->InsertNode();
|
||||||
|
|
||||||
|
EdgeBasedGraphEdgeData dummy{SPECIAL_EDGEID, /*is_boundary_arc=*/true, 0, 0, false, false};
|
||||||
|
|
||||||
|
for (const auto edge : incoming_edges)
|
||||||
|
{
|
||||||
|
edge_based_graph->InsertEdge(edge.first, artificial, edge.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
incoming_edges.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user