图搜索算法教程(个人总结版)

图搜索算法是一类用于遍历或搜索图结构的算法,广泛应用于网络分析、路径规划、人工智能等领域。常见的图搜索算法包括深度优先搜索(DFS)、广度优先搜索(BFS)、Dijkstra算法、A*算法等。本文将详细介绍这些图搜索算法的基本原理、具体实现步骤、优劣势以及应用实例。

一、图的基本概念

在介绍图搜索算法之前,首先了解一些图的基本概念:

  • :由顶点(节点)和边(连接顶点的线)组成的结构。
  • 无向图:边没有方向,即 (u, v) 与 (v, u) 是相同的。
  • 有向图:边有方向,即 (u, v) 与 (v, u) 是不同的。
  • 权重:边上的数值,表示从一个顶点到另一个顶点的代价。

二、深度优先搜索(DFS)

2.1 基本原理

深度优先搜索(Depth First Search, DFS)是一种遍历或搜索图的算法。它从起始节点开始,沿着每一个可能的分支尽可能深地探索,直到到达死胡同,然后回溯并继续探索其他分支。

2.2 具体实现

以下是DFS的递归实现:

def dfs(graph, start, visited=None):if visited is None:visited = set()visited.add(start)print(start, end=' ')for next in graph[start] - visited:dfs(graph, next, visited)return visited# 示例图的邻接表表示
graph = {'A': {'B', 'C'},'B': {'A', 'D', 'E'},'C': {'A', 'F'},'D': {'B'},'E': {'B', 'F'},'F': {'C', 'E'}
}# 执行DFS
dfs(graph, 'A')

2.3 优劣势

优势

  • 实现简单,适用于无环图。
  • 空间复杂度低,递归调用栈空间为O(V)。

劣势

  • 可能陷入无限循环(在图中存在环时)。
  • 不保证找到最短路径。

三、广度优先搜索(BFS)

3.1 基本原理

广度优先搜索(Breadth First Search, BFS)是一种遍历或搜索图的算法。它从起始节点开始,先访问所有邻近节点,然后逐层向外扩展,直到找到目标节点或遍历完整个图。

3.2 具体实现

以下是BFS的实现:

from collections import dequedef bfs(graph, start):visited = set()queue = deque([start])visited.add(start)while queue:vertex = queue.popleft()print(vertex, end=' ')for neighbor in graph[vertex]:if neighbor not in visited:visited.add(neighbor)queue.append(neighbor)# 示例图的邻接表表示
graph = {'A': {'B', 'C'},'B': {'A', 'D', 'E'},'C': {'A', 'F'},'D': {'B'},'E': {'B', 'F'},'F': {'C', 'E'}
}# 执行BFS
bfs(graph, 'A')

3.3 优劣势

优势

  • 能找到从起点到目标节点的最短路径(无权图)。
  • 不易陷入无限循环(环被检测到后忽略)。

劣势

  • 空间复杂度较高,需存储每一层的所有节点。

四、Dijkstra算法

4.1 基本原理

Dijkstra算法用于查找带权图中从起点到其他所有节点的最短路径。它通过维护一个优先队列来选择当前最短路径的节点,并更新其邻居的距离。

4.2 具体实现

以下是Dijkstra算法的实现:

import heapqdef dijkstra(graph, start):pq = [(0, start)]distances = {vertex: float('inf') for vertex in graph}distances[start] = 0while pq:current_distance, current_vertex = heapq.heappop(pq)if current_distance > distances[current_vertex]:continuefor neighbor, weight in graph[current_vertex].items():distance = current_distance + weightif distance < distances[neighbor]:distances[neighbor] = distanceheapq.heappush(pq, (distance, neighbor))return distances# 示例图的邻接表表示(带权重)
graph = {'A': {'B': 1, 'C': 4},'B': {'A': 1, 'D': 2, 'E': 5},'C': {'A': 4, 'F': 3},'D': {'B': 2},'E': {'B': 5, 'F': 1},'F': {'C': 3, 'E': 1}
}# 执行Dijkstra算法
distances = dijkstra(graph, 'A')
print(distances)

