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
|
* @note This assumes that the values of μ, φ and ρ represent a special
|
||||||
* blossom forest on the graph when this method is called.
|
* 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> path_to_forest_root(Graph const & graph, NodeId id)
|
||||||
{
|
{
|
||||||
std::vector<NodeId> retval;
|
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)
|
__attribute__((noinline))
|
||||||
{
|
void augment(Graph & graph, std::vector<NodeId> const & x_path, std::vector<NodeId> const & y_path,
|
||||||
graph.reset_forest();
|
std::stack<NodeId> & outer_unvisited_nodes)
|
||||||
// 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())
|
|
||||||
{
|
{
|
||||||
//std::cout << "Augment" << std::endl;
|
//std::cout << "Augment" << std::endl;
|
||||||
// Paths are disjoint -> augment
|
// Paths are disjoint -> augment
|
||||||
|
@ -151,9 +121,10 @@ void maximum_matching_from_initial_matching(Graph & graph)
|
||||||
// new stack frames in OPT mode
|
// new stack frames in OPT mode
|
||||||
graph.reset_forest();
|
graph.reset_forest();
|
||||||
collect_exposed_vertices(graph, outer_unvisited_nodes);
|
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;
|
//std::cout << "Contract blossom" << std::endl;
|
||||||
// Paths are not disjoint -> shrink blossom
|
// Paths are not disjoint -> shrink blossom
|
||||||
|
@ -233,6 +204,49 @@ void maximum_matching_from_initial_matching(Graph & graph)
|
||||||
}
|
}
|
||||||
//check_integrity(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;
|
graph.node(id).scanned = true;
|
||||||
|
|
Loading…
Reference in a new issue