路径寻路可视化工具中网格节点邻居邻接表生成错误及优化方案咨询
问题分析与解决方案
原代码的核心问题
你的代码出现两个关键错误,直接导致邻居索引完全不符合预期:
- 节点键的唯一性丢失:用
row.index(col)作为字典的键,这本质是节点的列索引,同一列的所有节点都会共享同一个键,循环到最后一行时会覆盖前面所有行的同列节点数据——这就是为什么你看到的都是最后一行(索引19)相关的邻居。 - 索引获取方式不可靠:
grid.index(row)和row.index(col)这两个方法会返回第一个匹配元素的索引,如果网格中有重复行/重复列值,会直接返回错误的索引;而且这种方式效率很低,每次都要遍历列表找元素。
修复后的基础实现
改用enumerate直接获取行和列的索引,同时用(行索引, 列索引)作为字典的唯一键,确保每个节点都有独立的条目:
def get_neighbors(grid): neighbors = {} rows = len(grid) if rows == 0: return neighbors cols = len(grid[0]) # 遍历每个节点的行索引i和列索引j for i, row in enumerate(grid): for j, _ in enumerate(row): # 生成上下左右四个方向的邻居索引 up = (i - 1, j) down = (i + 1, j) left = (i, j - 1) right = (i, j + 1) neighbors[(i, j)] = [down, up, left, right] return neighbors
优化方案:添加边界检查(过滤无效邻居)
上面的代码会生成(-1, 0)或(20, 0)这类超出网格范围的无效邻居,我们可以在生成时直接过滤掉这些值,只保留有效范围内的邻居:
def get_neighbors(grid): neighbors = {} rows = len(grid) if rows == 0: return neighbors cols = len(grid[0]) # 定义上下左右四个方向的偏移量 directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] for i in range(rows): for j in range(cols): valid_neighbors = [] for di, dj in directions: ni, nj = i + di, j + dj # 检查邻居是否在网格边界内 if 0 <= ni < rows and 0 <= nj < cols: valid_neighbors.append((ni, nj)) neighbors[(i, j)] = valid_neighbors return neighbors
额外适配:支持障碍物过滤(针对寻路算法)
如果你的路径寻路需要区分可通行和障碍物节点,可以在生成邻接表时直接过滤掉障碍物:
def get_neighbors(grid, obstacle_value=1): neighbors = {} rows = len(grid) if rows == 0: return neighbors cols = len(grid[0]) directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] for i in range(rows): for j in range(cols): # 跳过当前是障碍物的节点(可选,根据你的需求调整) if grid[i][j] == obstacle_value: continue valid_neighbors = [] for di, dj in directions: ni, nj = i + di, j + dj if 0 <= ni < rows and 0 <= nj < cols: # 只添加非障碍物的邻居 if grid[ni][nj] != obstacle_value: valid_neighbors.append((ni, nj)) neighbors[(i, j)] = valid_neighbors return neighbors
这样生成的邻接表完全符合你的需求,每个节点的键是唯一的(行,列)元组,邻居都是正确的有效索引。
内容的提问来源于stack exchange,提问作者Irkl1_
相关产品推荐
相关产品推荐

