C++ 用BFS算法求无权有向图中两节点间的所有最短路径

C++ 用BFS算法求无权有向图中两节点间的所有最短路径,c++,breadth-first-search,shortest,C++,Breadth First Search,Shortest,我正在研究一个问题,我需要在给定的有向无权图中找到两个节点之间的所有最短路径。我使用BFS算法来完成这项工作,但不幸的是,我只能打印一条最短路径,而不是所有路径,例如,如果它们是长度为3的4条路径,我的算法只打印第一条路径,但我希望它打印所有四条最短路径。在下面的代码中,我想知道应该如何更改它,以便打印出两个节点之间的所有最短路径 class graphNode{ public: int id; string name; bool stat

我正在研究一个问题,我需要在给定的有向无权图中找到两个节点之间的所有最短路径。我使用BFS算法来完成这项工作,但不幸的是,我只能打印一条最短路径,而不是所有路径,例如,如果它们是长度为3的4条路径,我的算法只打印第一条路径,但我希望它打印所有四条最短路径。在下面的代码中,我想知道应该如何更改它,以便打印出两个节点之间的所有最短路径

class graphNode{
    public:
        int id;
        string name;
        bool status;
        double weight;
};


map<int, map<int,graphNode>* > graph; 


int Graph::BFS(graphNode &v, graphNode &w){

    queue <int> q;
    map <int, int> map1;  // this is to check if the node has been visited or not.
    std::string str= "";
    map<int,int> inQ;  // just to check that we do not insert the same iterm twice in the queue


    map <int, map<int, graphNode>* >::iterator pos;
    pos = graph.find(v.id);
    if(pos == graph.end()) {
        cout << v.id << " does not exists in the graph " <<endl;
        return 1;

    }

    int parents[graph.size()+1];   // this vector keeps track of the parents for the node
    parents[v.id] = -1;


    if (findDirectEdge(v.id,w.id) == 1 ){
        cout << " Shortest Path: " << v.id << " -> " << w.id << endl;
        return 1;
    } //if
    else{
        int gn;
        map <int, map<int, graphNode>* >::iterator pos;

        q.push(v.id);
        inQ.insert(make_pair(v.id, v.id));

        while (!q.empty()){
        gn = q.front();
        q.pop();
        map<int, int>::iterator it;
        cout << " Popping: " << gn <<endl;
        map1.insert(make_pair(gn,gn));


        if (gn == w.id){//backtracing to  print all the nodes if gn is the same as our target node such as w.id
            int current = w.id;
            cout << current << " - > ";
            while (current!=v.id){
                current = parents[current];
                cout << current << " -> ";
            }
        cout <<endl;
        }
                          if ((pos = graph.find(gn)) == graph.end()) {
            cout << " pos is empty " <<endl;
            continue;
        }
        map<int, graphNode>* pn = pos->second;

                          map<int, graphNode>::iterator p = pn->begin();
        while(p != pn->end()) {
            map<int, int>::iterator it;

            it = map1.find(p->first);//map1 keeps track of the visited nodes
            graphNode gn1= p->second;
            if (it== map1.end())    {
                map<int, int>::iterator it1;
                it1 = inQ.find(p->first);  //if the node already exits in the inQ, we do not insert it twice

                if (it1== inQ.end()){
                    parents[p->first] = gn;
                    cout << " inserting " << p->first << " into the queue " <<endl;
                    q.push(p->first);  // add it to the queue
                } //if
            }  //if
            p++;
          } //while

    } //while
}
类图形节点{
公众:
int-id;
字符串名;
布尔状态;
双倍重量;
};
地图图;
int-Graph::BFS(graphNode&v、graphNode&w){
队列q;
map map1;//检查节点是否已被访问。
std::string str=“”;
map inQ;//只是为了检查我们没有在队列中插入相同的iterm两次
迭代器位置;
pos=图形查找(v.id);
if(pos==graph.end()){
库特
  • map-graph
    声明一个每边有一个
    graphNode
    对象的图

    每个节点的一个
    graphNode
    将具有类型
    map
    ,或者更好的是,
    map
    ,或者更好的是,
    multimap

    graphNode
    s需要从您使用的
    map
    存储在单独的结构中(例如,
    vector
    deque

  • int父项[graph.size()+1];
    是非标准的。请改用
    向量父项(graph.size()+1);

  • 要回答您的问题,您需要继续BFS,直到到达拓扑顺序大于第一个结果的第一个节点。请引入变量
    int first\u id\u of_next\u level=v.id;
    (或者更好,使用指针)找到匹配项后,将其路径附加到路径列表中。当
    gn==first\u id\u of_next\u level
    时,如果列表不是
    empty
    返回该列表,或者设置
    first\u id\u of_next\u level=p->first
    ,即当前父级的第一个子级,这样您就知道下一次停止搜索的机会


  • 要编写所有最短路径,您必须编写一个类似DFS的递归算法。运行BFS以查找到每个节点的最小距离,存储该距离,然后从源节点运行DFS,仅分支到满足最小路径的节点。每当到达目标节点时,请编写到达目标节点的路径(您一直在递归函数中跟踪它)。请注意,您不会在DFS中标记节点

    由于该算法需要回溯,因此最好的方法是通过递归DFS。您可以使用BFS编写该算法,但您必须维护堆栈以跟踪回溯,这意味着您实际上是使用手动维护的堆栈编写DFS,即使用两倍于您需要的代码编写完全相同的算法对


    请注意,最短路径的数量并不总是多项式的,因此您可能正在编写指数数量的路径。

    您的算法是正确的,但措词不正确,很容易与拓扑排序混淆,拓扑排序与最短路径无关。存在O(E)算法而不是指数1@bitec不,没有。怎么可能有一个线性算法来写指数数量的项目?说话之前先想一想。对不起,我错了。我的意思是使用编辑过的BFS的算法需要O(E)准备路径,然后可以按指数方式打印它们。但我的意思是,在找到最小距离(M)后的变体中,您建议使用修改的DFS来查找所有路径(不将节点标记为永久访问,但仅在递归循环中)当路径超过M时,完成递归。这可能导致指数工作,即使只有几个最短路径。这就是我的意思