Commit 1d16a08d authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Include max_cardinality_matching() in flow module

parent a35d46b9
......@@ -18,6 +18,7 @@ libgraph_tool_flow_la_SOURCES = \
graph_edmonds_karp.cc \
graph_push_relabel.cc \
graph_kolmogorov.cc \
graph_maximum_cardinality_matching.cc \
graph_flow_bind.cc
libgraph_tool_flow_la_include_HEADERS = \
......
......@@ -24,6 +24,7 @@ void push_relabel_max_flow(GraphInterface& gi, size_t src, size_t sink,
boost::any capacity, boost::any res);
void kolmogorov_max_flow(GraphInterface& gi, size_t src, size_t sink,
boost::any capacity, boost::any res);
bool max_cardinality_matching(GraphInterface& gi, boost::any match);
#include <boost/python.hpp>
using namespace boost::python;
......@@ -33,4 +34,5 @@ BOOST_PYTHON_MODULE(libgraph_tool_flow)
def("edmonds_karp_max_flow", &edmonds_karp_max_flow);
def("push_relabel_max_flow", &push_relabel_max_flow);
def("kolmogorov_max_flow", &kolmogorov_max_flow);
def("max_cardinality_matching", &max_cardinality_matching);
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007 Tiago de Paula Peixoto <tiago@forked.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph_filtering.hh"
#include "graph_selectors.hh"
#include "graph_properties.hh"
#include "graph.hh"
#include "graph_augment.hh"
#include <boost/graph/max_cardinality_matching.hpp>
#include <boost/bind.hpp>
using namespace graph_tool;
using namespace boost;
struct get_max_cardinality_matching
{
template <class Graph, class VertexIndex, class MatchMap>
void operator()(Graph& g, VertexIndex vertex_index, MatchMap match,
bool &check) const
{
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
unchecked_vector_property_map<vertex_t,VertexIndex>
mate(vertex_index, num_vertices(g));
typename graph_traits<Graph>::edge_iterator e, e_end;
for (tie(e, e_end) = edges(g); e != e_end; ++e)
match[*e] = false;
check =
checked_edmonds_maximum_cardinality_matching(g, mate, vertex_index);
for (tie(e, e_end) = edges(g); e != e_end; ++e)
{
if (mate[source(*e,g)] != graph_traits<Graph>::null_vertex() &&
mate[source(*e,g)] == target(*e,g))
{
// search for an already matched parallel edge
bool matched = false;
typename graph_traits<Graph>::out_edge_iterator oe, oe_end;
for (tie(oe, oe_end) = out_edges(source(*e, g),g); oe != oe_end;
++oe)
{
if (match[*oe])
{
matched = true;
break;
}
}
if (!matched)
match[*e] = true;
}
}
}
};
bool max_cardinality_matching(GraphInterface& gi, boost::any match)
{
bool check;
run_action<graph_tool::detail::never_directed>()
(gi, bind<void>(get_max_cardinality_matching(),
_1, gi.GetVertexIndex(), _2, ref(check)),
writable_edge_scalar_properties()) (match);
return check;
}
......@@ -26,7 +26,7 @@ dl_import("import libgraph_tool_flow")
from .. core import _prop, _check_prop_scalar, _check_prop_writable
__all__ = ["edmonds_karp_max_flow", "push_relabel_max_flow",
"kolmogorov_max_flow"]
"kolmogorov_max_flow", "max_cardinality_matching"]
def edmonds_karp_max_flow(g, source, target, capacity, residual=None):
_check_prop_scalar(capacity, "capacity")
......@@ -66,3 +66,16 @@ def kolmogorov_max_flow(g, source, target, capacity, residual=None):
_prop("e", g, capacity),
_prop("e", g, residual))
return residual
def max_cardinality_matching(g, match=None):
if match == None:
match = g.new_edge_property("bool")
_check_prop_scalar(match, "match")
_check_prop_writable(match, "match")
g.stash_filter(directed=True)
g.set_directed(False)
check = libgraph_tool_flow.\
max_cardinality_matching(g._Graph__graph, _prop("e", g, match))
g.pop_filter(directed=True)
return match, check
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment