EG/plugins/user/pathfinding_algorithms/algorithms/bfs.py
2025-12-12 16:16:15 +08:00

125 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
BFS算法实现
广度优先搜索算法,保证找到最短路径(在无权图中)
"""
from collections import deque
from typing import List, Tuple, Optional, Dict, Set
class BFS:
"""
BFS算法实现
广度优先搜索算法,保证找到最短路径(在无权图中)
"""
def __init__(self):
"""初始化BFS算法"""
self.stats = {
'nodes_visited': 0,
'max_queue_size': 0
}
def find_path(self, grid: List[List[int]], start: Tuple[int, int], goal: Tuple[int, int]) -> Optional[List[Tuple[int, int]]]:
"""
使用BFS算法查找路径
Args:
grid: 网格地图0表示可通行1表示障碍物
start: 起点坐标 (row, col)
goal: 终点坐标 (row, col)
Returns:
路径坐标列表如果找不到路径则返回None
"""
# 重置统计信息
self.stats = {
'nodes_visited': 0,
'max_queue_size': 0
}
# 获取网格尺寸
rows = len(grid)
cols = len(grid[0]) if rows > 0 else 0
# 检查起点和终点是否有效
if not (0 <= start[0] < rows and 0 <= start[1] < cols):
return None
if not (0 <= goal[0] < rows and 0 <= goal[1] < cols):
return None
if grid[start[0]][start[1]] == 1 or grid[goal[0]][goal[1]] == 1:
return None
# 初始化队列
queue = deque([start])
# 初始化父节点字典和访问集合
parent: Dict[Tuple[int, int], Tuple[int, int]] = {}
visited: Set[Tuple[int, int]] = {start}
# 4方向移动上下左右
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
while queue:
# 更新统计信息
self.stats['nodes_visited'] += 1
self.stats['max_queue_size'] = max(self.stats['max_queue_size'], len(queue))
# 取出队列中的第一个节点
current = queue.popleft()
# 如果到达目标节点
if current == goal:
# 重构路径
path = self._reconstruct_path(parent, current)
return path
# 检查所有邻居节点
for dr, dc in directions:
neighbor = (current[0] + dr, current[1] + dc)
# 检查邻居节点是否在网格范围内
if not (0 <= neighbor[0] < rows and 0 <= neighbor[1] < cols):
continue
# 检查邻居节点是否为障碍物
if grid[neighbor[0]][neighbor[1]] == 1:
continue
# 检查邻居节点是否已访问
if neighbor in visited:
continue
# 标记为已访问并加入队列
visited.add(neighbor)
parent[neighbor] = current
queue.append(neighbor)
# 未找到路径
return None
def _reconstruct_path(self, parent: Dict[Tuple[int, int], Tuple[int, int]], current: Tuple[int, int]) -> List[Tuple[int, int]]:
"""
重构路径
Args:
parent: 父节点字典
current: 当前节点
Returns:
路径坐标列表
"""
path = [current]
while current in parent:
current = parent[current]
path.append(current)
path.reverse()
return path
def get_stats(self) -> Dict[str, int]:
"""
获取算法统计信息
Returns:
统计信息字典
"""
return self.stats.copy()