Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.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中迷宫矩阵的A星(A*)搜索算法_Python_Search_Artificial Intelligence_A Star_Maze - Fatal编程技术网

python中迷宫矩阵的A星(A*)搜索算法

python中迷宫矩阵的A星(A*)搜索算法,python,search,artificial-intelligence,a-star,maze,Python,Search,Artificial Intelligence,A Star,Maze,我有一个迷宫问题的迷宫矩阵 Labyrinth = [[0, 0, 0, 0, 0, 0, 1, 0], [0, 1, 0, 1, 1, 1, 1, 0], [0, 1, 1, 1, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 1, 1, 3, 0], [0, 0, 1, 1, 1, 0, 0, 0], [0, 1, 2, 0, 1, 1, 1, 0], [0, 1, 0, 0, 0, 0, 0, 0]] 这里, 0表示作为墙的被阻

我有一个迷宫问题的迷宫矩阵

Labyrinth =
[[0, 0, 0, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 0, 1, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 1, 1, 3, 0],
[0, 0, 1, 1, 1, 0, 0, 0],
[0, 1, 2, 0, 1, 1, 1, 0],
[0, 1, 0, 0, 0, 0, 0, 0]]
这里,

  • 0表示作为墙的被阻止单元
  • 1表示空单元格

  • 2和3分别代表起点和终点

我需要一个函数,它可以在执行a*Search算法后返回从点2到3的路径,该算法使用曼哈顿距离作为距离估计,当前路径的长度作为路径成本

有什么建议吗?或者提示/线索我应该如何操作这个

更新:我想通过使用其他字符(如X)标记路径,从开始到结束返回路径。作为参考,如下所示:

Labyrinth =
[[0, 0, 0, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 0, 1, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, X, X, 3, 0],
[0, 0, X, X, X, 0, 0, 0],
[0, 1, 2, 0, 1, 1, 1, 0],
[0, 1, 0, 0, 0, 0, 0, 0]]

经典搜索算法使用一组称为边缘的状态和一组访问状态:

  • 边缘队是所有希望找到目标状态的球队
  • 已访问集是已访问以避免再次访问的所有状态
A*的想法是探索边缘中成本值最小的状态(定义为启发式成本和进度成本之和(由您之前必须经过的所有状态计算))。您可以在上找到此算法的通用实现。在你的情况下,一个州可能包括:

  • 网格中的
    i,j
    位置
  • 前一个状态(假设第一个状态为
    None
  • 此状态的总成本(启发式+路径成本)
  • 要探索一个集合,您只需要检查单元格的直接邻居(仅包括值为1的邻居)。值得注意的是,在访问的集合中,您应该只包括位置(i,j)和成本(因为如果您发现较短的路径,您可能会重新进入该状态,即使这不太可能在您的问题中)

    以下是一个适用于您的案例的示例(但可能很容易推广):

    def astar(实验室):
    #首先,让我们看看开始的位置,有更好的,但它是有效的
    (i_s,j_s)=[[(i,j)对于j,枚举(行)中的单元格如果单元格==2]对于i,枚举(实验室)中的行如果行中有2][0]
    #并选择目标位置(用于启发式)
    (i_e,j_e)=[[(i,j)对于j,枚举(行)中的单元格如果单元格==3]对于i,枚举(实验室)中的行如果行中有3][0]
    宽度=长度(实验室[0])
    高度=透镜(实验室)
    启发式=λi,j:abs(i_e-i)+abs(j_e-j)
    comp=lambda状态:状态[2]+状态[3]#获取总成本
    #较小的变化便于编写代码,状态为(协调元组、上一个、路径成本、启发式成本)
    边缘=[((i_s,j_s),list(),0,启发式(i_s,j_s))]
    已访问={}#空集
    #可能限制以防止搜索时间过长
    尽管如此:
    #获取第一状态(最低成本)
    状态=边缘.pop(0)
    #进球检查
    (i,j)=状态[0]
    如果lab[i][j]==3:
    路径=[状态[0]]+状态[1]
    path.reverse()
    返回路径
    #设置成本(路径足够了,因为启发式不会改变)
    到访[(i,j)]=州[2]
    #探索邻居
    邻居=列表()
    如果i>0且lab[i-1][j]>0:#顶部
    邻居追加((i-1,j))
    如果i<高度和实验室[i+1][j]>0:
    append((i+1,j))
    如果j>0且lab[i][j-1]>0:
    邻域追加((i,j-1))
    如果j0:
    append((i,j+1))
    对于邻居中的n:
    下一个成本=状态[2]+1
    如果n在已访问和已访问[n]>=下一个成本:
    持续
    附加((n[state[0]]+state[1],下一个成本,启发式(n[0],n[1]))
    #使用列表(此处应使用优先级队列,以避免一直重新排序)
    条纹排序(键=组件)
    
    这段代码可以用来解决您的问题:您看过a*的实现吗?网络上有大量可用的资料。是的,我查过各种来源,但有一件事我想要的是返回从开始到结束的路径。如果有人能在这方面帮助我的话。由于StackOverflow不是一个代码编写服务,你应该编辑你当前的代码,尝试解决你的路径打印问题,作为你的问题的一部分,并指出它的作用,这不是你所期望的-这两个方面都是具体的。我确实知道*算法背后的基本思想。感谢你的努力。但是我想返回从开始到结束的确切路径。然后它将取决于您的确切实现,正如我在状态定义中所说的,您可以在其中添加上一个状态,并基于此在一个辅助窗口中重建整个路径。您也可以只添加一个coord列表,只需在返回之前将其反转即可。(我编辑了我的答案以包含您问题的解决方案)