split into separate methods and use noinline attribute to profile
This commit is contained in:
parent
03f9afa67b
commit
f3240b7f6b
1 changed files with 111 additions and 97 deletions
|
@ -64,6 +64,7 @@ void check_integrity(Graph const & graph)
|
|||
* @note This assumes that the values of μ, φ and ρ represent a special
|
||||
* blossom forest on the graph when this method is called.
|
||||
* **/
|
||||
__attribute__((noinline))
|
||||
std::vector<NodeId> path_to_forest_root(Graph const & graph, NodeId id)
|
||||
{
|
||||
std::vector<NodeId> retval;
|
||||
|
@ -96,40 +97,9 @@ void collect_exposed_vertices(Graph & graph, std::stack<NodeId> & container)
|
|||
}
|
||||
}
|
||||
|
||||
void maximum_matching_from_initial_matching(Graph & graph)
|
||||
{
|
||||
graph.reset_forest();
|
||||
// Over the course of the algorithm, this will maintain all outer vertices
|
||||
// that have not been scanned yet.
|
||||
// Note that at the beginning, this is exactly the exposed edges.
|
||||
// Throughout the algorithm, we push new ids whenever there are new outer vertices.
|
||||
// Also note that we separately mark each node whether it has been collected to this stack.
|
||||
// When this stack runs out, then we know that all vertices marked 'scanned' have already been processed,
|
||||
// but also all vertices not marked 'scanned' are not outer vertices, so we can in fact terminate.
|
||||
std::stack<NodeId> outer_unvisited_nodes;
|
||||
collect_exposed_vertices(graph, outer_unvisited_nodes);
|
||||
while(not outer_unvisited_nodes.empty())
|
||||
{
|
||||
NodeId const id = outer_unvisited_nodes.top();
|
||||
outer_unvisited_nodes.pop();
|
||||
for(NodeId neighbor_id : graph.node(id).neighbors())
|
||||
{
|
||||
//check_integrity(graph);
|
||||
//std::cout << "Check passed" << std::endl;
|
||||
if (graph.is_out_of_forest(neighbor_id))
|
||||
{
|
||||
//std::cout << "Grow forest" << std::endl;
|
||||
// Grow Forest
|
||||
graph.node(neighbor_id).phi = id;
|
||||
assert(graph.matched_neighbor(neighbor_id) != neighbor_id);
|
||||
outer_unvisited_nodes.push(graph.matched_neighbor(neighbor_id));
|
||||
}
|
||||
else if (graph.is_outer(neighbor_id) and graph.rho(id) != graph.rho(neighbor_id))
|
||||
{
|
||||
std::vector<NodeId> x_path = path_to_forest_root(graph, id);
|
||||
std::vector<NodeId> y_path = path_to_forest_root(graph, neighbor_id);
|
||||
|
||||
if (x_path.back() != y_path.back())
|
||||
__attribute__((noinline))
|
||||
void augment(Graph & graph, std::vector<NodeId> const & x_path, std::vector<NodeId> const & y_path,
|
||||
std::stack<NodeId> & outer_unvisited_nodes)
|
||||
{
|
||||
//std::cout << "Augment" << std::endl;
|
||||
// Paths are disjoint -> augment
|
||||
|
@ -151,9 +121,10 @@ void maximum_matching_from_initial_matching(Graph & graph)
|
|||
// new stack frames in OPT mode
|
||||
graph.reset_forest();
|
||||
collect_exposed_vertices(graph, outer_unvisited_nodes);
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
||||
void contract_blossom(Graph & graph, std::vector<NodeId> const & x_path, std::vector<NodeId> const & y_path,
|
||||
std::stack<NodeId> & outer_unvisited_nodes)
|
||||
{
|
||||
//std::cout << "Contract blossom" << std::endl;
|
||||
// Paths are not disjoint -> shrink blossom
|
||||
|
@ -233,6 +204,49 @@ void maximum_matching_from_initial_matching(Graph & graph)
|
|||
}
|
||||
//check_integrity(graph);
|
||||
}
|
||||
|
||||
void maximum_matching_from_initial_matching(Graph & graph)
|
||||
{
|
||||
graph.reset_forest();
|
||||
// Over the course of the algorithm, this will maintain all outer vertices
|
||||
// that have not been scanned yet.
|
||||
// Note that at the beginning, this is exactly the exposed edges.
|
||||
// Throughout the algorithm, we push new ids whenever there are new outer vertices.
|
||||
// Also note that we separately mark each node whether it has been collected to this stack.
|
||||
// When this stack runs out, then we know that all vertices marked 'scanned' have already been processed,
|
||||
// but also all vertices not marked 'scanned' are not outer vertices, so we can in fact terminate.
|
||||
std::stack<NodeId> outer_unvisited_nodes;
|
||||
collect_exposed_vertices(graph, outer_unvisited_nodes);
|
||||
while(not outer_unvisited_nodes.empty())
|
||||
{
|
||||
NodeId const id = outer_unvisited_nodes.top();
|
||||
outer_unvisited_nodes.pop();
|
||||
for(NodeId neighbor_id : graph.node(id).neighbors())
|
||||
{
|
||||
//check_integrity(graph);
|
||||
//std::cout << "Check passed" << std::endl;
|
||||
if (graph.is_out_of_forest(neighbor_id))
|
||||
{
|
||||
//std::cout << "Grow forest" << std::endl;
|
||||
// Grow Forest
|
||||
graph.node(neighbor_id).phi = id;
|
||||
assert(graph.matched_neighbor(neighbor_id) != neighbor_id);
|
||||
outer_unvisited_nodes.push(graph.matched_neighbor(neighbor_id));
|
||||
}
|
||||
else if (graph.is_outer(neighbor_id) and graph.rho(id) != graph.rho(neighbor_id))
|
||||
{
|
||||
std::vector<NodeId> x_path = path_to_forest_root(graph, id);
|
||||
std::vector<NodeId> y_path = path_to_forest_root(graph, neighbor_id);
|
||||
|
||||
if (x_path.back() != y_path.back())
|
||||
{
|
||||
augment(graph, x_path, y_path, outer_unvisited_nodes);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
contract_blossom(graph, x_path, y_path, outer_unvisited_nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
graph.node(id).scanned = true;
|
||||
|
|
Loading…
Reference in a new issue