4.3 优劣势

优势

  • 能找到从起点到所有其他节点的最短路径。
  • 适用于有向图和无向图。

劣势

  • 对于负权图无法使用(Bellman-Ford算法适用于负权图)。
  • 时间复杂度较高,为O(E + V log V)。

五、A*算法

5.1 基本原理

A*算法是一种用于路径规划的启发式搜索算法,通过结合实际距离和估计距离(启发式函数)来选择路径。它在确保最优性的同时,提高了搜索效率。

5.2 具体实现

以下是A*算法的实现:

import heapqdef heuristic(a, b):return abs(ord(a) - ord(b))def astar(graph, start, goal):pq = [(0, start)]came_from = {start: None}g_score = {vertex: float('inf') for vertex in graph}g_score[start] = 0f_score = {vertex: float('inf') for vertex in graph}f_score[start] = heuristic(start, goal)while pq:current = heapq.heappop(pq)[1]if current == goal:path = []while current:path.append(current)current = came_from[current]return path[::-1]for neighbor, weight in graph[current].items():tentative_g_score = g_score[current] + weightif tentative_g_score < g_score[neighbor]:came_from[neighbor] = currentg_score[neighbor] = tentative_g_scoref_score[neighbor] = g_score[neighbor] + heuristic(neighbor, goal)heapq.heappush(pq, (f_score[neighbor], neighbor))return []# 示例图的邻接表表示(带权重)
graph = {'A': {'B': 1, 'C': 4},'B': {'A': 1, 'D': 2, 'E': 5},'C': {'A': 4, 'F': 3},'D': {'B': 2},'E': {'B': 5, 'F': 1},'F': {'C': 3, 'E': 1}
}# 执行A*算法
path = astar(graph, 'A', 'F')
print(path)

5.3 优劣势

优势

  • 能找到最优路径(使用适当的启发式函数)。
  • 比Dijkstra算法更高效。

劣势

  • 启发式函数的选择对算法性能影响很大。
  • 不适用于负权图。

六、图搜索算法的应用实例

6.1 迷宫求解

利用BFS或A*算法可以求解迷宫问题,找到从起点到终点的路径。

def bfs_maze(maze, start, goal):queue = deque([start])visited = set()visited.add(start)came_from = {start: None}while queue:current = queue.popleft()if current == goal:path = []while current:path.append(current)current = came_from[current]return path[::-1]for direction in [(0, 1), (1, 0), (0, -1), (-1, 0)]:neighbor = (current[0] + direction[0], current[1] + direction[1])if neighbor in maze and neighbor not in visited:visited.add(neighbor)queue.append(neighbor)came_from[neighbor] = currentreturn []# 示例迷宫(0表示空地,1表示墙壁)
maze = {(0, 0): 0, (0, 1): 0, (0, 2): 1, (0, 3): 0,(1, 0): 1, (1, 1): 0, (1, 2): 1, (1, 3): 0,(2, 0): 0, (2, 1): 0, (2, 2): 0, (2, 3): 1,(3, 0): 0, (3, 1): 1, (3, 2): 0, (3, 3): 0
}# 执行迷宫求解
start = (0, 0)
goal = (3, 3)
path = bfs_maze(maze, start, goal)
print(path)

6.2 路径规划

利用Dijkstra或A*算法可以进行路径规划,找到从起点到终点的最短路径。

# 示例地图的邻接表表示(带权重)
map_graph = {'A': {'B': 1, 'C': 4},'B': {'A': 1, 'D': 2, 'E': 5},'C': {'A': 4, 'F': 3},'D': {'B': 2},'E': {'B': 5, 'F': 1},'F': {'C': 3, 'E': 1}
}# 执行路径规划
start = 'A'
goal = 'F'
shortest_path = astar(map_graph, start, goal)
print(shortest_path)

七、总结

