- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我目前正在研究一个单词阶梯问题的项目,我已经构建了用于在其中存储所有字典单词的图形并在其中添加了边,我使用 boost 图形库完成了此操作。
但令我困惑的是 breadth_first_search()
函数,似乎参数只采用起始顶点但没有结束顶点。
我检查了文档并注意到我可以为该搜索功能定义 BFS 访问者,但由于我是 boost 库的新手,我无法弄清楚它是如何工作的。
谁能解释一下如何实现寻找两个顶点之间的最短路径?我正在使用无向和未加权的图。
#include <iostream> // std::cout
#include <fstream>
#include <string>
#include <stdlib.h>
#include <utility> // std::pair
#include "headers.h"
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/graph_utility.hpp>
using namespace std;
//Define a class that has the data you want to associate to every vertex and
edge
//struct Vertex{ int foo;}
// struct Edge{std::string blah;}
struct VertexProperties {
string name;
VertexProperties(string name) : name(name) {}
};
//typedef property<edge_weight_t, int> EdgeWeightProperty;
//typedef property<vertex_name_t, string> VertexNameProperty;
//Define the graph using those classes
typedef boost::adjacency_list<boost::setS, boost::listS, boost::undirectedS,
VertexProperties> Graph;
typedef Graph::vertex_iterator Vit;
typedef Graph::vertex_descriptor Vde;
typedef Graph::edge_descriptor E;
typedef boost::graph_traits<Graph>::adjacency_iterator adjacency_it;
struct my_visitor : boost::default_dijkstra_visitor {
using base = boost::default_dijkstra_visitor;
struct done{};
my_visitor(Vde vd, size_t& visited) : destination(vd), visited(visited) {}
void finish_vertex(Vde v, Graph const& g) {
++visited;
if (v == destination)
throw done{};
base::finish_vertex(v, g);
}
private:
Vde destination;
size_t &visited;
};
//Some typedefs for simplicity
//typedef boost::graph_traits<Graph>::vertex_descriptor vertex_t;
//typedef boost::graph_traits<Graph>::edge_descriptor edge_t;
int main()
{
ifstream dictionary("dictionary.txt");
string word;
Graph allWords;
//Vit begin,end;
if(dictionary.is_open())
{
while(getline(dictionary,word))
{
word.pop_back();
add_vertex(VertexProperties(word),allWords);
}
}
else
cout<<"File openning failed."<<endl;
dictionary.close();
//cout<<num_vertices(allWords)<<endl;
Vit begin,end;
boost::tie(begin, end) = vertices(allWords);
vector<Graph::vertex_descriptor> vindex(begin, end);
int first=0;
int second=0;
for(Vit it=begin;it!=end;it++)
{
for(Vit that=it;that!=end;that++)
{
if(isEditDistanceOne(allWords[*it].name,allWords[*that].name))
add_edge(vindex[first],vindex[second],allWords);
second++;
}
first++;
second=first;
cout<<first<<endl;
}
//Vit temp=begin;
//temp++;
//cout<<allWords[*begin].name<<"////////////////"<<endl;
adjacency_it neighbour, neighbour_end;
for (tie(neighbour, neighbour_end) = adjacent_vertices(*begin, allWords);
neighbour != neighbour_end; ++neighbour)
cout<<allWords[*neighbour].name<<endl;
string firstWord;
string secondWord;
int firstIndex=-1;
int secondIndex=-1;
cout<<"Enter first word:"<<endl;
cin>>firstWord;
cout<<"Enter second word:"<<endl;
cin>>secondWord;
Vit a=begin;
for(int i=0;i<num_vertices(allWords);i++)
{
if(allWords[*a].name==firstWord)
{
firstIndex=i;
break;
}
a++;
}
Vit b=begin;
for(int i=0;i<num_vertices(allWords);i++)
{
if(allWords[*b].name==secondWord)
{
secondIndex=i;
break;
}
b++;
}
if(firstIndex==-1)
cout<<"First word not in graph."<<endl;
else if(secondIndex==-1)
cout<<"Second word not in graph."<<endl;
else
{
Vde start_vertex=vindex[firstIndex];
Vde end_vertex=vindex[secondIndex];
size_t visited;
std::vector<boost::default_color_type> colors(num_vertices(allWords),
boost::default_color_type{});
std::vector<Vde> _pred(num_vertices(allWords),
allWords.null_vertex());
std::vector<size_t> _dist(num_vertices(allWords),
-1ull);
my_visitor vis { end_vertex, visited };
auto predmap = _pred.data(); // interior properties:
boost::get(boost::vertex_predecessor, g);
auto distmap = _dist.data(); // interior properties:
boost::get(boost::vertex_distance, g);
try {
std::cout << "Searching from #" << start_vertex << " to #" << end_vertex
<<
"...\n";
boost::dijkstra_shortest_paths(allWords, start_vertex,
boost::visitor(vis).
color_map(colors.data()).
distance_map(distmap).
predecessor_map(predmap).
weight_map(boost::make_constant_property<E>(1ul))
);
std::cout << "No path found\n";
return 0;
} catch(my_visitor::done const&) {
std::cout << "Percentage skipped: " <<
(100.0*visited/num_vertices(allWords)) << "%\n";
}
}
//cout<<adjacency_list[*begin]<<"\t";
return 0;
}
最佳答案
只要发现目标就中止搜索。
这是一个工作示例
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/random.hpp>
#include <random>
#include <iostream>
using G = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
using V = G::vertex_descriptor;
using E = G::edge_descriptor;
struct my_visitor : boost::default_dijkstra_visitor {
using base = boost::default_dijkstra_visitor;
struct done{};
my_visitor(V vd, size_t& visited) : destination(vd), visited(visited) {}
void finish_vertex(V v, G const& g) {
++visited;
if (v == destination)
throw done{};
base::finish_vertex(v, g);
}
private:
V destination;
size_t &visited;
};
int main() {
#if 1
auto seed = 2912287549; // fixed seed for demo
#else
auto seed = std::random_device{}();
std::cout << "SEED: " << seed << "\n";
#endif
std::mt19937 prng { seed };
G g;
generate_random_graph(g, 100, 400, prng);
print_graph(g);
V start_vertex = prng()%num_vertices(g);
V end_vertex = prng()%num_vertices(g);
size_t visited;
std::vector<boost::default_color_type> colors(num_vertices(g), boost::default_color_type{});
std::vector<V> _pred(num_vertices(g), g.null_vertex());
std::vector<size_t> _dist(num_vertices(g), -1ull);
my_visitor vis { end_vertex, visited };
auto predmap = _pred.data(); // interior properties: boost::get(boost::vertex_predecessor, g);
auto distmap = _dist.data(); // interior properties: boost::get(boost::vertex_distance, g);
try {
std::cout << "Searching from #" << start_vertex << " to #" << end_vertex << "...\n";
boost::dijkstra_shortest_paths(g, start_vertex,
boost::visitor(vis).
color_map(colors.data()).
distance_map(distmap).
predecessor_map(predmap).
weight_map(boost::make_constant_property<E>(1ul))
);
std::cout << "No path found\n";
return 0;
} catch(my_visitor::done const&) {
std::cout << "Percentage skipped: " << (100.0*visited/num_vertices(g)) << "%\n";
}
size_t distance = distmap[end_vertex];
std::cout << "Distance from #" << start_vertex << " to #" << end_vertex << ": " << distance << "\n";
if (distance != size_t(-1)) {
std::deque<V> path;
for (V current = end_vertex;
current != g.null_vertex()
&& predmap[current] != current
&& current != start_vertex;)
{
path.push_front(predmap[current]);
current = predmap[current];
}
std::cout << "Path from #" << start_vertex << " to #" << end_vertex << ": ";
std::copy(path.begin(), path.end(), std::ostream_iterator<V>(std::cout, ", "));
std::cout << end_vertex << "\n";
}
}
它生成具有 100 个顶点和 400 条边的随机无向图。对于特定的演示种子,它会打印以下输出:
0 <--> 45 46 15 83 69 32 38 68 37
1 <--> 29 52 99 85 10 19 30 78
2 <--> 42 7 35 80 25 9 23 23
3 <--> 29 9 15 77 7 58 42
4 <--> 75 56 98 24 14 40 97 34 84 37 80 30 62
5 <--> 58 46 80 71
6 <--> 89 12 47 88 80
7 <--> 62 69 2 86 88 74 8 33 13 76 3 9 86 48
8 <--> 64 26 31 7 94 95 77
9 <--> 83 53 76 3 43 55 7 2 67 72
10 <--> 51 16 21 20 1 63 31
11 <--> 38 50 19 88 16 52
12 <--> 46 6 85 21 61 39
13 <--> 95 24 17 51 7
14 <--> 24 4 43 53
15 <--> 0 51 70 3 43 34
16 <--> 72 10 23 99 28 35 22 11 96 99 19 38 39
17 <--> 84 25 13 54 74 96 28
18 <--> 90 54 88 78
19 <--> 63 11 61 20 73 22 1 63 90 75 16
20 <--> 70 57 79 35 19 10 65 79 45
21 <--> 49 89 43 50 10 38 12 26 67
22 <--> 41 49 95 99 25 39 23 16 19 81
23 <--> 35 16 22 95 2 69 2
24 <--> 76 85 13 42 14 4 85 88
25 <--> 98 17 22 72 92 60 2 51
26 <--> 65 48 62 8 50 86 44 37 21 48
27 <--> 42 82
28 <--> 92 46 89 16 50 53 59 17 94
29 <--> 1 33 3 46 91 96 46 48
30 <--> 60 96 70 79 1 48 4
31 <--> 37 66 50 8 59 72 32 87 10 67
32 <--> 84 77 49 71 0 31 81 75 98 66
33 <--> 29 83 66 7 69 74 80 79
34 <--> 90 59 73 61 47 4 75 87 15
35 <--> 51 23 46 20 16 2 68
36 <--> 70
37 <--> 31 41 77 68 70 26 70 4 0 60
38 <--> 11 65 74 0 21 39 50 94 16 86
39 <--> 48 88 38 22 12 89 16
40 <--> 81 92 86 4 55
41 <--> 22 37 74 64 63 63 79
42 <--> 27 2 24 84 90 65 67 76 72 93 3
43 <--> 51 75 21 54 9 65 14 53 44 15
44 <--> 74 82 26 43
45 <--> 0 86 70 46 94 89 20
46 <--> 0 12 28 35 45 96 5 29 29
47 <--> 96 51 6 82 62 34 88 78
48 <--> 26 99 39 50 59 78 30 29 7 26
49 <--> 21 22 52 32 99 61 55 69 66 57
50 <--> 82 11 31 21 26 65 28 48 38 94 55
51 <--> 43 35 10 47 15 55 13 55 88 25 69 84
52 <--> 86 49 66 1 93 55 11 74 90
53 <--> 89 76 9 76 82 28 77 43 14
54 <--> 87 43 17 98 59 18 66
55 <--> 68 76 51 65 51 81 52 9 49 92 50 40
56 <--> 4 82 95 88 80
57 <--> 20 87 66 62 49
58 <--> 5 3
59 <--> 34 75 71 28 31 48 54 70 96
60 <--> 81 30 81 87 61 61 25 37
61 <--> 78 62 97 19 49 34 12 60 60
62 <--> 7 26 69 87 61 70 92 57 47 90 4
63 <--> 19 41 41 10 72 19
64 <--> 8 92 41 95 86
65 <--> 26 38 50 42 55 43 83 79 20 79
66 <--> 52 31 33 57 87 54 32 49
67 <--> 97 42 98 9 31 21
68 <--> 55 74 96 37 0 98 35
69 <--> 7 97 62 0 97 33 70 49 75 51 23
70 <--> 20 83 45 78 15 69 30 37 62 37 59 78 77 36
71 <--> 83 74 59 32 5 88
72 <--> 16 74 31 25 85 83 42 63 9
73 <--> 74 34 87 19
74 <--> 68 73 41 44 72 71 7 38 17 96 33 82 52
75 <--> 4 43 59 86 32 34 19 69 85
76 <--> 24 53 55 53 9 42 7
77 <--> 32 37 79 53 3 70 96 90 8
78 <--> 61 70 70 48 1 18 47
79 <--> 20 77 41 30 98 65 20 33 65 82
80 <--> 82 81 86 93 56 5 33 2 6 4
81 <--> 40 60 60 80 91 55 32 22
82 <--> 80 50 44 56 88 53 47 27 74 79
83 <--> 9 70 71 0 33 95 72 65
84 <--> 32 17 42 86 4 51
85 <--> 24 96 12 87 24 1 72 89 87 75
86 <--> 52 45 40 7 84 26 75 80 7 64 38
87 <--> 54 57 73 85 62 60 66 31 85 34
88 <--> 7 39 82 56 11 6 51 24 18 47 71
89 <--> 53 21 6 28 99 92 45 85 39
90 <--> 34 42 96 18 77 19 62 52
91 <--> 81 29
92 <--> 28 40 64 62 25 89 55
93 <--> 52 80 42
94 <--> 8 45 50 28 38
95 <--> 22 13 83 56 23 64 8
96 <--> 85 47 30 68 46 90 74 17 16 77 29 59
97 <--> 69 67 61 69 4
98 <--> 25 4 54 79 68 67 32
99 <--> 22 48 16 89 1 49 16
Searching from #20 to #27...
Percentage skipped: 91%
Distance from #20 to #27: 3
Path from #20 to #27: 20, 65, 42, 27
如您所见,91% 的节点未被访问。
文档说当边缘权重恒定时使用广度优先搜索。遗憾的是我无法完成这项工作。
假设算法等价性被断言,使用早出的路径仍然是最短的(假设边缘权重是常数)。
关于c++ - 如何找到 BGL 图中两个顶点之间的最短路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47518846/
我想使用并行 MST 算法 dense_boruvka_minimum_spanning_tree从 boost 。 该算法接口(interface)的一个必需参数是“必须是顶点列表图和分布式边列表图
这个问题是关于Boost Graph Library的。 假设我的图形类型定义如下: using Graph = boost::adjacency_list; 现在,如果我理解正确的话,可以将新的St
我似乎无法弄清楚如何让 BGL 的推送重新标记最大流量算法与捆绑属性一起使用。 像这样设置图表: struct VertexProperties{ }; struct EdgeProperties{
我想用子图实现加权无向图。这是我对该图的初始化代码: #include #include typedef boost::property EdgeWeightProperty; typedef b
下面是一些使用 bgl 创建图形并遍历顶点的示例代码。我想以随机顺序进行此迭代 - 换句话说:循环应该操纵每个顶点,但是对于主函数的每次调用,顶点的顺序应该是随机的。我怎样才能做到这一点? 我用 st
我正在尝试通过编写自定义 DFS 访问器(class TarjanVisitor : public default_dfs_visitor)在 BGL 中实现桥接检测算法 (tarjan),并且我正在
我开始使用 BGL 来完成一些与图形相关的任务。我有很多边,每条边都有几个属性,其中之一就是它的权重。 (所有属性都是 float 和整数)。由于我以前从未使用过 BGL(和/或类似的 CPP 库),
我想让所有边都具有属性、重量和容量。我发现 BGL 已经定义了这些。所以我为图定义了 Edge 和 Vertex 属性 typedef property VertexProperty; typed
我的要求是有一个图形结构,其中每个顶点都由 boost::uuids::uuid 唯一标识。 .所有顶点都有一个颜色属性,相似类别的顶点将根据该颜色属性进行分组。我不是在静态 map 上工作,顶点和边
我正在努力从我的图中删除所有没有连接边的节点(使用定义的模式 here )。到目前为止,我的 (MWE) 代码如下: //g++ -O3 question.cpp -o question.exe #i
我是 BGL( boost 图形库)的新手。我正在学习breadth_first_search 界面,它看起来很方便。但是,在我的应用程序中,当满足其他一些终止条件(例如搜索空间节点数满足最大值)时,
借鉴this回复,我试过如下实现介数中心性: typedef struct vpr_ { int id; } VProp; typedef boost::adjacency_l
我尝试使用boost的transitive_reduction,但是我不知道怎么用。 我有一个图表定义为: typedef boost::adjacency_list Graph; typedef G
我想知道是否有一种方法可以在不使用 lambda 函数的情况下获得 boost 图边缘的排序 vector 。 即我目前正在这样排序: std::vector edgs = ...; std::sor
在 bgl iteration_makros.hpp , 它说 Use the _T versions when the graph type is a template parameter or d
所以我目前正在研究一个单词阶梯问题的项目,我已经构建了用于在其中存储所有字典单词的图形并在其中添加了边,我使用 boost 图形库完成了此操作。 但令我困惑的是 breadth_first_searc
我想在检查边缘时更改边缘权重,但它告诉 error: assignment of member ‘EdgeProperty::weight’ in read-only object g[e].weig
Example code来自 BGL: breadth_first_search(g, vertex(s, g), color_map(get(&VertexProps::color, g)).vis
我正在阅读某人的代码。这是来自 boost 图形库的函数。这是原始函数定义。 void dijkstra_shortest_paths (const Graph& g, t
我希望多线程使用BGL的dijkstra_shortest_paths和astar_search函数,然后读取结果顶点和边的属性映射。 我想知道我是否应该使用互斥锁来确保线程安全。 所以这是我的问题:
我是一名优秀的程序员,十分优秀!