139 lines
4.4 KiB
Python
139 lines
4.4 KiB
Python
"""
|
||
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 |