//======================================================================= // Copyright 2013 University of Warsaw. // Authors: Piotr Wygocki // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= // //This algorithm is described in "Network Flows: Theory, Algorithms, and Applications" // by Ahuja, Magnanti, Orlin. #ifndef BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP #define BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP #include #include #include #include #include #include #include #include #include #include namespace boost { namespace detail { template class MapReducedWeight : public put_get_helper::value_type, MapReducedWeight > { typedef graph_traits gtraits; public: typedef boost::readable_property_map_tag category; typedef typename property_traits::value_type value_type; typedef value_type reference; typedef typename gtraits::edge_descriptor key_type; MapReducedWeight(const Graph & g, Weight w, Distance d, Reversed r) : g_(g), weight_(w), distance_(d), rev_(r) {} reference operator[](key_type v) const { return get(distance_, source(v, g_)) - get(distance_,target(v, g_)) + get(weight_, v); } private: const Graph & g_; Weight weight_; Distance distance_; Reversed rev_; }; template MapReducedWeight make_mapReducedWeight(const Graph & g, Weight w, Distance d, Reversed r) { return MapReducedWeight(g, w, d, r); } }//detail template void successive_shortest_path_nonnegative_weights( const Graph &g, typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, Weight weight, Reversed rev, VertexIndex index, Pred pred, Distance distance, Distance2 distance_prev) { filtered_graph > gres = detail::residual_graph(g, residual_capacity); typedef typename graph_traits::edge_descriptor edge_descriptor; BGL_FORALL_EDGES_T(e, g, Graph) { put(residual_capacity, e, get(capacity, e)); } BGL_FORALL_VERTICES_T(v, g, Graph) { put(distance_prev, v, 0); } while(true) { BGL_FORALL_VERTICES_T(v, g, Graph) { put(pred, v, edge_descriptor()); } dijkstra_shortest_paths(gres, s, weight_map(detail::make_mapReducedWeight(gres, weight, distance_prev, rev)). distance_map(distance). vertex_index_map(index). visitor(make_dijkstra_visitor(record_edge_predecessors(pred, on_edge_relaxed())))); if(get(pred, t) == edge_descriptor()) { break; } BGL_FORALL_VERTICES_T(v, g, Graph) { put(distance_prev, v, get(distance_prev, v) + get(distance, v)); } detail::augment(g, s, t, pred, residual_capacity, rev); } } //in this namespace argument dispatching tak place namespace detail { template void successive_shortest_path_nonnegative_weights_dispatch3( const Graph &g, typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, Weight weight, Reversed rev, VertexIndex index, Pred pred, Distance dist, Distance2 dist_pred) { successive_shortest_path_nonnegative_weights(g, s, t, capacity, residual_capacity, weight, rev, index, pred, dist, dist_pred); } //setting default distance map template void successive_shortest_path_nonnegative_weights_dispatch3( Graph &g, typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, Weight weight, Reversed rev, VertexIndex index, Pred pred, Distance dist, param_not_found) { typedef typename property_traits::value_type D; std::vector d_map(num_vertices(g)); successive_shortest_path_nonnegative_weights(g, s, t, capacity, residual_capacity, weight, rev, index, pred, dist, make_iterator_property_map(d_map.begin(), index)); } template void successive_shortest_path_nonnegative_weights_dispatch2( Graph &g, typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, Weight weight, Reversed rev, VertexIndex index, Pred pred, Distance dist, const bgl_named_params& params) { successive_shortest_path_nonnegative_weights_dispatch3(g, s, t, capacity, residual_capacity, weight, rev, index, pred, dist, get_param(params, vertex_distance2)); } //setting default distance map template void successive_shortest_path_nonnegative_weights_dispatch2( Graph &g, typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, Weight weight, Reversed rev, VertexIndex index, Pred pred, param_not_found, const bgl_named_params& params) { typedef typename property_traits::value_type D; std::vector d_map(num_vertices(g)); successive_shortest_path_nonnegative_weights_dispatch3(g, s, t, capacity, residual_capacity, weight, rev, index, pred, make_iterator_property_map(d_map.begin(), index), get_param(params, vertex_distance2)); } template void successive_shortest_path_nonnegative_weights_dispatch1( Graph &g, typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, Weight weight, Reversed rev, VertexIndex index, Pred pred, const bgl_named_params& params) { successive_shortest_path_nonnegative_weights_dispatch2(g, s, t, capacity, residual_capacity, weight, rev, index, pred, get_param(params, vertex_distance), params); } //setting default predecessors map template void successive_shortest_path_nonnegative_weights_dispatch1( Graph &g, typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, Capacity capacity, ResidualCapacity residual_capacity, Weight weight, Reversed rev, VertexIndex index, param_not_found, const bgl_named_params& params) { typedef typename graph_traits::edge_descriptor edge_descriptor; std::vector pred_vec(num_vertices(g)); successive_shortest_path_nonnegative_weights_dispatch2(g, s, t, capacity, residual_capacity, weight, rev, index, make_iterator_property_map(pred_vec.begin(), index), get_param(params, vertex_distance), params); } }//detail template void successive_shortest_path_nonnegative_weights( Graph &g, typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t, const bgl_named_params& params) { return detail::successive_shortest_path_nonnegative_weights_dispatch1(g, s, t, 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_weight), g, edge_weight), choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse), choose_const_pmap(get_param(params, vertex_index), g, vertex_index), get_param(params, vertex_predecessor), params); } template void successive_shortest_path_nonnegative_weights( Graph &g, typename graph_traits::vertex_descriptor s, typename graph_traits::vertex_descriptor t) { bgl_named_params params(0); successive_shortest_path_nonnegative_weights(g, s, t, params); } }//boost #endif /* BOOST_GRAPH_SUCCESSIVE_SHORTEST_PATH_HPP */