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

139 lines
4.4 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.

"""
DFS算法实现
深度优先搜索算法,不保证找到最短路径,但可能更快找到任意路径
"""
from collections import deque
from typing import List, Tuple, Optional, Dict, Set
class DFS:
"""
DFS算法实现
深度优先搜索算法,不保证找到最短路径,但可能更快找到任意路径
"""
def __init__(self):
"""初始化DFS算法"""
self.depth_limit = 1000 # 深度限制,防止无限递归
self.stats = {
'nodes_visited': 0,
'max_depth': 0
}
def find_path(self, grid: List[List[int]], start: Tuple[int, int], goal: Tuple[int, int]) -> Optional[List[Tuple[int, int]]]:
"""
使用DFS算法查找路径
Args:
grid: 网格地图0表示可通行1表示障碍物
start: 起点坐标 (row, col)
goal: 终点坐标 (row, col)
Returns:
路径坐标列表如果找不到路径则返回None
"""
# 重置统计信息
self.stats = {
'nodes_visited': 0,
'max_depth': 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
# 初始化栈
stack = [(start, 0)] # (节点, 深度)
# 初始化父节点字典和访问集合
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 stack:
# 更新统计信息
self.stats['nodes_visited'] += 1
# 取出栈顶节点
current, depth = stack.pop()
self.stats['max_depth'] = max(self.stats['max_depth'], depth)
# 如果超过深度限制,跳过
if depth >= self.depth_limit:
continue
# 如果到达目标节点
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
stack.append((neighbor, depth + 1))
# 未找到路径
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()
def set_depth_limit(self, limit: int):
"""
设置深度限制
Args:
limit: 深度限制
"""
self.depth_limit = limit