【机器学习】机器学习中用到的高等数学知识-8. 图论 (Graph Theory)

news/2024/11/20 16:54:11/
  • 图的表示和遍历:用于处理社交网络、推荐系统等结构化数据。

图论是研究图(Graph)结构的数学分支,在处理网络、关系和结构化数据时起着至关重要的作用。本文将从图的基本表示、遍历算法及其在实际应用中的使用展开讨论,并配以代码和可视化示例。

1. 图的基本表示

1.1 定义

图由节点(顶点)和边组成。

  • 无向图:边没有方向,如 (u, v) 表示节点 u 和 v 之间的连接。
  • 有向图:边有方向,如 (u, v) 表示从节点 u 到 v 的连接。
1.2 表示方法
  1. 邻接矩阵:用 n × n 的矩阵表示,矩阵的元素表示节点之间是否有边。
  2. 邻接表:每个节点对应一个列表,存储与该节点相连的所有节点。
    节点 1: [2, 3]
    节点 2: [1, 4]
    节点 3: [1]
    

1.3 Python 实现
import numpy as np# 邻接矩阵
graph = np.array([[0, 1, 1, 0],[1, 0, 0, 1],[1, 0, 0, 0],[0, 1, 0, 0]
])
print("邻接矩阵:")
print(graph)

 

2. 图的遍历

2.1 深度优先搜索 (DFS)

DFS 按照深度优先的策略遍历节点,适用于寻找路径或检查连通性。

2.1.1 定义

深度优先搜索按照递归深入的方式访问节点,尽可能向深层的节点探索,直到无法继续,再回溯到上一层节点。

2.1.2 算法流程
  1. 从起始节点出发,标记为已访问。
  2. 访问其一个未访问的邻居节点。
  3. 对该邻居节点重复步骤 1 和 2。
  4. 如果当前节点的所有邻居都已访问,则回溯到上一个节点。
  5. 重复直到所有节点访问完毕。
2.1.3 Python 实现
def dfs(graph, start, visited=None):if visited is None:visited = set()visited.add(start)print(start, end=" ")  # 输出当前节点for neighbor in graph[start]:if neighbor not in visited:dfs(graph, neighbor, visited)# 示例图:邻接表表示
graph = {1: [2, 3],2: [4],3: [5],4: [],5: []
}print("深度优先搜索结果:")
dfs(graph, 1)
深度优先搜索结果:
1 2 4 3 5 
2.1.4 应用案例
  • 连通性检查:检查图是否是一个连通图。
  • 路径探索:用于迷宫或网络中的路径查找。
2.1.5 可视化

import networkx as nx
import matplotlib.pyplot as plt# 构建图
G = nx.Graph()
edges = [(1, 2), (1, 3), (2, 4), (3, 5)]
G.add_edges_from(edges)# DFS 遍历
visited = []
def dfs_vis(graph, node):if node not in visited:visited.append(node)for neighbor in list(graph.neighbors(node)):dfs_vis(graph, neighbor)dfs_vis(G, 1)# 可视化
plt.figure(figsize=(6, 6))
pos = nx.spring_layout(G)
nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=2000)
nx.draw_networkx_nodes(G, pos, nodelist=visited, node_color='lightgreen')
plt.title("DFS Traversal")
plt.show()
2.2 广度优先搜索 (BFS)

BFS 按照层级优先的策略遍历节点,适用于寻找最短路径。

2.2.1 定义

广度优先搜索按照层级逐层访问节点,从起始节点出发,先访问所有直接邻居节点,再访问邻居的邻居,依次类推。

2.2.2 算法流程
  1. 从起始节点出发,将其加入队列并标记为已访问。
  2. 从队列中取出一个节点,访问并输出。
  3. 将该节点的所有未访问的邻居加入队列。
  4. 重复步骤 2 和 3,直到队列为空。
2.2.3 Python 实现
from collections import dequedef bfs(graph, start):visited = set()queue = deque([start])  # 队列存储待访问节点visited.add(start)while queue:node = queue.popleft()  # 弹出队首节点print(node, end=" ")  # 输出当前节点for neighbor in graph[node]:if neighbor not in visited:visited.add(neighbor)queue.append(neighbor)# 示例图:邻接表表示
graph = {1: [2, 3],2: [4],3: [5],4: [],5: []
}print("广度优先搜索结果:")
bfs(graph, 1)
广度优先搜索结果:
1 2 3 4 5 
2.2.4 应用案例
  • 最短路径搜索:寻找无权图中的最短路径。
  • 社交网络分析:如推荐朋友、寻找关系链。
2.2.5 可视化

from collections import deque
import networkx as nx
import matplotlib.pyplot as plt# 构建图
G = nx.Graph()
edges = [(1, 2), (1, 3), (2, 4), (3, 5)]
G.add_edges_from(edges)# BFS 遍历
def bfs_vis(graph, start):visited = []queue = deque([start])while queue:node = queue.popleft()if node not in visited:visited.append(node)queue.extend(list(graph.neighbors(node)))return visitedvisited_bfs = bfs_vis(G, 1)# 定义节点位置
pos = nx.spring_layout(G)# 可视化
plt.figure(figsize=(6, 6))
nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=2000)
nx.draw_networkx_nodes(G, pos, nodelist=visited_bfs, node_color='orange')
plt.title("BFS Traversal")
plt.show()
2.3 深度优先搜索 vs 广度优先搜索
特性深度优先搜索 (DFS)广度优先搜索 (BFS)
遍历策略递归深入到最后再回溯层级逐层访问
数据结构栈(隐式递归栈)队列
实现难度简单,递归实现简单,队列实现
适用场景连通性、路径探索最短路径、层级分析
时间复杂度O(V + E)O(V + E)
空间复杂度O(V)O(V)
2.4 实际案例:寻找最短路径 (BFS 应用)

以下用 BFS 在无权图中寻找最短路径:

from collections import deque
def shortest_path_bfs(graph, start, end):queue = deque([(start, [start])])while queue:node, path = queue.popleft()for neighbor in graph[node]:if neighbor == end:return path + [end]elif neighbor not in path:queue.append((neighbor, path + [neighbor]))# 示例图
graph = {1: [2, 3],2: [4],3: [5],4: [],5: []
}
print("最短路径:", shortest_path_bfs(graph, 1, 5))
最短路径: [1, 3, 5]

最短路径: [1, 3, 5]

2.5 总结
  • DFS:深入优先,适用于路径探索和检查连通性。
  • BFS:层级优先,适用于最短路径和层次分析。
  • 图的遍历在解决实际问题(如网络分析、导航优化)中有重要意义。

通过代码实现和可视化,你可以直观理解两种算法及其在不同场景下的适用性。


3. 图的可视化

3.1 用 NetworkX 可视化图

import networkx as nx
import matplotlib.pyplot as plt# 创建图
G = nx.Graph()
G.add_edges_from([(1, 2), (1, 3), (2, 4)])# 绘制图
plt.figure(figsize=(6, 6))
nx.draw(G, with_labels=True, node_color='skyblue', node_size=2000, edge_color='gray')
plt.title("Graph Representation")
plt.show()

4. 图的算法案例:最短路径

以 Dijkstra 算法为例,计算最短路径:

import heapqdef dijkstra(graph, start):pq = []heapq.heappush(pq, (0, start))distances = {node: float('inf') for node in graph}distances[start] = 0while pq:current_distance, current_node = heapq.heappop(pq)if current_distance > distances[current_node]:continuefor neighbor, weight in graph[current_node]:distance = current_distance + weightif distance < distances[neighbor]:distances[neighbor] = distanceheapq.heappush(pq, (distance, neighbor))return distances# 带权图
weighted_graph = {1: [(2, 1), (3, 4)],2: [(4, 2)],3: [(4, 5)],4: []
}
print("最短路径:", dijkstra(weighted_graph, 1))
最短路径: {1: 0, 2: 1, 3: 4, 4: 3}

5. 实际应用详解

