[英]Algorithm to find the shortest path, with obstacles
我有一个代表网格的点集合,我正在寻找一个能让我获得A点和B点之间最短距离的算法。任何点(不包括A和B)的捕获都会有阻碍路径的障碍,并且因此必须绕道而行。 路径可能不会以对角线移动。
对于任何想要解决此类问题的人,我发现这些引用非常有用:
http://optlab-server.sce.carleton.ca/POAnimations2007/DijkstrasAlgo.html
这是使用A *搜索算法的绝佳场所, A *搜索算法是一种启发式搜索算法,即使存在障碍物,也能非常快速地找到点之间的最佳路径。 该想法是将网格转换为图形 ,其中网格中的每个单元是节点,并且在任何两个相邻单元之间存在不相互阻碍的边缘。 获得此图表后,您要查找的答案是图表中从起始节点到目标节点的最短路径。
为了使用A *,您需要一个启发式功能,“猜测”从网格上的任何点到目标方块的距离。 一个很好的启发式方法是使用两点之间的曼哈顿距离 。
如果您正在寻找一种更简单但仍然非常有效的查找最短路径的算法 ,请考虑查看Dijkstra的算法 ,该算法可以被认为是A *的更简单版本。 它比A *慢一点,但仍能非常快速地运行并保证最佳答案。
希望这可以帮助!
这是一个可以使用广度优先搜索解决的简单问题
/**
* 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;
}
我相信如前所述,广度优先搜索(BFS)可以解决给定的问题。 建立问题陈述很重要。 因此,让我们描述问题,然后我们转向解决方案的一部分。
您负责为新建筑物之一准备最近购买的地块。 该地块覆盖着沟渠,并且在为建筑物准备地基之前需要拆除一个障碍物。 拆除机器人必须移除障碍物才能在建筑物上进行。 编写算法以确定拆除机器人移除障碍物所需的最小距离。
返回一个整数,表示移动的最小距离以移除障碍物,否则返回-1。
from collections import defaultdict
from collections import deque
def is_valid(i, j, m, n, matrix, visited):
if i >= 0 and j >= 0 \
and i < m and j < n \
and visited[i][j] is False \
and matrix[i][j] in (1, 9):
return True
return False
def remove_obstacle(matrix, m, n):
queue = deque()
i = 0
j = 0
queue.append((i, j, 0))
visited = [[False for _ in range(n)] for _ in range(m)]
distance_matrix = [[100 for _ in range(n)] for _ in range(m)]
visited[i][j] = True
while queue:
i, j, distance = queue.popleft()
distance_matrix[i][j] = distance
visited[i][j] = True
if matrix[i][j] == 9:
return distance
new_distance = distance + 1
if is_valid(i + 1, j, m, n, matrix, visited):
queue.append((i + 1, j, new_distance))
if is_valid(i - 1, j, m, n, matrix, visited):
queue.append((i - 1, j, new_distance))
if is_valid(i, j + 1, m, n, matrix, visited):
queue.append((i, j + 1, new_distance))
if is_valid(i, j - 1, m, n, matrix, visited):
queue.append((i, j - 1, new_distance))
return -1
if __name__ == '__main__':
m = 5
n = 4
l = [
[1, 1, 1, 1],
[0, 1, 1, 1],
[0, 1, 0, 1],
[1, 1, 9, 1],
[0, 0, 1, 1]
]
bfs = remove_obstacle(l, m, n)
assert bfs == 5
m = 3
n = 3
l = [
[1, 0, 0],
[1, 0, 0],
[1, 9, 1]
]
bfs = remove_obstacle(l, m, n)
assert bfs == 3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.