图搜索算法是解决图结构问题的重要工具,广泛应用于路径规划、网络分析、人工智能等领域。本文详细介绍了深度优先搜索(DFS)、广度优先搜索(BFS)、Dijkstra算法、A*算法的基本原理、具体实现、优劣势及应用实例。通过这些算法的学习和应用,可以有效解决实际问题,并为进一步研究和应用提供基础。

参考文献

  1. 《算法导论》 - Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein
  2. 《人工智能:一种现代的方法》 - Stuart Russell, Peter Norvig
  3. 《算法》 - Robert Sedgewick, Kevin Wayne
  4. 《图论及其应用》 - Jonathan L. Gross, Jay Yellen

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/14626.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

创建JSON数据包

在C语言中&#xff0c;JSON不是一种内置的数据类型&#xff0c;因此你需要使用第三方库来创建和解析JSON数据。一个流行的库是cJSON&#xff0c;它允许你以C语言的方式操作JSON数据。 以下是一个使用cJSON库创建类似于你给出的JSON数据包的示例&#xff1a; 首先&#xff0c;…

go-zero 实战(5)

引入Prometheus 用 Prometheus 监控应用 1. 用 docker 启动 Prometheus 编辑配置位置&#xff0c;我将 prometheus.yaml 和 targets.json 文件放在了 /opt/prometheus/conf目录下 prometheus.yaml global:scrape_interval: 15s # 抓取间隔evaluation_interval: 15s # 评估…

【代码随想录 二叉树】二叉树前序、中序、后序遍历的迭代遍历

文章目录 1. 二叉树前序遍历&#xff08;迭代法&#xff09;2. 二叉树后序遍历&#xff08;迭代法&#xff09;3. 二叉树中序遍历&#xff08;迭代法&#xff09; 1. 二叉树前序遍历&#xff08;迭代法&#xff09; 题目连接 &#x1f34e;因为处理顺序和访问顺序是一致的。所…

前端工程化-babel、corejs、postcss

出处&#xff1a;前端工程化-babel、corejs、postcss | 刘维_个人博客_编程秘籍_开发技巧_入门到精通_生活感悟 (ldlw.site) 一. babel和corejs的作用到底是什么 脑子里面的想法 es6 -> es5 es6里面其实有两种东西 语法 新特性 转的语法 const a 1 const b &#xf…

Shader GLSL 3D旋转函数

