C++ boost::graph算法是否能够使用以前的解决方案更快地解决密切相关的新问题?
我在下图中定义了最大流量问题: 最初,所有四条边上的容量均为4个单位。我在0到3之间寻找最大流量值。答案是8。(沿路径0->1->3有4个单位,沿路径0->2->3有4个单位) 下面的代码创建图形并查找最大流C++ boost::graph算法是否能够使用以前的解决方案更快地解决密切相关的新问题?,c++,algorithm,boost,graph,C++,Algorithm,Boost,Graph,我在下图中定义了最大流量问题: 最初,所有四条边上的容量均为4个单位。我在0到3之间寻找最大流量值。答案是8。(沿路径0->1->3有4个单位,沿路径0->2->3有4个单位) 下面的代码创建图形并查找最大流 #include <boost/graph/adjacency_list.hpp> #include <boost/graph/boykov_kolmogorov_max_flow.hpp> #include <boost/graph/edmonds_kar
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/boykov_kolmogorov_max_flow.hpp>
#include <boost/graph/edmonds_karp_max_flow.hpp>
#include <boost/graph/push_relabel_max_flow.hpp>
#include <iostream>
using namespace boost;
typedef adjacency_list_traits<vecS, vecS, directedS> Traits;
typedef adjacency_list<
vecS, vecS, directedS,
property<
vertex_name_t, std::string,
property<vertex_index_t, int,
property<vertex_color_t, boost::default_color_type,
property<vertex_distance_t, double,
property<vertex_predecessor_t, Traits::edge_descriptor>
> > > >,
property<
edge_index_t, int,
property<edge_capacity_t, double,
property<edge_weight_t, double,
property<edge_residual_capacity_t, double,
property<edge_reverse_t, Traits::edge_descriptor>
> > > > >
Graph;
int main() {
Graph g;
property_map<Graph, edge_index_t>::type e = get(edge_index, g);
property_map<Graph, edge_capacity_t>::type cap = get(edge_capacity, g);
property_map<Graph, edge_weight_t>::type cost = get(edge_weight, g);
property_map<Graph, edge_residual_capacity_t>::type rescap = get(edge_residual_capacity, g);
property_map<Graph, edge_reverse_t>::type rev = get(edge_reverse, g);
int nonodes = 4;
for (int i = 0; i < nonodes; i++) {
Traits::vertex_descriptor vd;
vd = add_vertex(g);
assert(vd == i);
}
// Create edges
Traits::edge_descriptor edf, edb; // Max flow algorithms seem to want both forward and backward edges. edf is for
// forward, edb is for backward
edf = (add_edge(0, 1, g)).first;
edb = (add_edge(1, 0, g)).first;
e[edf] = 0;
e[edb] = 1;
cap[edf] = 4;
cap[edb] = 4;
rev[edf] = edb;
rev[edb] = edf;
edf = (add_edge(0, 2, g)).first;
edb = (add_edge(2, 0, g)).first;
e[edf] = 2;
e[edb] = 3;
cap[edf] = 4;
cap[edb] = 4;
rev[edf] = edb;
rev[edb] = edf;
edf = (add_edge(1, 3, g)).first;
edb = (add_edge(3, 1, g)).first;
e[edf] = 4;
e[edb] = 5;
cap[edf] = 4;
cap[edb] = 4;
rev[edf] = edb;
rev[edb] = edf;
edf = (add_edge(2, 3, g)).first;
edb = (add_edge(3, 2, g)).first;
e[edf] = 6;
e[edb] = 7;
cap[edf] = 4;
cap[edb] = 4;
rev[edf] = edb;
rev[edb] = edf;
double flow = boykov_kolmogorov_max_flow(g, 0, 3);
std::cout << "Flow: " << flow << "\n";
}
与上述问题密切相关的是:是否有一种方法(一个
int
returning method())可以计算出在解决上述boykov\u kolmogorov\u max\u flow(g,0,3)
的每次调用时需要做多少工作?请注意,在前面的代码中有两个地方调用此算法。所谓工作,我指的是从开始到问题解决为止的整数次迭代?有些算法是。例如,有一个版本的connected_components使用不相交集状态来增量查找增长图的组件:@sehe谢谢,但这不是我所指的。我对经典的图算法更感兴趣,例如最短路径、最小成本流、最大流或最小生成树等。根据我迄今收集的信息,图库不使用以前的解决方案。你知道有没有一种方法可以“输入”部分解决方案,这样这些算法就可以从高级状态开始,而不是从头开始?例如,如果我要解决1000个Dijkstra最短路径问题,每一个问题都与前一个问题不同,只需花费1个弧,从头开始解决每个问题将非常昂贵!我提到了我所知道的。这是对问题标题的回应。当然,我注意到问题文本将话题转向了最大流量算法,否则我会回答而不是评论。一般来说,我在BGL中找不到(其他)关于增量算法的参考。有相当多的关于它的研究,所以可能还有其他图书馆这样做。根据您的特定领域问题,可能很容易在修改时更新您自己的增量图属性。我的逻辑是:实现能够从类似问题的解决方案中获益的算法需要付出大量额外的努力(在极限情况下,您会得到动态算法,即使是“简单”算法也要复杂得多)问题(如MST)。因此,如果他们努力实现这些更困难、更复杂的算法,他们肯定会在文档中宣布这些功能的可用性。
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/boykov_kolmogorov_max_flow.hpp>
#include <boost/graph/edmonds_karp_max_flow.hpp>
#include <boost/graph/push_relabel_max_flow.hpp>
#include <iostream>
using namespace boost;
typedef adjacency_list_traits<vecS, vecS, directedS> Traits;
typedef adjacency_list<
vecS, vecS, directedS,
property<
vertex_name_t, std::string,
property<vertex_index_t, int,
property<vertex_color_t, boost::default_color_type,
property<vertex_distance_t, double,
property<vertex_predecessor_t, Traits::edge_descriptor>
> > > >,
property<
edge_index_t, int,
property<edge_capacity_t, double,
property<edge_weight_t, double,
property<edge_residual_capacity_t, double,
property<edge_reverse_t, Traits::edge_descriptor>
> > > > >
Graph;
int main() {
Graph g;
property_map<Graph, edge_index_t>::type e = get(edge_index, g);
property_map<Graph, edge_capacity_t>::type cap = get(edge_capacity, g);
property_map<Graph, edge_weight_t>::type cost = get(edge_weight, g);
property_map<Graph, edge_residual_capacity_t>::type rescap = get(edge_residual_capacity, g);
property_map<Graph, edge_reverse_t>::type rev = get(edge_reverse, g);
int nonodes = 4;
for (int i = 0; i < nonodes; i++) {
Traits::vertex_descriptor vd;
vd = add_vertex(g);
assert(vd == i);
}
// Create edges
Traits::edge_descriptor edf, edb; // Max flow algorithms seem to want both forward and backward edges. edf is for
// forward, edb is for backward
edf = (add_edge(0, 1, g)).first;
edb = (add_edge(1, 0, g)).first;
e[edf] = 0;
e[edb] = 1;
cap[edf] = 4;
cap[edb] = 4;
rev[edf] = edb;
rev[edb] = edf;
edf = (add_edge(0, 2, g)).first;
edb = (add_edge(2, 0, g)).first;
e[edf] = 2;
e[edb] = 3;
cap[edf] = 4;
cap[edb] = 4;
rev[edf] = edb;
rev[edb] = edf;
edf = (add_edge(1, 3, g)).first;
edb = (add_edge(3, 1, g)).first;
e[edf] = 4;
e[edb] = 5;
cap[edf] = 4;
cap[edb] = 4;
rev[edf] = edb;
rev[edb] = edf;
edf = (add_edge(2, 3, g)).first;
edb = (add_edge(3, 2, g)).first;
e[edf] = 6;
e[edb] = 7;
cap[edf] = 4;
cap[edb] = 4;
rev[edf] = edb;
rev[edb] = edf;
double flow = boykov_kolmogorov_max_flow(g, 0, 3);
std::cout << "Flow: " << flow << "\n";
std::cout << "c flow values:" << std::endl;
//Now trying to change the capacities of certain edges to figure out if boost redoes the problem or intelligently modifies previous solution...
graph_traits < Graph >::out_edge_iterator ei, e_end;
for (tie(ei, e_end) = out_edges(1, g); ei != e_end; ++ei)
if (target(*ei, g) == 3)
cap[*ei] = 5;//Change capacity of forward arc (1,3) to 5
for (tie(ei, e_end) = out_edges(2, g); ei != e_end; ++ei)
if (target(*ei, g) == 3)
cap[*ei] = 5;//Change capacity of forward arc (2,3) to 5
for (tie(ei, e_end) = out_edges(3, g); ei != e_end; ++ei)
if (target(*ei, g) == 1 || target(*ei, g) == 2)
cap[*ei] = 5;//Change capacity of backward arcs (3,1) and (3,2) to 5
flow = boykov_kolmogorov_max_flow(g, 0, 3);
std::cout << "Flow: " << flow << "\n";
}