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

【图结构从入门到应用】图的表示和遍历,图搜索算法详解与示例

 1 图的概念

         图是一种非常常见的数据结构,用于表示对象之间的关系。在计算机科学中,有许多不同的图类型,包括有向图(Directed Graph)和无向图(Undirected Graph)。图通常由节点(顶点)和边组成,节点代表对象,边表示对象之间的关系。

表示图:

使用NetworkX库,你可以轻松表示图。首先,确保你已经安装了这个库:

pip install networkx

接下来,让我们创建一个简单的无向图来表示社交网络关系:

import networkx as nx# 创建一个空的无向图
G = nx.Graph()# 添加节点
G.add_node("Alice")
G.add_node("Bob")
G.add_node("Charlie")# 添加边
G.add_edge("Alice", "Bob")
G.add_edge("Bob", "Charlie")
G.add_edge("Charlie", "Alice")

这将创建一个包含三个节点和三条边的无向图,表示Alice、Bob和Charlie之间的社交关系。

2  图的表示

        图可以分为有向图(Directed Graph)和无向图(Undirected Graph)。以下是几种表示图的方式:

2.1 邻接矩阵(Adjacency Matrix)

        使用一个二维数组表示图中的边。对于无向图,矩阵是对称的,而对于有向图,矩阵不一定对称。矩阵中的元素表示从一个顶点到另一个顶点是否有边,以及边的权重(对于带权图)。

例如,以下是一个无向图的邻接矩阵表示:

0 1 1 0
1 0 1 1
1 1 0 0
0 1 0 0

2.2 邻接列表(Adjacency List)

        使用一个数组或哈希表,其中每个顶点都有一个关联的链表,链表中包含了与该顶点相邻的顶点。

例如,以下是一个无向图的邻接列表表示:

0 -> 1 -> 2
1 -> 0 -> 2 -> 3
2 -> 0 -> 1
3 -> 1

 2.3 边列表(Edge List)

        将图中的边存储为一组二元组或对象的列表,每个元素表示一条边。

例如,以下是一个无向图的边列表表示:

(0, 1), (0, 2), (1, 2), (1, 3)

3 图的遍历

图的遍历是指按照一定规则访问图中的所有节点。常见的图遍历算法包括深度优先搜索(DFS)和广度优先搜索(BFS)。

3.1 遍历节点

# 遍历所有节点
for node in G.nodes():print(node)

3.2 遍历边

# 遍历所有边
for edge in G.edges():print(edge)

3.3 遍历节点的邻居

node = "Bob"
neighbors = G.neighbors(node)
for neighbor in neighbors:print(f"{node} 的邻居: {neighbor}")

4 图搜索算法

        图搜索(Graph Search)是一种用于在图数据结构中查找特定信息或路径的通用计算机科学算法。图搜索广泛应用于各种领域,包括计算机科学、人工智能、地理信息系统、网络路由和数据分析。

图搜索的目标可以有很多种,包括以下几个常见的:

  1. 路径搜索:查找从一个节点到另一个节点的最短路径或任何可行路径。这包括算法如Dijkstra算法、A*算法和深度优先搜索(DFS)等。

  2. 连通性检测:确定图中是否存在一条路径或边,以连接两个特定的节点。这通常用于网络路由和通信系统中。

  3. 遍历:遍历整个图,以查找特定条件的节点或边。这包括深度优先搜索(DFS)和广度优先搜索(BFS)等。

  4. 最小生成树:查找一个图的最小生成树,它是一个包含所有节点并且边权重之和最小的子图。

  5. 拓扑排序:对有向无环图(DAG)进行拓扑排序,以确定节点之间的依赖关系。

图搜索算法的选择取决于问题的性质和要求。以下是一些常见的图搜索算法:

4.1 深度优先搜索(DFS)

递归地探索图的深度,然后返回并探索其他分支。适用于路径搜索和遍历。

visited = set()def dfs(node):if node not in visited:print(node)visited.add(node)for neighbor in G.neighbors(node):dfs(neighbor)start_node = "Alice"
dfs(start_node)

