简体   繁体   English

在C ++中使用BFS的最短路径

[英]Shortest path using BFS in C++

I have to write an algorithm to find the shortest path in an unweighted graph. 我必须编写一种算法来找到未加权图中的最短路径。 I found out that the best way to find the shortest path in an unweighted graph is to simply perform a BFS and stop once the destination is reached. 我发现在未加权图中找到最短路径的最佳方法是简单地执行BFS,并在到达目标位置后停止。 The problem is I don't know how to keep track of the path that led to that destination. 问题是我不知道如何跟踪通往该目的地的路径。

So far I've thought about creating a new path list for every new node that is discovered, but I can't figure out how to implement that. 到目前为止,我已经考虑过为发现的每个新节点创建一个新的路径列表,但是我不知道该如何实现。

This code seems to be working so far as visiting every node goes (it's a bit messy, sorry): 只要访问每个节点,此代码似乎就可以正常工作(有点混乱,抱歉):

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();
    }
}

Any ideas? 有任何想法吗?

You can store the shortest path tree by keeping, for each vertex v , the name of v 's parent in the shortest path tree. 您可以通过在最短路径树中为每个顶点v保留v的父级名称来存储最短路径树。 Then you can reconstruct whichever shortest path you want by following these parent pointers until you get to the source vertex. 然后,可以通过遵循这些父指针,直到到达源顶点,来重构所需的最短路径。

Add vertex *parent to your vertex class whatever that is, and add one more input *vertex to your push function and change this line: vertex *parent添加到您的顶点类中,无论如何,再将一个输入*vertex添加到您的push函数中并更改此行:

myQueue.push(extractList((*it)->name, listVertices)); myQueue.push(extractList((* it)-> name,listVertices));

to this: 对此:

myQueue.push(extractList((*it)->name, listVertices),*vert); myQueue.push(extractList((* it)-> name,listVertices),* vert);

after you myQueue.pop(); 在您myQueue.pop(); check if poped node is your destination if it is, break from while loop and start from your destination and with a loop print(or whatever you do) every node->parent and then node = node->parent until your reach the source. 检查poped节点是否是您的目的地,从while循环中断并从目的地开始,并循环打印(或执行任何操作)每个node->parent node = node->parent ,然后node = node->parent直到到达源node = node->parent

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM