当前位置: 首页 > news >正文

用Python玩转罗马尼亚地图寻路:手把手实现A*、贪婪、BFS、DFS四种算法(附完整代码)

用Python玩转罗马尼亚地图寻路:手把手实现A*、贪婪、BFS、DFS四种算法(附完整代码)

罗马尼亚地图寻路问题是人工智能和算法学习中的经典案例。通过这个项目,我们可以直观地比较不同搜索算法的表现,理解它们的优缺点。本文将带你从零开始,用Python实现四种常见搜索算法:A*、贪婪最佳优先搜索(GBFS)、广度优先搜索(BFS)和深度优先搜索(DFS)。

1. 准备工作:构建罗马尼亚地图

在开始算法实现前,我们需要先构建罗马尼亚城市间的连接关系。这里使用Python字典来表示图结构:

romania_map = { 'Arad': {'Zerind': 75, 'Sibiu': 140, 'Timisoara': 118}, 'Zerind': {'Arad': 75, 'Oradea': 71}, 'Sibiu': {'Arad': 140, 'Oradea': 151, 'Fagaras': 99, 'Rimnicu Vilcea': 80}, 'Timisoara': {'Arad': 118, 'Lugoj': 111}, 'Oradea': {'Zerind': 71, 'Sibiu': 151}, 'Fagaras': {'Sibiu': 99, 'Bucharest': 211}, 'Rimnicu Vilcea': {'Sibiu': 80, 'Pitesti': 97, 'Craiova': 146}, 'Lugoj': {'Timisoara': 111, 'Mehadia': 70}, 'Mehadia': {'Lugoj': 70, 'Drobeta': 75}, 'Drobeta': {'Mehadia': 75, 'Craiova': 120}, 'Craiova': {'Drobeta': 120, 'Rimnicu Vilcea': 146, 'Pitesti': 138}, 'Pitesti': {'Rimnicu Vilcea': 97, 'Craiova': 138, 'Bucharest': 101}, 'Bucharest': {'Fagaras': 211, 'Pitesti': 101, 'Giurgiu': 90, 'Urziceni': 85}, 'Giurgiu': {'Bucharest': 90}, 'Urziceni': {'Bucharest': 85, 'Hirsova': 98, 'Vaslui': 142}, 'Hirsova': {'Urziceni': 98, 'Eforie': 86}, 'Eforie': {'Hirsova': 86}, 'Vaslui': {'Urziceni': 142, 'Iasi': 92}, 'Iasi': {'Vaslui': 92, 'Neamt': 87}, 'Neamt': {'Iasi': 87} }

同时,我们需要定义各城市到目标城市Bucharest的直线距离(启发式函数值):

heuristic = { 'Arad': 366, 'Zerind': 374, 'Sibiu': 253, 'Timisoara': 329, 'Oradea': 380, 'Fagaras': 176, 'Rimnicu Vilcea': 193, 'Lugoj': 244, 'Mehadia': 241, 'Drobeta': 242, 'Craiova': 160, 'Pitesti': 100, 'Bucharest': 0, 'Giurgiu': 77, 'Urziceni': 80, 'Hirsova': 151, 'Eforie': 161, 'Vaslui': 199, 'Iasi': 226, 'Neamt': 234 }

2. 广度优先搜索(BFS)实现

BFS是一种盲目搜索算法,它会先探索所有相邻节点,再逐层向外扩展。下面是BFS的实现代码:

from collections import deque def bfs(graph, start, goal): visited = set() queue = deque([(start, [start])]) while queue: current, path = queue.popleft() if current == goal: return path if current not in visited: visited.add(current) for neighbor in graph[current]: if neighbor not in visited: queue.append((neighbor, path + [neighbor])) return None

使用示例:

path = bfs(romania_map, 'Arad', 'Bucharest') print("BFS路径:", ' -> '.join(path))

BFS的特点:

  • 总是能找到最短路径(按边数计算)
  • 需要较多内存,因为要存储所有已访问节点
  • 适用于寻找最短路径或探索所有可能状态

3. 深度优先搜索(DFS)实现

DFS会沿着一条路径尽可能深入,直到无法继续才回溯。下面是DFS的实现:

def dfs(graph, start, goal, path=None, visited=None): if path is None: path = [] if visited is None: visited = set() path = path + [start] visited.add(start) if start == goal: return path for neighbor in graph[start]: if neighbor not in visited: result = dfs(graph, neighbor, goal, path, visited) if result is not None: return result return None

使用示例:

