Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 加快Dijkstra';求解三维迷宫的s算法_Python_Algorithm_3d_Dijkstra_Maze - Fatal编程技术网

Python 加快Dijkstra';求解三维迷宫的s算法

Python 加快Dijkstra';求解三维迷宫的s算法,python,algorithm,3d,dijkstra,maze,Python,Algorithm,3d,Dijkstra,Maze,我正在尝试编写一个Python脚本来解决3D迷宫问题,我正在使用Dijkstra的算法和优先级队列(包含在模块heapq中)来完成。以下是我的主要功能代码: from heapq import * def dijkstra(start,end,vertices,obstacles): covered=[] s=vertices.index(s) currentVertex=s liveDistances={} for i in range(len(vert

我正在尝试编写一个Python脚本来解决3D迷宫问题,我正在使用Dijkstra的算法和优先级队列(包含在模块heapq中)来完成。以下是我的主要功能代码:

from heapq import *
def dijkstra(start,end,vertices,obstacles):
    covered=[]
    s=vertices.index(s)
    currentVertex=s
    liveDistances={}
    for i in range(len(vertices)):
        liveDistances[i]=inf
    liveDistances[s]=0
    next=[[liveDistances[s],s]]
    while next:
        np,currentVertex=heappop(next)
        covered.append(currentVertex)
        for u in sons(vertices[currentVertex]):
            v=vertices.index(u)
            if v in covered:continue
            if 1+liveDistances[currentVertex]<liveDistances[v]:
                liveDistances[v]=1+liveDistances[currentVertex]
                heappush(next,[liveDistances[v],v])
    if liveDistances[vertices.index(e)]!=inf:
        return liveDistances[vertices.index(e)]
    else:
        return "No path!"
来自heapq导入的
*
def dijkstra(起点、终点、顶点、障碍物):
覆盖=[]
s=顶点。索引(s)
currentVertex=s
liveDistances={}
对于范围内的i(len(顶点)):
livedistance[i]=inf
livedistance[s]=0
下一步=[[liveDistances[s],s]]
下一步:
np,currentVertex=heappop(下一个)
covered.append(currentVertex)
对于子对象中的u(顶点[currentVertex]):
v=顶点。索引(u)
如果覆盖v:继续

如果1+liveDistances[currentVertex]您知道*搜索(“A星”)吗?这是对Dijkstra算法的修改,当你了解情况的几何学时,它会有很大的帮助。未经修改的Dijkstra假设任何边缘都可能是通往目标的一条非常短的道路的起点,但通常情况下,情况的几何结构不允许这样做,或者至少使其不太可能

基本的想法是,如果你想找到一条从丹佛到匹兹堡的最短路径,那么通往盐湖城的边缘不太可能有帮助。因此,通过向堆中的权重添加从该节点到目标的距离的下限来偏移权重——在这个2D示例中,这将是直线或大圆距离,因为没有实际道路可以比这短。这种启发式倾向于将错误的选择进一步推到堆中,因此它们通常永远不会被发现


不过,我无法证明你构建3D迷宫的方式是否适用于*搜索。

我怀疑在这两行中会花费大量时间:

v=vertices.index(u)
if v in covered:continue
这两条线都是O(n)操作,其中n是图形中的顶点数

我建议将第一个替换为字典(从顶点名称映射到顶点索引),第二个替换为将
covered
从列表更改为集合


这将使两种操作都达到O(1)级,并可使速度提高几个数量级。

我最初的方法是使用一些基本的回溯:

boolean[][]已访问=新的boolean[h][w][d];
布尔foundPath=false;
公共无效路径(整数y、整数x、整数z){
访问[y][x][z]=真;
如果(x==targetx&&y==target&&z==targetz){
foundPath=true;
返回;
}
if(!visted[y-1][x][z]&&&!foundPath)//if up
路径(y-1,x,z);
如果(!已访问[y+1][x][z]&&&!foundPath)//如果已关闭
路径(y+1,x,z);
如果(!visted[y][x-1][z]&&&!foundPath)//如果离开
路径(y,x-1,z);
如果(!已访问[y][x+1][z]&&&!foundPath)//如果正确
路径(y,x+1,z);
if(!visted[y][x][z+1]&&&!foundPath)//if forward
路径(y,x,z+1);
if(!visted[y][x][z-1]&&&!foundPath)//if backward
路径(y,x+1,z-1);
if(foundPath)返回;
访问[y][x][z]=错误;
}

不,这不正常。我无法通过查看代码发现问题,但如果您提供完整的代码和地图,我可能会帮助您。选择dijkstra而不是BFS还有什么特别的原因吗?我只是更熟悉dijkstra的,因为dijkstra和BFS非常相似,我不认为BFS会有很大的提高。我算法的其余部分只是返回任意给定点的相邻网格点的函数sons,因此我认为这没有什么区别。如果有人想运行代码并自行测试,他们将需要剩余的资源。我尝试了使用欧几里德距离作为启发式的*搜索,虽然在30x30x30没有墙壁的迷宫上,它并没有做出很大的改变。解决这个问题仍然需要一分钟以上的时间。当有更多的墙时,这会有不同。它找不到最短路径,是吗?假设有多个解决方案,不,通常是DFS