### 在Python中使用A星(A*)搜索算法解决迷宫矩阵问题 [重复]

我有一个用于迷宫问题的迷宫矩阵。

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*搜索算法后,使用曼哈顿距离作为距离估算,使用当前路径的长度作为路径成本,返回从点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*的理念是在边缘中探索具有最小成本值的状态(定义为启发式成本和进展成本之和,进展成本由之前必须经过的所有状态计算得出)。您可以在A*搜索算法的维基百科页面上找到这种算法的通用实现。在您的情况下,一个状态可能包括:

  1. 网格中的i, j位置
  2. 前一个状态(假设第一个状态为None
  3. 这个状态的总成本(启发式成本 + 路径成本)。

要探索一个集合,您只需要检查单元格的直接邻居(只包括值为1的那些)。值得注意的是,在已访问集合中,您应该只包括位置(i,j)和成本(因为即使在您的问题中不太可能,您也可能会重新进入这个状态,如果您找到了更短的路径)。

这里有一个适用于您情况的示例(但可以轻松地进行泛化):

def astar(lab):    # 首先,让我们查找起始位置,有更好的方法但这可以工作    (i_s, j_s) = [[(i, j) for j, cell in enumerate(row) if cell == 2] for i, row in enumerate(lab) if 2 in row][0][0]    # 并获取目标位置(用于启发式)    (i_e, j_e) = [[(i, j) for j, cell in enumerate(row) if cell == 3] for i, row in enumerate(lab) if 3 in row][0][0]    width = len(lab[0])    height = len(lab)    heuristic = lambda i, j: abs(i_e - i) + abs(j_e - j)    comp = lambda state: state[2] + state[3] # 获取总成本    # 为了代码更易读,状态是(坐标元组,前一个,路径成本,启发式成本)    fringe = [((i_s, j_s), list(), 0, heuristic(i_s, j_s))]    visited = {} # 空集合    # 可能限制以防止搜索时间过长    while True:        # 获取第一个状态(成本最低)        state = fringe.pop(0)        # 目标检查        (i, j) = state[0]        if lab[i][j] == 3:            path = [state[0]] + state[1]            path.reverse()            return path        # 设置成本(路径足够,因为启发式不会改变)        visited[(i, j)] = state[2]         # 探索邻居        neighbor = list()        if i > 0 and lab[i-1][j] > 0: #上方            neighbor.append((i-1, j))        if i < height and lab[i+1][j] > 0:            neighbor.append((i+1, j))        if j > 0 and lab[i][j-1] > 0:            neighbor.append((i, j-1))        if j < width and lab[i][j+1] > 0:            neighbor.append((i, j+1))        for n in neighbor:            next_cost = state[2] + 1            if n in visited and visited[n] >= next_cost:                continue            fringe.append((n, [state[0]] + state[1], next_cost, heuristic(n[0], n[1])))        # 重新排序列表(这里应该使用优先级队列以避免每次都重新排序)        fringe.sort(key=comp)

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注