c++ - 没有对角线移动的 Dijkstra 算法

标签 c++ path dijkstra path-finding

对不起,如果这个问题有点愚蠢,但我找不到合适的解决方案。我想获得从一个点到另一个点的最短路径。我在互联网上找到了一个代码,但是这个代码给了我对角线的路径,我只需要垂直和水平移动。任何人都可以告诉我我应该改变什么?因为我尝试了几次修改,但似乎都不起作用。这是代码:

提前致谢。

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

class Cell 
{    
    int x;
    int y;

    public:

        int getx(){ 
            return x; 
        }
        int gety(){ 
            return y; 
        }
        void setx(int x){
            this->x = x;
        }
        void sety(int y){
            this->y = y;
        }
        bool operator==(Cell o) {
            return x==o.x && y==o.y;
        }
        Cell operator=(Cell o) {
            x = o.x; 
            y = o.y; 
            return *this;
        }
        Cell(int x, int y):x(x),y(y){ }
        Cell():x(0),y(0){}
};
vector<Cell> getShortestPath(Cell ori, Cell dest, int array[], int width, int height);

int main()
{
    int ejemplo[] = {
        0,1,0,1,0,0,0,0,        //0: void
        0,1,0,1,0,0,0,0,        //1: obstacle
        0,1,0,1,0,0,0,0,
        0,1,0,1,0,0,0,0,
        0,1,0,1,0,0,0,0,
        0,1,0,1,0,0,0,0,
        0,0,0,1,0,0,0,0,
        0,0,0,0,0,0,0,0};

    vector<Cell> camino= getShortestPath(Cell(2,0),Cell(0,7),ejemplo,8,8);

    for(int i = 0; i < camino.size(); i++) {
        cout << "(" << camino[i].getx() << ", " << camino[i].gety() << ")" << endl;
    }
}

vector<Cell> getShortestPath(Cell ori, Cell dest, int array[], int width, int height)
{
    if ( ori == dest ) 
        return vector<Cell>();

    unsigned int *sizes = new unsigned int[width*height];
    Cell *prev = new Cell[width*height];

    for(int i = 0; i < width*height; i++) {
        sizes[i] = -1; 
        prev[i] = Cell(-1,-1);
    }

    sizes[ori.getx()+ori.gety()*width] = 0;
    prev[ori.getx()+ori.gety()*width] = ori;


    queue<Cell> porVisitar;
    porVisitar.push(ori);

    while(!porVisitar.empty())
    {
        Cell cur = porVisitar.front();
        porVisitar.pop();
        cout << porVisitar.size() << endl;

        for(int i = -1; i < 2; i++)
           for(int j = -1; j < 2; j++)
                if((cur.getx()+j)>=0 && (cur.getx()+j)<width && (cur.gety()+i)>=0 && (cur.gety()+i)<height &&      //is not out of bounds
                 array[(cur.getx()+j)+(cur.gety()+i)*width]==0 &&           //is not an obstable
                 sizes[cur.getx()+cur.gety()*width]+1 < sizes[(cur.getx()+j)+(cur.gety()+i)*width]      //there is not a better path
                ) {
                    sizes[(cur.getx()+j)+(cur.gety()+i)*width]=sizes[cur.getx()+cur.gety()*width]+1;
                    prev[(cur.getx()+j)+(cur.gety()+i)*width]=Cell(cur.getx(),cur.gety());
                    porVisitar.push(Cell(cur.getx()+j,cur.gety()+i));
                }
    }

    if(prev[dest.getx()+dest.gety()*width]==Cell(-1,-1)) 
        return vector<Cell>();

    Cell pp = dest;
    vector<Cell> res(sizes[dest.getx()+dest.gety()*width]+1);

    for(int i = res.size()-1; !(pp == ori); i-- )
    {
         res[i] = pp;
         pp = prev[pp.getx()+pp.gety()*width];
     }

     return res;

最佳答案

考虑子图:

a b c
d N e
f g h

N 是您当前的节点/顶点。将邻居添加到潜在路径列表(或队列或其他)时,仅添加 bdeg 。上面的代码添加了a-h

提示:这发生在嵌套的for 循环中。

回答:条件应该是if((i != -1 && i != 1) || (j != 1 && j != -1)).

关于c++ - 没有对角线移动的 Dijkstra 算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29480691/

相关文章:

image - Vue img src 路径与 :src 不一样

linux - pathconf( ) linux 等效 windows API

c++ - 两点之间网格中的最短路径。有一个陷阱

algorithm - 查找具有两个负边的图中从给定节点 s 到 V 中所有节点的最短路径距离

c++ - 如何为 linux 机器创建 Qt 可执行文件

c++ - 如何在 C++ 中的列表末尾推断出模板参数?

url - 为什么 require.js 忽略配置 baseUrl 和路径

algorithm - Dijkstra 的(或其他最短路径算法),其中结束节点可以是开始节点

c++ - 不支持 clang 3.5 中的 -finline-functions?

c++ - 实现宏 for while 循环