C++ 如何在BGL图中找到两个顶点之间的最短路径?

C++ 如何在BGL图中找到两个顶点之间的最短路径?,c++,boost,graph-theory,breadth-first-search,C++,Boost,Graph Theory,Breadth First Search,因此,我目前正在进行一个单词阶梯问题的项目,我已经构建了一个用于存储所有字典单词的图,并在其中添加了边,我使用boost graph library完成了这项工作 但让我困惑的是,width\u first\u search()函数的参数似乎只取起始顶点,而不取结束顶点 我查看了文档,注意到我可以为该搜索功能定义BFS访问者,但由于我是boost库的新手,我无法理解它是如何工作的 有人能解释一下如何在两个顶点之间找到最短路径吗?我使用的是一个无向无权图 #include <iostream

因此,我目前正在进行一个单词阶梯问题的项目,我已经构建了一个用于存储所有字典单词的图,并在其中添加了边,我使用boost graph library完成了这项工作

但让我困惑的是,
width\u first\u 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;
 }
#包括//std::cout
#包括
#包括
#包括
#include//std::pair
#包括“headers.h”
#包括
#包括
#包括
使用名称空间std;
//定义一个类,该类包含要关联到每个顶点和顶点的数据
边缘
//结构顶点{int foo;}
//结构边缘{std::string blah;}
结构顶点属性{
字符串名;
顶点属性(字符串名称):名称(名称){}
};
//typedef属性EdgeWightProperty;
//typedef属性VertexNameProperty;
//使用这些类定义图形
typedef boost::邻接列表图;
typedef图::顶点迭代器Vit;
typedef图形::顶点描述符Vde;
typedef图形::边描述符E;
typedef boost::graph_traits::邻接迭代器邻接it;
struct my_visitor:boost::default_dijkstra_visitor{
使用base=boost::default\u dijkstra\u visitor;
结构完成{};
我的访客(Vde vd,大小和访问):目的地(vd),访问(访问){
虚空顶点(Vde v,图形常量和g){
++参观;
if(v==目的地)
抛出完成{};
底:完成顶点(v,g);
}
私人:
Vde目的地;
参观和访问的规模;
};
//有些typedef为简单起见
//typedef boost::graph_traits::vertex_描述符vertex_t;
//typedef boost::graph_traits::edge_描述符edge_t;
int main()
{
ifstream字典(“dictionary.txt”);
字符串字;
图形化所有单词;
//Vit开始,结束;
if(dictionary.is_open())
{
while(getline(字典、单词))
{
单词pop_back();
添加_顶点(顶点属性(word)、所有word);
}
}
其他的

当你发现你的目标时,可以中止搜索

这是一个工作样本

#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";
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
使用G=boost::邻接列表;
使用V=G::vertex\u描述符;
使用E=G::edge\u描述符;
struct my_visitor:boost::default_dijkstra_visitor{
使用base=boost::default\u dijkstra\u visitor;
结构完成{};
我的访客(V vd,大小和访问):目的地(vd),访问(访问){
空心饰面_顶点(V、G常量和G){
++参观;
if(v==目的地)
抛出完成{};
底:完成顶点(v,g);
}
私人:
V目的地;
参观和访问的规模;
};
int main(){
#如果1
自动种子=2912287549;//已修复演示的种子
#否则
自动种子=std::random_设备{}();

std::cout怎么样?谢谢回答!但我这里有另一个问题。我在我的项目中尝试了你的代码,但编译时它给了我一些错误,看起来有些boost函数与模板不匹配,所以既然我使用的是无向和未加权的图,这是原因吗?或者我必须在某些特定的条件下编译它n环境?Ps:我正在使用linux编译它。谢谢。@booooo老实说,这不是寻求帮助的方式。你看过我的代码吗?你检查过我的版本是否使用无向图吗?你检查过它是否未加权吗?你看到我的“注释”了吗关于恒定权重?如果您无法检查这些差异,为什么不包括您自己的代码,以便其他人可以为您进行检查?据我所知,我现在已经为您编写了完整的示例。如果您不能将其集成到您自己的代码中,我们将无能为力。我们看不到无形的问题(我只能猜测).我不能去帮个忙。相反,我建议下次发布一个或。我真的很抱歉出现这种混乱……我正要出去,所以我没有发布我的代码。我现在已经发布了,所以问题是我使用一个无向和未加权的图来试图找到两个单词之间的最短路径,编译器显示一些错误如下所示:/home/b/bowu/boost_1_66_0/boost/graph/detail/adjacence_list.hpp:2550:53:错误:形成对void const_类型的引用^
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