简体   繁体   English

BFS 打印最短路径

[英]BFS print shortest path

I am trying to implement BFS algorithm to find the shortest path on a uniformly weighted graph.我正在尝试实现 BFS 算法以在均匀加权图上找到最短路径。 The code below is a straight implementation of the BFS from here: https://www.redblobgames.com/pathfinding/a-star/introduction.html下面的代码是从这里直接实现的 BFS: https://www.redblobgames.com/pathfinding/a-star/introduction.html

void print_path(vector<vector<int>> & gr, int xf, int yf, int xt, int yt)
{
    /* Cell neighbours */
    const vector<pair<int,int>> nbr {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};

    /* route breadcrumbs */
    map<pair<int,int>,pair<int,int>> route;
    queue<pair<int,int>> q;

    /* Represent each node as a pair<int,int> */
    pair<int,int> start = {xf, yf};
    pair<int,int> end = {xt, yt};

    /* NULL node */
    route[start] = {-1, -1};
    q.push(start);

    while (!q.empty()) {
        auto current = q.front();
        q.pop();

        if (current == end) break;

        /* Iterate through all possible neighbours */
        for (const auto & n : nbr) {
            /* pair<int,int> operator+ overloaded */
            auto next = current + n;

            /* Can move to the next node and it is not yet in the route */
            if (can_move_to(next, gr) && route.find(next) == route.end()) {
                q.push(next);
                route[next] = current;
            }
        }
    }

    /* Trace back the shortest path */
    while (route[end] != pair<int,int>(-1, -1)) {
        cout << end.first << ';' << end.second << endl;
        end = route[end];
    }
    /* Print the starting node */
    cout << end.first << ';' << end.second << endl;
}

Maybe I miss something, but the code does not yield the shortest path (and I don't see why should it).也许我错过了一些东西,但代码没有产生最短路径(我不明白为什么要这样做)。 This function prints the path along the right angle sides, rather than "wiggle" around the hypotenuse.此 function 沿直角边打印路径,而不是围绕斜边“摆动”。

Well, with the help of paper and pencil, the solution was pretty obvious (yet I can not prove it).好吧,在纸和铅笔的帮助下,解决方案非常明显(但我无法证明)。 If I alter the neighbours iteration order each "layer", then the diagonal paths will alter it's direction and so yield the valid (shortest?) path.如果我改变每个“层”的邻居迭代顺序,那么对角线路径将改变它的方向,从而产生有效的(最短的?)路径。 That being said, the inner nbr loop should look something like this:话虽如此,内部 nbr 循环应该如下所示:

if ((current.first + current.second) & 1) {
    /* Odd layers */
    for (auto it = nbr.begin(); it != nbr.end(); it++) {
        auto next = current + *it;
        if (can_move_to(next, gr) && route.find(next) == route.end()) {
            q.push(next);
            route[next] = current;
        }
    }
}
else {
    /* Even layers */
    for (auto it = nbr.rbegin(); it != nbr.rend(); it++) {
        auto next = current + *it;

        if (can_move_to(next, gr) && route.find(next) == route.end()) {
            q.push(next);
            route[next] = current;
        }
    }
}

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

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