C ++ Boost库-最低成本,最大流量

时间:2019-02-20 17:04:20

标签: c++ boost

我正在尝试将此example与这个sample拼凑在一起。我将其编译并运行:

#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/boykov_kolmogorov_max_flow.hpp>
#include <boost/graph/push_relabel_max_flow.hpp>
#include <boost/graph/edmonds_karp_max_flow.hpp>
#include <boost/graph/cycle_canceling.hpp> 

using namespace boost;

typedef int EdgeWeightType;

typedef adjacency_list_traits < vecS, vecS, directedS > Traits;
typedef adjacency_list < vecS, vecS, directedS,
  property < vertex_name_t, std::string,
    property < vertex_index_t, long,
      property < vertex_color_t, boost::default_color_type,
        property < vertex_distance_t, long,
          property < vertex_predecessor_t, Traits::edge_descriptor > > > > >,

  property < edge_capacity_t, EdgeWeightType,
    property < edge_weight_t, EdgeWeightType,
        property < edge_residual_capacity_t, EdgeWeightType,
            property < edge_reverse_t, Traits::edge_descriptor > > > > > Graph;

Traits::edge_descriptor AddEdge(Traits::vertex_descriptor &v1,
                                Traits::vertex_descriptor &v2,
                                property_map < Graph, edge_reverse_t >::type &rev,
                                const double capacity,
                                const double weight, 
                                Graph &g);

int main(int, char*[])
{
  Graph g; //a graph with 0 vertices

  property_map < Graph, edge_reverse_t >::type rev = get(edge_reverse, g);

  //add a source and sink node, and store them in s and t, respectively
  Traits::vertex_descriptor v0 = add_vertex(g);
  Traits::vertex_descriptor v1 = add_vertex(g);
  Traits::vertex_descriptor v2 = add_vertex(g);
  Traits::vertex_descriptor v3 = add_vertex(g);

  Traits::vertex_descriptor v4 = add_vertex(g);
  Traits::vertex_descriptor v5 = add_vertex(g);
  Traits::vertex_descriptor v6 = add_vertex(g);
  Traits::vertex_descriptor v7 = add_vertex(g);
  Traits::vertex_descriptor v8 = add_vertex(g);
  Traits::vertex_descriptor v9 = add_vertex(g);
  Traits::vertex_descriptor v10 = add_vertex(g);
  Traits::vertex_descriptor v11 = add_vertex(g);

  AddEdge(v0, v1, rev, 1, 1, g);
  AddEdge(v0, v2, rev, 1, 1, g);
  AddEdge(v0, v3, rev, 1, 1, g);

  AddEdge(v1, v4, rev, 100, 10, g);
  AddEdge(v1, v5, rev, 100, 2, g);

  AddEdge(v2, v6, rev, 100, 10, g);
  AddEdge(v2, v7, rev, 100, 2, g);

  AddEdge(v3, v8, rev, 100, 10, g);
  AddEdge(v3, v9, rev, 100, 2, g);

  AddEdge(v4, v11, rev, 100, 1, g);
  AddEdge(v6, v11, rev, 100, 1, g);
  AddEdge(v8, v11, rev, 100, 1, g);

  AddEdge(v5, v10, rev, 100, 1, g);
  AddEdge(v7, v10, rev, 100, 1, g);
  AddEdge(v9, v10, rev, 100, 1, g);  

  AddEdge(v10, v11, rev, 100, 1, g);


  //find min cut
  //EdgeWeightType flow = boykov_kolmogorov_max_flow(g, v0, v3); // a list of sources will be returned in s, and a list of sinks will be returned in t
  //EdgeWeightType flow = push_relabel_max_flow(g, v0, v3); // a list of sources will be returned in s, and a list of sinks will be returned in t
  EdgeWeightType flow = edmonds_karp_max_flow(g, v0, v11); // a list of sources will be returned in s, and a list of sinks will be returned in t
  boost::cycle_canceling(g);

  int cost = boost::find_flow_cost(g);

  std::cout << "Flow cost is " << cost << std::endl;
  std::cout << "Max flow is: " << flow << std::endl;

  property_map<Graph, edge_capacity_t>::type
          capacity = get(edge_capacity, g);
  property_map<Graph, edge_residual_capacity_t>::type
          residual_capacity = get(edge_residual_capacity, g);


  graph_traits<Graph>::vertex_iterator u_iter, u_end;
  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)
          if (capacity[*ei] > 0)
              std::cout << "Source: " << *u_iter << " destination: " << target(*ei, g) << " capacity: "  << capacity[*ei] << "residual cap: " << residual_capacity[*ei] << " used capacity: "
                      << (capacity[*ei] - residual_capacity[*ei]) << std::endl;

 return 0;
}

Traits::edge_descriptor AddEdge(Traits::vertex_descriptor &v1, Traits::vertex_descriptor &v2, property_map < Graph, edge_reverse_t >::type &rev, const double capacity, const double weight, Graph &g)
{
  Traits::edge_descriptor e1 = add_edge(v1, v2, g).first;
  Traits::edge_descriptor e2 = add_edge(v2, v1, g).first;
  put(edge_capacity, g, e1, capacity);
  put(edge_capacity, g, e2, capacity);
  put(edge_weight, g, e1, weight);
  put(edge_weight, g, e2, weight);
  rev[e1] = e2;
  rev[e2] = e1;
}

我希望最小成本最大流量应该选择从v1到v5,从v2到v7和从v3到v9的边缘,因为与边缘v1到v4,v2到v6和v3到v8相比,这些边缘的成本较低。但是,这不是我运行程序时得到的结果。

你能指出我可能做错了吗?

感谢和问候 穆罕默德·萨奇布·伊利亚斯

1 个答案:

答案 0 :(得分:0)

我在libs \ graph \ test中找到了min_cost_max_flow_utils.hpp文件。我修改了getSampleGraph()函数以创建自己的图形并成功解决了该问题。