mirror of
https://github.com/boostorg/graph.git
synced 2026-02-09 11:12:28 +00:00
updated to use named parameters
[SVN r9908]
This commit is contained in:
@@ -36,9 +36,9 @@
|
||||
|
||||
namespace boost {
|
||||
|
||||
// The "labeling" algorithm from "Network Flows" by Ahuja, Magnanti, Orlin.
|
||||
// I think it is the same as or similar to the Edmunds-Karp algorithm.
|
||||
// This solves the maximum flow problem.
|
||||
// The "labeling" algorithm from "Network Flows" by Ahuja, Magnanti,
|
||||
// Orlin. I think this is the same as or very similar to the original
|
||||
// Edmunds-Karp algorithm. This solves the maximum flow problem.
|
||||
|
||||
namespace detail {
|
||||
|
||||
@@ -82,68 +82,177 @@ namespace boost {
|
||||
} while (u != src);
|
||||
}
|
||||
|
||||
template <class Graph, class P, class T, class R>
|
||||
struct edge_capacity_value
|
||||
{
|
||||
typedef bgl_named_params<P, T, R> Params;
|
||||
typedef typename property_value< Params, edge_capacity_t>::type Param;
|
||||
typedef typename detail::choose_pmap_helper<Param, Graph,
|
||||
edge_capacity_t>::const_result_type CapacityEdgeMap;
|
||||
typedef typename property_traits<CapacityEdgeMap>::value_type type;
|
||||
};
|
||||
|
||||
template <class Graph,
|
||||
class CapacityEdgeMap, class ResidualCapacityEdgeMap,
|
||||
class ReverseEdgeMap, class ColorMap, class PredEdgeMap>
|
||||
typename property_traits<CapacityEdgeMap>::value_type
|
||||
edmunds_karp_max_flow_impl
|
||||
(Graph& g,
|
||||
typename graph_traits<Graph>::vertex_descriptor src,
|
||||
typename graph_traits<Graph>::vertex_descriptor sink,
|
||||
CapacityEdgeMap cap,
|
||||
ResidualCapacityEdgeMap res,
|
||||
ReverseEdgeMap rev,
|
||||
ColorMap color,
|
||||
PredEdgeMap pred)
|
||||
{
|
||||
typename graph_traits<Graph>::vertex_iterator u_iter, u_end;
|
||||
typename graph_traits<Graph>::out_edge_iterator ei, e_end;
|
||||
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
|
||||
for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
|
||||
res[*ei] = cap[*ei];
|
||||
|
||||
typedef color_traits<typename property_traits<ColorMap>::value_type>
|
||||
Color;
|
||||
|
||||
color[sink] = Color::gray();
|
||||
while (color[sink] != Color::white()) {
|
||||
breadth_first_search
|
||||
(detail::residual_graph(g, res), src,
|
||||
make_bfs_visitor(record_edge_predecessors(pred, on_tree_edge())),
|
||||
color);
|
||||
if (color[sink] != Color::white())
|
||||
detail::augment(g, src, sink, pred, res, rev);
|
||||
} // while
|
||||
|
||||
typename property_traits<CapacityEdgeMap>::value_type flow = 0;
|
||||
for (tie(ei, e_end) = out_edges(src, g); ei != e_end; ++ei)
|
||||
flow += (cap[*ei] - res[*ei]);
|
||||
return flow;
|
||||
} // edmunds_karp_max_flow_impl()
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Handle default for color property map
|
||||
|
||||
template <class Graph, class PredMap, class P, class T, class R>
|
||||
typename edge_capacity_value<Graph, P, T, R>::type
|
||||
edmunds_karp_dispatch2
|
||||
(Graph& g,
|
||||
typename graph_traits<Graph>::vertex_descriptor src,
|
||||
typename graph_traits<Graph>::vertex_descriptor sink,
|
||||
PredMap pred,
|
||||
const bgl_named_params<P, T, R>& params,
|
||||
detail::error_property_not_found)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
typedef typename graph_traits<Graph>::vertices_size_type size_type;
|
||||
size_type n = is_default_param(get_param(params, vertex_color)) ?
|
||||
num_vertices(g) : 0;
|
||||
std::vector<default_color_type> color_vec(n);
|
||||
return edmunds_karp_max_flow_impl
|
||||
(g, src, sink,
|
||||
choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
|
||||
choose_pmap(get_param(params, edge_residual_capacity),
|
||||
g, edge_residual_capacity),
|
||||
choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
|
||||
make_iterator_property_map(color_vec.begin(), choose_const_pmap
|
||||
(get_param(params, vertex_index),
|
||||
g, vertex_index)),
|
||||
pred);
|
||||
}
|
||||
|
||||
template <class Graph, class PredMap, class P, class T, class R,
|
||||
class ColorMap>
|
||||
typename edge_capacity_value<Graph, P, T, R>::type
|
||||
edmunds_karp_dispatch2
|
||||
(Graph& g,
|
||||
typename graph_traits<Graph>::vertex_descriptor src,
|
||||
typename graph_traits<Graph>::vertex_descriptor sink,
|
||||
PredMap pred,
|
||||
const bgl_named_params<P, T, R>& params,
|
||||
ColorMap color)
|
||||
{
|
||||
return edmunds_karp_max_flow_impl
|
||||
(g, src, sink,
|
||||
choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
|
||||
choose_pmap(get_param(params, edge_residual_capacity),
|
||||
g, edge_residual_capacity),
|
||||
choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
|
||||
color, pred);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Handle default for predecessor property map
|
||||
|
||||
template <class Graph, class P, class T, class R>
|
||||
typename edge_capacity_value<Graph, P, T, R>::type
|
||||
edmunds_karp_dispatch1
|
||||
(Graph& g,
|
||||
typename graph_traits<Graph>::vertex_descriptor src,
|
||||
typename graph_traits<Graph>::vertex_descriptor sink,
|
||||
const bgl_named_params<P, T, R>& params,
|
||||
detail::error_property_not_found)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
typedef typename graph_traits<Graph>::vertices_size_type size_type;
|
||||
size_type n = is_default_param(get_param(params, vertex_predecessor)) ?
|
||||
num_vertices(g) : 0;
|
||||
std::vector<edge_descriptor> pred_vec(n);
|
||||
|
||||
return edmunds_karp_dispatch2
|
||||
(g, src, sink,
|
||||
make_iterator_property_map(pred_vec.begin(), choose_const_pmap
|
||||
(get_param(params, vertex_index),
|
||||
g, vertex_index)),
|
||||
params,
|
||||
get_param(params, vertex_color));
|
||||
}
|
||||
|
||||
template <class Graph, class P, class T, class R, class PredMap>
|
||||
typename edge_capacity_value<Graph, P, T, R>::type
|
||||
edmunds_karp_dispatch1
|
||||
(Graph& g,
|
||||
typename graph_traits<Graph>::vertex_descriptor src,
|
||||
typename graph_traits<Graph>::vertex_descriptor sink,
|
||||
const bgl_named_params<P, T, R>& params,
|
||||
PredMap pred)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
typedef typename graph_traits<Graph>::vertices_size_type size_type;
|
||||
size_type n = is_default_param(get_param(params, vertex_predecessor)) ?
|
||||
num_vertices(g) : 0;
|
||||
std::vector<edge_descriptor> pred_vec(n);
|
||||
|
||||
return edmunds_karp_dispatch2
|
||||
(g, src, sink, pred, params, get_param(params, vertex_color));
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class Graph,
|
||||
class CapacityEdgeMap, class ResidualCapacityEdgeMap,
|
||||
class ReverseEdgeMap, class ColorMap, class PredEdgeMap>
|
||||
typename property_traits<CapacityEdgeMap>::value_type
|
||||
template <class Graph, class P, class T, class R>
|
||||
typename detail::edge_capacity_value<Graph, P, T, R>::type
|
||||
edmunds_karp_max_flow
|
||||
(Graph& g,
|
||||
(Graph& g,
|
||||
typename graph_traits<Graph>::vertex_descriptor src,
|
||||
typename graph_traits<Graph>::vertex_descriptor sink,
|
||||
CapacityEdgeMap cap,
|
||||
ResidualCapacityEdgeMap res,
|
||||
ReverseEdgeMap rev,
|
||||
ColorMap color,
|
||||
PredEdgeMap pred)
|
||||
const bgl_named_params<P, T, R>& params)
|
||||
{
|
||||
typename graph_traits<Graph>::vertex_iterator u_iter, u_end;
|
||||
typename graph_traits<Graph>::out_edge_iterator ei, e_end;
|
||||
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
|
||||
for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
|
||||
res[*ei] = cap[*ei];
|
||||
return detail::edmunds_karp_dispatch1
|
||||
(g, src, sink, params, get_param(params, vertex_predecessor));
|
||||
}
|
||||
|
||||
typedef color_traits<typename property_traits<ColorMap>::value_type> Color;
|
||||
|
||||
color[sink] = Color::gray();
|
||||
while (color[sink] != Color::white()) {
|
||||
breadth_first_search
|
||||
(detail::residual_graph(g, res), src,
|
||||
make_bfs_visitor(record_edge_predecessors(pred, on_tree_edge())),
|
||||
color);
|
||||
if (color[sink] != Color::white())
|
||||
detail::augment(g, src, sink, pred, res, rev);
|
||||
} // while
|
||||
|
||||
typename property_traits<CapacityEdgeMap>::value_type flow = 0;
|
||||
for (tie(ei, e_end) = out_edges(src, g); ei != e_end; ++ei)
|
||||
flow += (cap[*ei] - res[*ei]);
|
||||
return flow;
|
||||
} // edmunds_karp_max_flow()
|
||||
|
||||
template <class Graph,
|
||||
class CapacityEdgeMap, class ResidualCapacityEdgeMap,
|
||||
class ReverseEdgeMap, class VertexIndexMap>
|
||||
typename property_traits<CapacityEdgeMap>::value_type
|
||||
template <class Graph>
|
||||
typename property_traits<
|
||||
typename property_map<Graph, edge_capacity_t>::const_type
|
||||
>::value_type
|
||||
edmunds_karp_max_flow
|
||||
(Graph& g,
|
||||
(Graph& g,
|
||||
typename graph_traits<Graph>::vertex_descriptor src,
|
||||
typename graph_traits<Graph>::vertex_descriptor sink,
|
||||
CapacityEdgeMap cap,
|
||||
ResidualCapacityEdgeMap res,
|
||||
ReverseEdgeMap rev,
|
||||
VertexIndexMap index_map)
|
||||
typename graph_traits<Graph>::vertex_descriptor sink)
|
||||
{
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
std::vector<edge_descriptor> pred(num_vertices(g));
|
||||
std::vector<default_color_type> color(num_vertices(g));
|
||||
|
||||
return edmunds_karp_max_flow
|
||||
(g, src, sink, cap, res, rev,
|
||||
make_iterator_property_map(color.begin(), index_map, color[0]),
|
||||
make_iterator_property_map(pred.begin(), index_map, pred[0]));
|
||||
} // edmunds_karp_max_flow()
|
||||
bgl_named_params<int, int> params(0);
|
||||
return edmunds_karp_max_flow(g, src, sink, params);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
Reference in New Issue
Block a user