4.2 广度优先搜索(BFS)

        逐层遍历图,从起始节点开始,然后扩展到与起始节点距离为1的节点,依此类推。适用于路径搜索和连通性检测。

from collections import dequedef bfs(start_node):visited = set()queue = deque([start_node])while queue:node = queue.popleft()if node not in visited:print(node)visited.add(node)queue.extend(neighbor for neighbor in G.neighbors(node) if neighbor not in visited)start_node = "Alice"
bfs(start_node)

4.3 Dijkstra算法 

        用于查找带权重图中的最短路径。适用于路径搜索和路由算法。

        Dijkstra算法用于在带权重的图中查找从一个起点到所有其他节点的最短路径。它是一种贪婪算法,通过不断选择距离最短的节点来扩展路径,以找到最短路径。

示例(Python):

import heapqdef dijkstra(graph, start):distances = {node: float('infinity') for node in graph}distances[start] = 0queue = [(0, start)]  # 使用优先队列来加速查找最短距离while queue:current_distance, current_node = heapq.heappop(queue)if current_distance > distances[current_node]:continuefor neighbor, weight in graph[current_node].items():distance = current_distance + weightif distance < distances[neighbor]:distances[neighbor] = distanceheapq.heappush(queue, (distance, neighbor))  # 更新距离并加入队列return distancesgraph = {'A': {'B': 1, 'C': 4},'B': {'A': 1, 'C': 2, 'D': 5},'C': {'A': 4, 'B': 2, 'D': 1},'D': {'B': 5, 'C': 1}
}start_node = 'A'
shortest_distances = dijkstra(graph, start_node)
print(shortest_distances)

输出:

4.4 A*算法

        结合了启发式搜索和Dijkstra算法的特点,用于在有权重的图中查找最短路径。适用于路径搜索。

4.5 Kruskal算法和Prim算法

        用于寻找最小生成树。

4.6 拓扑排序

        用于DAG中的节点排序。

相关文章:

  • ubuntu 下的 使用anaconda 环境运行python 项目
  • [C++]——带你学习类和对象
  • C++入门精讲——入门看完这一篇就够了
  • Go学习第十五章——Gin参数绑定bind与验证器
  • c:变参函数:汇编解析;va_list;marco 宏:__VA_ARGS__
  • 数字孪生与智慧城市:开启未来智慧生活
  • 2023CCF中国开源大会 | 麒麟信安作为首批合作伙伴入驻全国信创开源广场
  • 计算机专业毕业设计如何选题、如何规避风险、避免入坑
  • uniapp解决iOS切换语言——原生导航栏buttons文字不生效
  • Elasticsearch聚合----aggregations的简单使用
  • 软考系统架构师知识点集锦二:软件工程
  • Tensorflow2 中模型训练标签顺序和预测结果标签顺序不一致问题解决办法
  • jsp简单实现新闻发布系统中用户注册确认和用户模拟登录功能的开发
  • 设计模式之代理模式
  • 【RabbitMQ 实战】12 镜像队列
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • Google 是如何开发 Web 框架的
  • [数据结构]链表的实现在PHP中
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • AWS实战 - 利用IAM对S3做访问控制
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • java 多线程基础, 我觉得还是有必要看看的
  • JAVA 学习IO流
  • Javascript 原型链
  • js数组之filter
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • node学习系列之简单文件上传
  • Python实现BT种子转化为磁力链接【实战】
  • Redux 中间件分析
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 大快搜索数据爬虫技术实例安装教学篇
  • 模型微调
  • 如何解决微信端直接跳WAP端
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 微信开源mars源码分析1—上层samples分析
  • 线性表及其算法(java实现)
  • 最简单的无缝轮播
  • 阿里云ACE认证学习知识点梳理
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​比特币大跌的 2 个原因
  • ​第20课 在Android Native开发中加入新的C++类
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • (02)vite环境变量配置
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (42)STM32——LCD显示屏实验笔记
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (zt)最盛行的警世狂言(爆笑)
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (十六)串口UART
  • (一)u-boot-nand.bin的下载
  • (转)负载均衡,回话保持,cookie
  • (状压dp)uva 10817 Headmaster's Headache
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示