我一直在努力寻找方法。我对快速找到图的割集感兴趣。我知道BGL支持在诸如edmonds_karp_max_flow支持的colorMap参数上通过迭代查找割集。Gomory Hu算法需要多次调用最小切割算法。
我希望得到的结果是有一个包含以下内容的多图:(颜色,顶点)
以下代码是尝试从Boost Graph库重写示例以将多图用于associative_property_map的尝试。可以使用以下命令完成代码的编译:clang -lboost_graph -o edmonds_karp edmonds_karp.cpp或g ++而不是clang。我没有发现错误。
#include <boost/config.hpp> #include <iostream> #include <string> #include <boost/foreach.hpp> #include <boost/graph/adjacency_list.hpp> #include <boost/graph/edmonds_karp_max_flow.hpp> #include <boost/graph/graph_utility.hpp> #include <boost/graph/read_dimacs.hpp> #include <boost/lexical_cast.hpp> #include <boost/property_map/property_map.hpp> #include <boost/unordered_map.hpp> int main() { using namespace boost; typedef adjacency_list_traits < vecS, vecS, directedS > Traits; typedef adjacency_list < listS, vecS, directedS, property < vertex_name_t, std::string >, property < edge_capacity_t, long, property < edge_residual_capacity_t, long, property < edge_reverse_t, Traits::edge_descriptor > > > > Graph; Graph g; property_map < Graph, edge_capacity_t >::type capacity = get(edge_capacity, g); property_map < Graph, edge_reverse_t >::type rev = get(edge_reverse, g); property_map < Graph, edge_residual_capacity_t >::type residual_capacity = get(edge_residual_capacity, g); std::multimap<default_color_type, Traits::vertex_descriptor> colorMap; boost::associative_property_map< std::map<default_color_type, Traits::vertex_descriptor> > color_map(colorMap); Traits::vertex_descriptor s, t; read_dimacs_max_flow(g, capacity, rev, s, t); std::vector<Traits::edge_descriptor> pred(num_vertices(g)); long flow = edmonds_karp_max_flow (g, s, t, capacity, residual_capacity, rev, make_iterator_property_map(color_map.begin()), &pred[0]); std::cout << "c The total flow:" << std::endl; std::cout << "s " << flow << std::endl << std::endl; std::cout << "c flow values:" << std::endl; graph_traits < Graph >::vertex_iterator u_iter, u_end; graph_traits < Graph >::out_edge_iterator ei, e_end; for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) if (capacity[*ei] > 0) std::cout << "f " << *u_iter << " " << target(*ei, g) << " " << (capacity[*ei] - residual_capacity[*ei]) << std::endl; // if using the original example, unedited, this piece of code works // BOOST_FOREACH(default_color_type x, color){ // std::cout << x << std::endl; // } return EXIT_SUCCESS; }
提示将不胜感激。谢谢。
这是基于Boost BiMap的快速PoC
typedef boost::bimap<bimaps::list_of<default_color_type>, bimaps::set_of<Traits::vertex_descriptor> > smart_map; smart_map colorMap; boost::associative_property_map<smart_map::right_map> color_map(colorMap.right);
我从http://lpsolve.sourceforge.net/5.5/DIMACS_maxf.htm中提取了一个小样本,您可以看到它在 Live Coliru上显示 ,输出:
c The total flow: s 15 c flow values: f 0 1 5 f 0 2 10 f 1 3 5 f 1 4 0 f 2 3 5 f 2 4 5 f 3 5 10 f 4 5 5 ltr: 0 -> 5 ltr: 4 -> 0 ltr: 0 -> 1 ltr: 4 -> 2 ltr: 0 -> 3 ltr: 0 -> 4 rtl: 0 -> 4 rtl: 1 -> 0 rtl: 2 -> 4 rtl: 3 -> 0 rtl: 4 -> 0 rtl: 5 -> 0
#include <boost/foreach.hpp> #include <boost/bimap.hpp> #include <boost/graph/adjacency_list.hpp> #include <boost/bimap/list_of.hpp> #include <boost/bimap/set_of.hpp> #include <boost/graph/edmonds_karp_max_flow.hpp> #include <boost/graph/graph_utility.hpp> #include <boost/graph/read_dimacs.hpp> #include <boost/lexical_cast.hpp> #include <boost/property_map/property_map.hpp> #include <boost/unordered_map.hpp> int main() { using namespace boost; typedef adjacency_list_traits<vecS, vecS, directedS> Traits; typedef adjacency_list< listS, vecS, directedS, property<vertex_name_t, std::string>, property<edge_capacity_t, long, property<edge_residual_capacity_t, long, property<edge_reverse_t, Traits::edge_descriptor> > > > Graph; Graph g; property_map<Graph, edge_capacity_t>::type capacity = get(edge_capacity, g); property_map<Graph, edge_reverse_t>::type rev = get(edge_reverse, g); property_map<Graph, edge_residual_capacity_t>::type residual_capacity = get(edge_residual_capacity, g); typedef boost::bimap<bimaps::list_of<default_color_type>, bimaps::set_of<Traits::vertex_descriptor> > smart_map; smart_map colorMap; boost::associative_property_map<smart_map::right_map> color_map(colorMap.right); Traits::vertex_descriptor s, t; read_dimacs_max_flow(g, capacity, rev, s, t); std::vector<Traits::edge_descriptor> pred(num_vertices(g)); long flow = edmonds_karp_max_flow( g, s, t, capacity, residual_capacity, rev, color_map, &pred[0]); std::cout << "c The total flow:" << std::endl; std::cout << "s " << flow << std::endl << std::endl; std::cout << "c flow values:" << std::endl; graph_traits<Graph>::vertex_iterator u_iter, u_end; graph_traits<Graph>::out_edge_iterator ei, e_end; for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) if (capacity[*ei] > 0) std::cout << "f " << *u_iter << " " << target(*ei, g) << " " << (capacity[*ei] - residual_capacity[*ei]) << std::endl; for (auto const& e : colorMap.left) std::cout << "ltr: " << e.first << " -> " << e.second << "\n"; for (auto const& e : colorMap.right) std::cout << "rtl: " << e.first << " -> " << e.second << "\n"; return EXIT_SUCCESS; }
使用Boost MultiIndex创建双向映射:
struct VertexColor { Traits::vertex_descriptor vertex; boost::default_color_type color; }; typedef boost::multi_index_container< VertexColor, bmi::indexed_by< bmi::hashed_non_unique<bmi::tag<struct by_color>, bmi::member<VertexColor, boost::default_color_type, &VertexColor::color> >, bmi::ordered_unique <bmi::tag<struct by_vertex>, bmi::member<VertexColor, Traits::vertex_descriptor, &VertexColor::vertex> > > > smart_map;
现在,使用Boost Property Map建模 ReadWritePropertyMap :
ReadWritePropertyMap
struct bidi_color_map { typedef smart_map::index<by_vertex>::type impl_t; bidi_color_map(impl_t& ref) : ref_(&ref) {} impl_t &get() { return *ref_; } impl_t const &get() const { return *ref_; } private: impl_t* ref_; }; namespace boost { template <> struct property_traits<bidi_color_map> { typedef default_color_type value_type; typedef default_color_type reference; typedef Traits::vertex_descriptor key_type; typedef read_write_property_map_tag category; }; } boost::property_traits<bidi_color_map>::reference get(bidi_color_map const& idx, boost::property_traits<bidi_color_map>::key_type const& key) { auto it = idx.get().find(key); if (it != idx.get().end()) return it->color; else throw std::range_error("key not found in index"); } void put(bidi_color_map& idx, boost::property_traits<bidi_color_map>::key_type const& key, boost::property_traits<bidi_color_map>::value_type val) { auto it = idx.get().find(key); if (it != idx.get().end()) idx.get().modify(it, [val](VertexColor& p) { p.color = val; }); else idx.get().insert({key,val}); }
现在,您可以将其作为颜色图传递:
smart_map colorMap; bidi_color_map color_map(colorMap.get<by_vertex>());
看到它 住在Coliru 以及