5.1 社交网络分析

应用背景
在社交网络中,每个用户可以被表示为一个节点,用户之间的好友关系、关注关系等用边表示。通过分析这种网络结构,可以实现好友推荐、影响力分析等功能。

实际举例

  • 好友推荐
    在 Facebook 或 LinkedIn 等平台中,利用图的遍历算法(如 BFS 或深度学习中的图神经网络),可以找到距离用户较近的未连接节点(共同好友多的用户),推荐为潜在朋友。

代码示例:好友推荐(BFS)

from collections import dequedef recommend_friends(graph, user):visited = set()queue = deque([user])recommended = set()while queue:node = queue.popleft()if node != user:recommended.add(node)for neighbor in graph[node]:if neighbor not in visited and neighbor != user:visited.add(neighbor)queue.append(neighbor)return recommended - set(graph[user])# 社交网络图:节点表示用户,边表示好友关系
social_network = {'A': ['B', 'C'],'B': ['A', 'D', 'E'],'C': ['A', 'F'],'D': ['B'],'E': ['B'],'F': ['C']
}print("推荐好友:", recommend_friends(social_network, 'A'))

结果

推荐好友: {'F', 'D', 'E'}
5.2 推荐系统

应用背景
推荐系统利用用户的行为或偏好生成个性化内容推荐。在图中,节点可以表示用户或物品,边表示用户与物品的关联关系(如用户购买或点赞)。

实际举例

  • 电影推荐
    在 Netflix 中,用户和电影形成一个二部图,用户与电影的交互作为图的边。通过计算与用户兴趣相关的电影节点,可以实现推荐。

代码示例:兴趣图上的推荐

import networkx as nx# 构建兴趣图
interest_graph = nx.Graph()
interest_graph.add_edges_from([('User1', 'MovieA'), ('User1', 'MovieB'),('User2', 'MovieB'), ('User2', 'MovieC'),('User3', 'MovieA'), ('User3', 'MovieC')
])# 推荐算法:找与用户连接节点共同邻居最多的节点
def recommend_movies(graph, user):movies = set(graph.neighbors(user))recommendations = {}for movie in movies:for neighbor in graph.neighbors(movie):if neighbor != user and neighbor not in movies:recommendations[neighbor] = recommendations.get(neighbor, 0) + 1return sorted(recommendations, key=recommendations.get, reverse=True)print("推荐电影:", recommend_movies(interest_graph, 'User1'))

结果

推荐电影: ['User2', 'User3']
5.3 最短路径问题

应用背景
最短路径问题广泛用于导航系统(如 Google Maps)、物流优化、通信网络等。在图中,节点表示位置或设备,边的权重表示距离或费用。

实际举例

  • 导航系统
    在 Google Maps 中,路网被表示为图,节点是路口,边是道路,权重是距离或时间。通过 Dijkstra 算法找到两个节点之间的最短路径。

代码示例:最短路径(Dijkstra 算法)

import heapqdef dijkstra(graph, start, end):pq = []  # 优先队列heapq.heappush(pq, (0, start))  # (距离, 节点)distances = {node: float('inf') for node in graph}distances[start] = 0previous_nodes = {node: None for node in graph}while pq:current_distance, current_node = heapq.heappop(pq)if current_distance > distances[current_node]:continuefor neighbor, weight in graph[current_node]:distance = current_distance + weightif distance < distances[neighbor]:distances[neighbor] = distanceprevious_nodes[neighbor] = current_nodeheapq.heappush(pq, (distance, neighbor))# 重建路径path, node = [], endwhile previous_nodes[node] is not None:path.insert(0, node)node = previous_nodes[node]path.insert(0, start)return path, distances[end]# 路网图:节点表示路口,边权重表示距离
road_network = {'A': [('B', 1), ('C', 4)],'B': [('A', 1), ('C', 2), ('D', 5)],'C': [('A', 4), ('B', 2), ('D', 1)],'D': [('B', 5), ('C', 1)]
}shortest_path, distance = dijkstra(road_network, 'A', 'D')
print("最短路径:", shortest_path)
print("路径距离:", distance)