path = dfs(romania_map, 'Arad', 'Bucharest') print("DFS路径:", ' -> '.join(path))

DFS的特点:

  • 内存需求相对较小(只需存储当前路径)
  • 不一定能找到最短路径
  • 适用于存在多条解且路径长度不重要的情况

4. 贪婪最佳优先搜索(GBFS)实现

GBFS是一种启发式搜索算法,总是选择看起来最有希望的节点进行扩展:

import heapq def gbfs(graph, heuristic, start, goal): visited = set() heap = [(heuristic[start], start, [start])] while heap: _, current, path = heapq.heappop(heap) if current == goal: return path if current not in visited: visited.add(current) for neighbor in graph[current]: if neighbor not in visited: heapq.heappush(heap, (heuristic[neighbor], neighbor, path + [neighbor])) return None

使用示例:

path = gbfs(romania_map, heuristic, 'Arad', 'Bucharest') print("GBFS路径:", ' -> '.join(path))

GBFS的特点:

  • 速度快,但不保证找到最优解
  • 完全依赖启发式函数的质量
  • 适用于启发式函数能提供良好估计的情况

5. A*搜索算法实现

A*结合了GBFS和Dijkstra算法的优点,既考虑已走路径的成本,也考虑剩余路径的估计:

def astar(graph, heuristic, start, goal): open_set = [] heapq.heappush(open_set, (0 + heuristic[start], 0, start, [start])) visited = set() while open_set: _, g, current, path = heapq.heappop(open_set) if current == goal: return path if current not in visited: visited.add(current) for neighbor, cost in graph[current].items(): if neighbor not in visited: new_g = g + cost heapq.heappush(open_set, (new_g + heuristic[neighbor], new_g, neighbor, path + [neighbor])) return None

使用示例:

path = astar(romania_map, heuristic, 'Arad', 'Bucharest') print("A*路径:", ' -> '.join(path))

A*的特点:

  • 保证找到最优解(如果启发式函数是可采纳的)
  • 比纯BFS更高效
  • 广泛应用于路径规划和游戏AI

6. 算法性能比较

让我们比较四种算法的表现:

算法路径长度扩展节点数适用场景
BFS最短(边数)最多需要最短路径
DFS不一定最短最少内存有限或解较深
GBFS不一定最短较少快速找到可行解
A*最短(成本)中等需要最优解

实现性能测试:

import time def test_algorithm(algorithm, *args): start_time = time.time() path = algorithm(*args) end_time = time.time() return path, end_time - start_time # 测试所有算法 algorithms = { 'BFS': bfs, 'DFS': dfs, 'GBFS': gbfs, 'A*': astar } for name, algo in algorithms.items(): if name == 'GBFS' or name == 'A*': path, time_taken = test_algorithm(algo, romania_map, heuristic, 'Arad', 'Bucharest') else: path, time_taken = test_algorithm(algo, romania_map, 'Arad', 'Bucharest') print(f"{name}: 路径长度={len(path)-1}, 耗时={time_taken:.6f}秒")

7. 可视化结果

为了更直观地展示算法差异,我们可以使用matplotlib绘制搜索路径:

import matplotlib.pyplot as plt import networkx as nx def draw_path(graph, path, title): G = nx.Graph() for city in graph: G.add_node(city) for neighbor, cost in graph[city].items(): G.add_edge(city, neighbor, weight=cost) pos = nx.spring_layout(G) nx.draw(G, pos, with_labels=True, node_color='lightblue') path_edges = list(zip(path[:-1], path[1:])) nx.draw_networkx_nodes(G, pos, nodelist=path, node_color='red') nx.draw_networkx_edges(G, pos, edgelist=path_edges, edge_color='red', width=2) plt.title(title) plt.show() # 获取各算法的路径 bfs_path = bfs(romania_map, 'Arad', 'Bucharest') dfs_path = dfs(romania_map, 'Arad', 'Bucharest') gbfs_path = gbfs(romania_map, heuristic, 'Arad', 'Bucharest') astar_path = astar(romania_map, heuristic, 'Arad', 'Bucharest') # 绘制路径 draw_path(romania_map, bfs_path, 'BFS搜索路径') draw_path(romania_map, dfs_path, 'DFS搜索路径') draw_path(romania_map, gbfs_path, 'GBFS搜索路径') draw_path(romania_map, astar_path, 'A*搜索路径')

8. 进阶优化与思考

