You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于AIMA代码框架在栅格地图上实现Floyd Warshall最短路径算法

栅格场景Floyd Warshall算法实现指南

核心适配逻辑

栅格地图本质是稠密无权/带权图,每个可通行栅格对应图的节点,相邻可通行栅格之间的移动对应图的边,边权为移动代价。你可以复用现有AIMA框架的GridProblem能力,仅需补充节点枚举、邻接矩阵构建的逻辑即可。

第一步:GridProblem类扩展

首先给GridProblem新增获取所有可通行节点的方法,用于构建邻接矩阵:

# 给GridProblem类新增如下方法
def get_all_passable_states(self):
    # 先确定栅格的坐标边界
    all_points = list(self.obstacles) + [self.initial, self.goal]
    xs = [p[0] for p in all_points]
    ys = [p[1] for p in all_points]
    min_x, max_x = int(min(xs)/self.grid_size) - 1, int(max(xs)/self.grid_size) + 1
    min_y, max_y = int(min(ys)/self.grid_size) - 1, int(max(ys)/self.grid_size) + 1
    passable_states = []
    # 遍历所有栅格,筛选可通行的节点
    for gx in range(min_x, max_x + 1):
        for gy in range(min_y, max_y + 1):
            if (gx, gy) not in self.gridmap:
                # 栅格坐标转实际坐标
                state = (round(gx * self.grid_size, 3), round(gy * self.grid_size, 3))
                passable_states.append(state)
    return passable_states

第二步:Floyd Warshall算法实现

参照BFS的封装思路,实现输入为Problem实例、输出为Node实例的算法函数,保证和现有框架兼容:

def floyd_warshall_search(problem):
    # 1. 预处理可通行节点和映射关系
    passable_states = problem.get_all_passable_states()
    state_to_idx = {s: i for i, s in enumerate(passable_states)}
    idx_to_state = {i: s for i, s in enumerate(passable_states)}
    N = len(passable_states)
    INF = float('inf')
    
    # 2. 初始化距离矩阵和前驱矩阵
    dist = [[INF] * N for _ in range(N)]
    prev = [[None] * N for _ in range(N)]
    for i in range(N):
        dist[i][i] = 0
        s = idx_to_state[i]
        # 复用GridProblem的actions方法获取相邻可到达节点
        for s1 in problem.actions(s):
            if s1 not in state_to_idx:
                continue
            j = state_to_idx[s1]
            dist[i][j] = problem.action_cost(s, None, s1)
            prev[i][j] = i
    
    # 3. 执行Floyd Warshall核心迭代
    for k in range(N):
        for i in range(N):
            for j in range(N):
                if dist[i][k] + dist[k][j] < dist[i][j]:
                    dist[i][j] = dist[i][k] + dist[k][j]
                    prev[i][j] = prev[k][j]
    
    # 4. 查找起点终点对应的索引
    initial_idx = state_to_idx.get(problem.initial)
    goal_idx = state_to_idx.get(problem.goal)
    if initial_idx is None or goal_idx is None or dist[initial_idx][goal_idx] == INF:
        return Node.failure
    
    # 5. 回溯前驱矩阵构造路径,生成符合AIMA规范的Node节点
    path = []
    current_idx = goal_idx
    while current_idx is not None:
        path.append(idx_to_state[current_idx])
        current_idx = prev[initial_idx][current_idx]
    path = path[::-1] # 反转得到从起点到终点的序列
    
    # 构造Node链,兼容现有path_states等工具方法
    root = Node(path[0])
    current_node = root
    for i in range(1, len(path)):
        s = path[i-1]
        s1 = path[i]
        cost = current_node.path_cost + problem.action_cost(s, None, s1)
        current_node = Node(s1, parent=current_node, path_cost=cost)
    return current_node

注意事项

  • Floyd Warshall算法时间复杂度为O(N³),仅适合节点数少于200的小尺寸栅格地图使用,大尺寸地图更推荐使用Dijkstra或A*算法,性能会高几个数量级。
  • 你当前GridProblem中的to_grid方法可以简化为lambda state: (int(state[0]/self.grid_size), int(state[1]/self.grid_size)),原有写法的乘10再除10操作是冗余的,还可能引入浮点计算误差。
  • 如果你只需要求解单起点到单终点的最短路径,Floyd Warshall并不是最优选择,它的优势是一次计算可以得到所有节点对的最短路径,适合需要多次查询路径的场景。

内容的提问来源于stack exchange,提问作者Pascal Zurich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 04:09:03