mat4 rotationMatrix(vec3 axis, float angle) {axis = normalize(axis);float s = sin(angle);float c = cos(angle)

类和对象的基本概念

类和对象的基本概念 C和C中struct区别类的封装封装访问权限总结struct和class的区别 将成员变量设置为private C和C中struct区别 C语言struct只有变量C语言struct 既有变量&#xff0c;也有函数 类的封装 封装 把变量&#xff08;属性&#xff09;和函数&#xff08;操作&a…

交换机部分综合实验

实验要求 1.内网IP地址使用172.16.0.0/16 2.sw1和sW2之间互为备份; 3.VRRP/mstp/vlan/eth-trunk均使用; 4.所有pc均通过DHcP获取Ip地址; 5.ISP只配置IP地址; 6.所有电脑可以正常访问IsP路由器环回 实验拓扑 实验思路 1.给交换机创建vlan&#xff0c;并将接口划入vlan 2.在SW1和…

Unity Render Streaming 云渲染 外网访问

初版&#xff1a; 日期&#xff1a;2024.5.20 前言&#xff1a;临时思路整理&#xff0c;后期会详细补充 环境&#xff1a; 1. 阿里云服务器 需要安装好nodejs 、npm 2. windows电脑&#xff0c;需安装好 nodejs 、npm 3.Unity 2021.3.15f1 4.Unity Render Streaming …

31.GDB介绍及简单使用

文章目录 基本用法查看汇编代码Text User Interface(TUI)refernece 欢迎访问个人网络日志&#x1f339;&#x1f339;知行空间&#x1f339;&#x1f339; GDB 是 GNU Debugger的缩写&#xff0c;是GNU软件系统中的标准调试器&#xff0c; 很多类UNIX系统都可以使用GDB&#xf…

【论文解读】Overview of the Scalable Video Coding Extension of the H.264/AVC Standard

介绍 该篇论文是一篇关于H.264/AVC标准可扩展视频编码(SVC)扩展的综述论文,由Heiko Schwarz、Detlev Marpe和Thomas Wiegand撰写,发表在《IEEE Transactions on Circuits and Systems for Video Technology》2007年9月第17卷第9期上。 论文解读 摘要: H.264/AVC视频编…

乡村振兴的农业供给侧结构性改革:优化农业产业结构,提升农产品质量,满足市场需求,实现美丽乡村产业振兴

一、引言 乡村振兴战略是我国当前及未来一段时间内的重大战略部署&#xff0c;旨在推动农业农村现代化&#xff0c;实现城乡融合发展。在乡村振兴战略中&#xff0c;农业供给侧结构性改革是核心任务之一。通过优化农业产业结构、提升农产品质量、满足市场需求&#xff0c;不仅…

韩国云主机远程故障怎么排查?

韩国云主机远程故障可能是由于多种原因引起的&#xff0c;包括网络问题、服务器故障、安全设置、客户端问题等。下面是针对韩国云主机远程故障的排查步骤和解决方法&#xff1a; 检查网络连接 1.使用 ping 命令 在本地计算机上使用 ping 命令检查与云主机之间的网络连接。如果无…

AI巨头争相与Reddit合作:为何一个古老的论坛成为AI训练的“宝藏”?

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

debian nginx upsync consul 实现动态负载

1. consul 安装 wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg echo "deb [signed-by/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_r…

MariaDB 给指定列值自动加密(持久数据加触发器)

文章目录 代码插入时&#xff0c;自动加密更新时&#xff0c;自动加密查看触发器数据操作示例update数据取出解密取 注意一次尝试&#xff0c;看加密后数据长度 参考链接&#xff1a; 一篇非常好的讲解触发器的文章&#xff1a;示例、原理MySQL/MariaDB触发器。 用触发器自动加…

前端工程化07-常见的包管理工具npm、yarn、cnpm、npx、pnpm

8、包管理工具 8.1、包管理工具概述 npm包管理工具、在安装node的时候这个东西就已经安装过了&#xff0c;通过npm去管理包的时候这个时候回有一个配置文件叫做package.json,他是以json的方式来书写对应的一个配置文件&#xff0c;这个配置文件是可以添加特别多的一些字段的&…

input输入多行文本,保存为.dot文件和对应的.txt文件

需求 不管是上面的dot还是这个dot 变成 input输入文本按“# ꧂ ꧁”结束保存在dot文本文件夹下&#xff0c;用txt保存每个文件文件名&#xff1a; 编号. 第二行有字文字 时间戳 代码 首先&#xff0c;我会创建一个Python脚本&#xff0c;它将接受用户的输入&#xff0c;直到…

案例题(第二版)

案例题目 信息系统架构设计 基本概念 信息系统架构&#xff08;ISA&#xff09;是对某一特定内容里的信息进行统筹、规划、设计、安排等一系列的有机处理的活动。特点如下 架构是对系统的抽象&#xff0c;它通过描述元素、元素的外部可见属性及元素之间的关系来反映这种抽象…

css属性之间总是有换行

问题 在create-next-app创建项目的时候,只要我没有选择eslint的时候&#xff0c;就不会在保存的时候每个属性之间有换行&#xff0c;但是创建项目的时候选择eslint&#xff0c;保存的时候就会在每条属性间有换行 回答 当你使用 create-next-app 创建项目并选择使用 ESLint 时…

k8s 1.28.10 浏览器访问6443查看api,需要证书

添加证书 使用client-certificate-data和client-key-data生成一个p12文件 1.生成client-certificate-data grep client-certificate-data ~/.kube/config | head -n 1 | awk {print $2} | base64 -d >> kubecfg.crt2.生成client-key-data grep client-key-data ~/.kub…