在实际项目中,我们可以对基础算法进行多种优化:

  1. 启发式函数改进

    • 考虑更多因素(如交通状况、地形)
    • 使用机器学习方法学习更好的启发式
  2. 内存优化

    • 使用迭代加深的深度优先搜索(IDDFS)
    • 实现双向搜索
  3. 并行化

    • 多线程/多进程实现
    • GPU加速
  4. 实时应用

    • 动态调整路径(如遇到障碍)
    • 增量式搜索
# 双向BFS示例 def bidirectional_bfs(graph, start, goal): forward_visited = {start: [start]} backward_visited = {goal: [goal]} forward_queue = deque([start]) backward_queue = deque([goal]) while forward_queue and backward_queue: # 前向搜索 current = forward_queue.popleft() for neighbor in graph[current]: if neighbor not in forward_visited: forward_visited[neighbor] = forward_visited[current] + [neighbor] forward_queue.append(neighbor) if neighbor in backward_visited: return forward_visited[neighbor][:-1] + backward_visited[neighbor][::-1] # 后向搜索 current = backward_queue.popleft() for neighbor in graph[current]: if neighbor not in backward_visited: backward_visited[neighbor] = backward_visited[current] + [neighbor] backward_queue.append(neighbor) if neighbor in forward_visited: return forward_visited[neighbor][:-1] + backward_visited[neighbor][::-1] return None

通过这个罗马尼亚地图寻路项目,我们不仅实现了四种基础搜索算法,还深入理解了它们的适用场景和性能特点。在实际应用中,根据具体需求选择合适的算法或组合多种算法,往往能获得更好的效果。

http://www.zskr.cn/news/1447924.html

相关文章:

  • DALL-E 3提示词工程实战:绕过内容限制,解锁AI图像创作潜力
  • 从‘拍脑袋’到‘按图索骥’:我是如何用知识图谱结构引导LLM进行可解释推理的
  • 别再让静态路由‘装死’了!手把手教你用华为BFD实现毫秒级故障切换
  • Django+Vue文化旅游信息公开管理平台源码+论文
  • 行业专属方案:2026九款垂直领域CRM推荐 - Joyky
  • 为什么COM3D2玩家需要实时编辑器?如何用MaidFiddler深度定制你的游戏体验
  • 快手视频下载的终极解决方案:KS-Downloader完整使用指南
  • 基于S9013晶体管的多谐振荡器LED闪烁电路设计与PCB实现
  • 基于Arduino与Python的虚拟迷宫求解机器人:架构、实现与优化
  • AdvCam项目:SiPM与数字化架构革新切伦科夫望远镜相机
  • STM32F407+LAN8720A实现本地网页登录注册功能(Keil工程,含LwIP与HTTP服务)
  • 2026杭州包包回收实测指南:上城拱墅正规实体店测评|名牌包高价回收|无套路避坑全解析 - 薛定谔的梨花猫
  • 百考通AI:数据智能生成,更高效精准
  • 2026沉香十大品牌消费指南 - 资讯速览
  • ZoteroDuplicatesMerger:智能高效解决文献重复问题的自动化工具
  • 2026西安高空外墙防水补漏TOP4:本地靠谱修缮公司甄选 专业防水公司排名推荐(2026年5月防水补漏最新TOP权威排名) - 冠盾建筑修缮
  • 别再傻傻分不清!用Python+OpenCV可视化DOTA数据集HBB与OBB标注,5分钟看懂本质区别
  • 苏州最擅长打经济合同官司的律师及法律服务解析 - 品牌排行榜
  • 智能微信好友关系检测:高效自动化清理单向好友的终极指南
  • 全国阀组组件厂家推荐排名TOP榜:本地源头工厂实力对比(2026年6月最新) - 商业新知
  • Redis缓存规范设计与全方位性能优化实战
  • 如何在PS4上轻松管理全世代游戏存档:Apollo Save Tool终极指南
  • 靠谱兼职平台推荐,全品类综合兼职求职渠道深度解读 - 讲清楚了
  • 免费微信聊天记录导出终极指南:无需越狱永久保存珍贵记忆
  • 2026 海南进出口贸易公司注册:前 10 财税代办公司测评,哪家稳妥? - 速递信息
  • 硬件工程师怎么用AI工具高效追踪材料价格波动?亲测这套工作流可行
  • B站视频怎么下载全场景操作方法与合规无损保存完整指南
  • 老电视信号接口改造:从300欧姆平衡端子到75欧姆同轴接口的工程实践
  • 【回眸】职业转型与心态突破实战指南
  • 闭眼入不翻车!2026实测靠谱的AI写作辅助网站|实测避坑硬核版