gpt4 book ai didi

c++ - Boost Graph bellman_ford_shortest_paths 与 labeled_graph

转载 作者:行者123 更新时间:2023-11-30 04:52:55 24 4
gpt4 key购买 nike

我正在尝试使用 Boost 库运行 Bellman-Ford 算法。我有一个带标签的图表,但我收到异常 invalid conversion from ‘void*’ to ‘int。任何帮助将不胜感激。这是我的代码:

// g++ -std=c++17 -Wall test.c++ -l boost_system && ./a.out 

#include <iostream> // for cout
#include <utility> // for pair
#include <algorithm> // for for_each
#include <vector> // For dist[] and pred[]
#include <limits> // To reliably indicate infinity
#include <map>
#include <list>

#include <boost/config.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/directed_graph.hpp>
#include <boost/graph/labeled_graph.hpp>
#include <boost/graph/bellman_ford_shortest_paths.hpp>

using namespace boost;
using namespace std;

class Node
{
public:
int id;
int group;
};

struct EdgeProperties {
double weight;

EdgeProperties(){}
EdgeProperties(double w){ weight = w; }
};

typedef labeled_graph<adjacency_list<hash_setS, hash_setS, directedS, Node, EdgeProperties>, int> Graph;

int main(){

cout << "Calling main()" << endl;

Graph g;

// populate the graph
{
add_vertex( 0, g );
g[0].id = 0;
g[0].group = 10;
add_vertex( 1, g );
g[1].id = 1;
g[1].group = 20;
add_edge_by_label( 0, 1, EdgeProperties(110), g);
add_edge_by_label( 1, 0, EdgeProperties(222), g);
print_graph(g, get(&Node::id, g));
cout << "There are " << num_vertices(g) << " nodes and " << num_edges(g) << " edges in the graph" << endl;
}

// number of verticies in the graph
auto n = num_vertices(g);

// weight map
auto ewp = weight_map(get(&EdgeProperties::weight, g.graph()));

const int source = 0;
const int target = 1;

// Distance Map (with n elements of value infinity; source's value is 0)
auto inf = numeric_limits<double>::max();
vector<double> dist(n, inf);
dist[source] = 0.0;

// Predecessor Map (with n elements)
vector<int> pred(n);

bellman_ford_shortest_paths(
g.graph(),
n,
ewp
.distance_map(make_iterator_property_map(dist.begin(), get(&Node::id, g)))
.predecessor_map(make_iterator_property_map(pred.begin(), get(&Node::id, g)))
);

return 0;
}

我在 https://www.boost.org/doc/libs/1_53_0/libs/graph/example/bellman-example.cpp 上看到了这个例子但该示例未使用带标签的图形。

这是我的代码的实时预览:

https://wandbox.org/permlink/WsQA8A0IyRvGWTIj

谢谢

最佳答案

问题的根源在您接受的现有答案中触及。

然而,还有更多。

首先,您几乎“有权”使用 Node::id 作为顶点索引,并且可能有很多很好的理由使用 vector 以外的东西 作为顶点容器选择器¹。

其次,那些东西应该......可能已经奏效了。 bellman_ford documents :

The PredecessorMap type must be a Read/Write Property Map which key and vertex types the same as the vertex descriptor type of the graph.

iterator_property_map documents :

This property map is an adaptor that converts any random access iterator into a Lvalue Property Map. The OffsetMap type is responsible for converting key objects to integers that can be used as offsets with the random access iterator.

现在LValuePropertyMap 可能实际上是只读的,但在这种情况下显然不应该是。

当使用带有附加 id-map 参数的 make_iterator_property_map 时,它实际上应该表现得像任何关联属性映射一样,键和值类型 vertex_descriptor 都符合算法。

UPDATE See "BONUS" below

稍后我可能会更详细地了解为什么它不起作用,但现在让我们在不修改图形模型的情况下解决这个问题:

Live On Coliru

auto gg = g.graph();
auto id = get(&Node::id, gg);
std::map<Graph::vertex_descriptor, Graph::vertex_descriptor> assoc_pred;

bellman_ford_shortest_paths(gg, n,
weight_map(get(&EdgeProperties::weight, gg))
.distance_map(make_iterator_property_map(dist.begin(), id))
.predecessor_map(make_assoc_property_map(assoc_pred))
);

它按预期工作:

Calling main()
1 --> 0
0 --> 1
There are 2 nodes and 2 edges in the graph

奖金

我找到了缺失的链接:前身 map 定义了错误的值类型:

vector<Graph::vertex_descriptor> pred(n);

显然会起作用: Live On Coliru


¹ 这与顶点描述符略有不同,但在某种意义上是相关的,即顶点容器的选择通常会预测顶点描述符的实际类型

关于c++ - Boost Graph bellman_ford_shortest_paths 与 labeled_graph,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54048847/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com