如何使用广度优先搜索获得2个节点之间的路径?

时间:2011-03-01 02:41:43

标签: search graph path breadth-first-search

我正在尝试在图表中的两个节点之间找到路径,其中边缘未加权

我正在使用广度优先搜索,它会在找到目标时停止,以便找到路径的存在,但我不知道如何获取路径本身。

我尝试查看访问过的节点列表,但这似乎没有帮助。 我看到有人用prolog回答了这个问题,但我是一名C ++程序员。

我也看了Dijkstras algorithm,但这似乎过度杀人,因为一个简单的广度优先搜索让我几乎全程。

如何使用广度优先搜索获取2个节点之间的路径?

2 个答案:

答案 0 :(得分:22)

在节点结构中,添加一个名为parentNode的变量,该变量是路径中该节点的父节点。最后,您可以通过向后遍历目标节点来检索路径。

答案 1 :(得分:0)

我发现了一个简单的算法,该算法将到节点的路径以及节点中的节点存储在此处:https://stackoverflow.com/a/50575971/5883177 因此,当我们从队列中弹出一个节点时,我们也很容易获得到该节点的路径。

链接中的代码在python中,它使用元组存储该对。这是使用std :: pair的C ++实现。

bool findPath(Node *n1, Node *n2, vector<Node*> &path)
{
    // We use queue to perform a BFS traversal and in addition to storing the
    // node we'll also store the path so far to the node.
    queue<pair<Node*,vector<Node*>>> q;
    
    // Visit the first node and add it to the queue.
    n1->visited=1;
    // Form the path, create a pair and add it the queue.
    vector<Node*> p;
    p.push_back(n1);
    q.push(make_pair(n1,p));
    
    while(!q.empty())
    {
        pair<Node*,vector<Node*>> curPair = q.front();
        q.pop();
        
        // visit all the unvisited nodes and check if there is n2 in it.
        for(Node *u : curPair.first->adjNodes ){
            if(u->visited == 0){
                
                if(u->value == n2->value){
                    // found our destination. Return true
                    // form the path by appending this node to the path till now
                    curPair.second.push_back(u);
                    // update the passed 'path' vector with the path so far.
                    path = curPair.second; // all nodes will be copied into path
                    return true;
                }
                
                // Not our node, visit the node if unvisited
                if(u->visited == 0){
                    u->visited = 1;
                    // Create a new path with this node added.
                    // Path so far can be obtained from the pair in queue
                    vector<Node*> newPath(curPair.second);
                    newPath.push_back(u);
                    // Add the node and the path to it into the queue.
                    q.push(make_pair(u, newPath));
                }
            }
        }
    }
    
    return false;
}


class Node{
    public:
    Node(int val) 
    { 
        value = val; 
        visited=0; 
    }
        
    int value;
    vector<Node*> adjNodes;
    int visited;
};