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

时间:2017-11-27 19:56:55

标签: c++ boost graph-theory breadth-first-search

所以我目前正在研究一个单词阶梯问题的项目,我已经构建了用于存储所有字典单词并在其中添加边缘的图形,我使用boost图形库来完成。

但令我困惑的是breadth_first_search()函数,看起来像参数只占用起始顶点但没有结束顶点。

我检查了文档并注意到我可以为该搜索功能定义BFS访问者,但由于我是升级库的新手,我无法弄清楚它是如何工作的。

有人能解释如何实现找到两个顶点之间的最短路径吗?我正在使用无向且未加权的图表。

#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;
 }

0 个答案:

没有答案