【问题标题】:Algorithm to find the shortest path, with obstacles找到最短路径的算法,有障碍物
【发布时间】:2011-07-15 06:47:32
【问题描述】:

我有一个代表网格的点集合,我正在寻找一种算法,可以让我获得点 A 和 B 之间的最短距离。 任何一点(不包括 A 和 B)的捕获都可能有阻碍路径的障碍物,因此必须绕道。路径可能不会沿对角线移动。

对于希望解决此类问题的其他人,我发现这些参考资料非常有用:

http://optlab-server.sce.carleton.ca/POAnimations2007/DijkstrasAlgo.html

http://en.literateprograms.org/Dijkstra%27s_algorithm_%28Java%29#chunk%20def:visit%20each%20vertex%20u,%20always%20visiting%20vertex%20with%20smallest%20minDistance%20first

【问题讨论】:

  • 好问题!你在哪里卡住了?
  • Dijkstra 将是去en.wikipedia.org/wiki/Dijkstra's_algorithm的正常方式@
  • 这个问题是关于实际最短路径(即其坐标)还是源与目的地之间的最短距离?

标签: java algorithm pathing


【解决方案1】:

这是一个可以使用广度优先搜索解决的简单问题

 /**
  * computing distance of each cell from the starting cell 
  * avoiding obstacles, 0 represents obstacle 1 represents non obstacle
  * we can take only one step x-1;x+1;y-1;y+1
 */

#include<iostream>
#include<queue>
#include<stdio.h>
using namespace std;

class XY
{
 public :
 int x;
int y;
};

int main()
{
int grid[8][8] = {
    {1,1,1,1,1,1,1,1},
    {1,0,0,0,1,1,1,1},
    {1,1,0,0,1,1,1,1},
    {1,1,0,0,1,1,1,1},
    {1,1,1,2,0,1,0,0},
    {1,1,1,1,1,1,1,1},
    {1,1,1,1,1,1,1,1},
    {1,1,1,1,1,1,1,1}
};


int rows = 8;
int cols = 8;

int distance[rows][cols];

for(int m = 0;m<rows;m++)
{
    for(int n =0;n<cols;n++)
    {
        distance[m][n] = -1;
    }
}

queue<XY> iterator;


XY xy;
xy.x = 0;
xy.y = 0;
distance[0][0] = 0;
iterator.push(xy);

while(!iterator.empty())
{
    xy = iterator.front();
    iterator.pop();
    //printf("popped %d+%d\n",xy.x ,xy.y);
    for(int p = -1;p<2;p++)
    {
        for(int q = -1;q<2;q++)
        {
            if(p == q)continue;
            int i = xy.x + p;
            int j = xy.y + q;

            if(i<0)i=0;
            if(j<0)j=0;
            if(i>rows-1)i=rows-1;
            if(j>cols-1)j=cols-1;

            if(i== xy.x && j == xy.y)continue;

    //              printf("i,j = %d,%d\n",i,j);

            if(distance[i][j] == -1)
            {
     //                 printf("******\n");
                if(grid[i][j] != 0)
                {
     //                 printf("assigned distance %d to %d+%d\n",distance[xy.x][xy.y] + 1,i,i); 
                distance[i][j] = distance[xy.x][xy.y] + 1;
                XY xyn;
                xyn.x = i;
                xyn.y = j;  
                iterator.push(xyn);
      //                    printf("pushed %d+%d\n",xyn.x,xyn.y);
                }
            }

        }
    }
}

for(int x = 0;x<rows;x++)
{
    for(int y =0;y<cols;y++)
    {
        printf("%d ",distance[x][y]);   
    }
    printf("\n");
}
return 0;
}

【讨论】:

  • 此算法找到最短距离,但不是从源到目的地的实际路径。如果我错了,请纠正我。
【解决方案2】:

这是使用A* search algorithm 的绝佳地点,这是一种启发式搜索算法,即使存在障碍物也能非常快速地找到点之间的最佳路径。这个想法是将网格转换为graph,其中网格中的每个单元格都是一个节点,并且其中任何两个相邻单元格之间都有一条不相互阻碍的边。获得此图后,您正在寻找的答案是图中从起始节点到目标节点的最短路径。

为了使用 A*,您需要一个启发式函数来“猜测”从网格上任意点到目标方格的距离。一个很好的启发式方法是在两点之间使用the Manhattan distance

如果您正在寻找一种更简单但仍然非常有效的算法来查找最短路径,请考虑查看Dijkstra's algorithm,它可以被认为是 A* 的更简单版本。它比 A* 慢一点,但仍然运行得非常快,并且保证了最佳答案。

希望这会有所帮助!

【讨论】:

  • @Valchris- 祝你好运! Dijkstra 和 A* 是可以用来解决各种问题的经典算法,绝对值得了解如何编写它们。
  • A* 在我心中始终占有特殊的位置,因为搜索在最坏的情况下会演变为广度优先搜索,这是一种很好的故障保护。
  • 如果我需要绕过障碍物的最短路径,是否有替代方案? A* 需要将地图分割成一个网格,我的车辆将绕障碍物以之字形方式移动,而不是直线
  • @wutzebaer A* 的通用版本不需要您使用网格,尽管在教程中经常以这种方式呈现。您熟悉有向图和无向图吗?
  • 嗯,我想是的 - 好的,我可以在所有障碍物边缘和目标点上创建航点,然后我可以连接所有连接不接触任何障碍物的点......像这样?
猜你喜欢
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多