结果

最短路径: ['A', 'B', 'C', 'D']
路径距离: 4
5.4 总结
  • 社交网络分析:通过 BFS 推荐潜在好友。
  • 推荐系统:利用图算法分析用户兴趣关联,推荐内容。
  • 最短路径问题:通过 Dijkstra 算法优化路径规划。

这些应用展示了图论在现实世界中的广泛用途,其背后依赖于高效的算法设计和图结构建模。


6. 总结

图论机器学习中是强大的工具:

  • 图表示学习:在图神经网络(GNN)中用于学习节点嵌入。
  • 优化问题:如流量优化和任务调度。
  • 复杂网络分析:如社区检测、页面排序等。

通过代码和图示,我们能更直观地理解图论,并将其用于各种实际场景中,进一步增强机器学习模型的表现力。


http://www.ppmy.cn/news/1548526.html

相关文章

华为数字化转型的本质为何是管理变革

随着全球经济的加速数字化转型&#xff0c;企业纷纷进入了数字化时代的大潮。华为作为数字化转型的领军者&#xff0c;已经成功实践了从传统企业向数字化企业的蜕变。对于企业而言&#xff0c;数字化转型不仅仅是新技术的应用&#xff0c;更是一场管理变革。在这场变革的背后&a…

Bugku CTF_Web——字符?正则?

Bugku CTF_Web——字符&#xff1f;正则&#xff1f; 进入靶场 <?php highlight_file(2.php); $keyflag{********************************}; $IM preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match); if…

基于yolov8、yolov5的植物类别识别系统(含UI界面、训练好的模型、Python代码、数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下&#xff1a; 算法模型&#xff1a;     yolov8、yolov8 SE注意力机制 或 yolov5、yolov5 SE注意力机制 &#xff0c; 直接提供最少两个训练好的模型。模型十分重要&#xff0c;因为有些同学的电脑没有 GPU&#xff0…

数字图像处理(c++ opencv):彩色图像处理-彩色基础与彩色模型

彩色图像基础 颜色特性&#xff1a;亮度、色调、饱和度 &#xff08;1&#xff09;亮度&#xff1a;即强度&#xff0c;如灰度值 &#xff08;2&#xff09;色调&#xff1a;混合光波中的主导光波属性&#xff0c;即被观察者感知的主导色。如描述一个物体为红色&#xff0c;就…

C函数从lua中读取数据接口常用接口

读取基本数据类型的接口 lua_tonumber和lua_tointeger 用途&#xff1a;用于从Lua栈中获取数字类型的数据。lua_tonumber用于获取浮点数&#xff0c;lua_tointeger用于获取整数。示例&#xff1a;假设在Lua中调用一个C函数并传入一个数字&#xff0c;在C函数中可以这样获取这个…

多目标优化算法:多目标黑翅鸢算法(MOBKA)求解UF1-UF10,提供完整MATLAB代码

一、黑翅鸢算法介绍 黑翅鸢优化算法&#xff08;Black-winged Kite Algorithm, BKA&#xff09;是2024年提出的一种元启发式优化算法&#xff0c;其灵感来源于黑翅鸢的迁徙和捕食行为。这种算法通过模拟黑翅鸢在捕食过程中的飞行和搜索策略&#xff0c;被用来解决优化问题&…

【Java】ArrayList与LinkedList详解!!!

目录 一&#x1f31e;、List 1&#x1f345;.什么是List&#xff1f; 2&#x1f345;.List中的常用方法 二&#x1f31e;、ArrayList 1&#x1f34d;.什么是ArrayList? 2&#x1f34d;.ArrayList的实例化 3&#x1f34d;.ArrayList的使用 4&#x1f34d;.ArrayList的遍…

Gin路由深入

路由(Routing )是由一个 URI (或者叫路径)和一个特定的 HTTP 方法( GET 、 POST 等) 组成的,涉及到应用如何响应客户端对某个网站节点的访问。 1、GET POST