我必须编写一个算法来查找未加权图中的最短路径。我发现在未加权图中找到最短路径的最佳方法是简单地执行BFS并在到达目的地后停止。问题是我不知道如何跟踪导致该目的地的路径。
到目前为止,我已经考虑过为每个发现的新节点创建一个新的路径列表,但我无法弄清楚如何实现它。
这个代码似乎在访问每个节点时都有效(它有点乱,对不起):
void shortestPath(string start, string finish, list< list<string> > adjList){
queue< list< list<vertex*> >::iterator > myQueue;
list< list<vertex*> > listVertices = initializeVertices(start, adjList);
list< list<vertex*> >::iterator aux = extractList(start, listVertices);
myQueue.push(aux);
while(myQueue.size() > 0){
list< list<vertex*> >::iterator vert = myQueue.front();
for(list<vertex*>::iterator it = vert->begin(); it != vert->end(); it++){
if((*it)->color == "white"){
(*it)->color = "gray";
myQueue.push(extractList((*it)->name, listVertices));
}
}
list<vertex*>::iterator vertAux = vert->begin();
(*vertAux)->color = "black";
myQueue.pop();
}
}
有什么想法吗?
答案 0 :(得分:2)
您可以通过为每个顶点v
保留最短路径树中v
的父级的名称来存储最短路径树。然后,您可以通过跟随这些父指针重建所需的最短路径,直到到达源顶点。
答案 1 :(得分:1)
将vertex *parent
添加到您的顶点类中,然后向您的*vertex
函数添加一个输入push
并更改此行:
myQueue.push(extractList((* it) - &gt; name,listVertices));
到此:
myQueue.push(extractList((* it) - &gt; name,listVertices),* vert);
在myQueue.pop();
检查poped
节点是否是您的目的地之后,从while循环中断并从目的地开始并使用循环打印(或您执行的任何操作){{1} }然后node->parent
直到你到达来源。
答案 2 :(得分:1)
//Breadth first Search Shortest Path
//It is implemented using Queue Linked list representation
//It is used to pind the shortest path from destination to the source
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
typedef struct queue1{
int info;
struct queue1 *next;
}node;
void createqueue(node **front1,node **rear1){
*front1=*rear1=NULL;
}
void pushqueue(node **front1, node **rear1,int item){
node *ptr;
ptr=(node *)malloc(sizeof(node));
ptr->info=item;
ptr->next=NULL;
if((*front1)==NULL)
*front1=*rear1=ptr;
else{
(*rear1)->next=ptr;
*rear1=ptr;
}
}
int popqueue(node **front1){
int item;
node *ptr;
ptr=*front1;
item=ptr->info;
*front1=ptr->next;
return item;
}
int peekqueue(node *front1){
return front1->info;
}
bool isEmpty(node *front1){
if(front1==NULL)
return true;
return false;
}
int main(){
int graph[7][7]={
{0,1,1,0,0,0,0},
{1,0,0,1,1,0,0},
{1,0,0,0,0,1,1},
{0,1,0,0,0,0,0},
{0,1,0,0,0,0,0},
{0,0,1,0,0,0,0},
{0,0,1,0,0,0,0},
};
int src;
cout << "Following is Breadth First Traversal (starting from vertex 0) \n";
cin>>src;
int parent[10];
parent[src]=-1; //Source is the root node
cout<<"Breadth First Search\n";
node *front1;
node *rear1;
int choice,element,temp;
createqueue(&front1,&rear1);
pushqueue(&front1,&rear1,src);
bool visited[7];
for(int i=0;i<7;i++) //Mark all nodes as visited as false
visited[i]=false;
while(!isEmpty(front1)){
src=popqueue(&front1);
cout<<src<<"\t";
if(!visited[src]){
for(int i=0;i<7;i++){
if(graph[src][i] && !visited[i]){
parent[i]=src; //TO get the predessecor of the node which will help in backtracking
pushqueue(&front1,&rear1,i);
}
}
visited[src]=true;
}
}
int destination;
cout<<"\nEnter destination = \n";
cin>>destination;
int j=destination;
cout<<"Path from "<<j<<" to root node is as follows\n";
//Backtrack from destination to root node
do{
cout<<""<<j<<"\t";
j=parent[j];
}while(j!=-1);
cout<<"Thank You\n";
return 0;
}