用Python将原始边列表转换为邻接矩阵

news/2024/5/10 1:18:56

👽发现宝藏

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。

在图论和网络分析中,图是一种非常重要的数据结构,它由节点(或顶点)和连接这些节点的边组成。在Python中,我们可以使用邻接矩阵来表示图,其中矩阵的行和列代表节点,矩阵中的值表示节点之间是否存在边。

有时候,我们会从外部数据源中得到原始的边列表,而需要将其转换为邻接矩阵以便进行后续的分析和处理。本文将介绍如何使用Python来实现这一转换过程。

原始边列表

假设我们有一个原始边列表,其中每个元素都表示一条边,例如:

edges = [(0, 1), (0, 2), (1, 2), (2, 3)]

在这个例子中,每个元组 (a, b) 表示节点 a 和节点 b 之间存在一条边。

转换为邻接矩阵

我们首先需要确定图中节点的数量,然后创建一个相应大小的零矩阵。接着,我们遍历原始边列表,根据每条边的两个节点,将对应的矩阵元素设为 1。最终得到的矩阵就是我们所需的邻接矩阵。

让我们来看看如何用Python代码实现这一过程:

def edges_to_adjacency_matrix(edges):# 找到图中节点的数量max_node = max(max(edge) for edge in edges) + 1# 创建零矩阵adjacency_matrix = [[0] * max_node for _ in range(max_node)]# 遍历原始边列表,更新邻接矩阵for edge in edges:adjacency_matrix[edge[0]][edge[1]] = 1adjacency_matrix[edge[1]][edge[0]] = 1  # 如果是无向图,边是双向的return adjacency_matrix# 测试
edges = [(0, 1), (0, 2), (1, 2), (2, 3)]
adjacency_matrix = edges_to_adjacency_matrix(edges)
for row in adjacency_matrix:print(row)

在这段代码中,edges_to_adjacency_matrix 函数接受原始边列表作为参数,并返回对应的邻接矩阵。然后我们对给定的边列表进行了测试,并输出了生成的邻接矩阵。

扩展和优化

虽然上述代码能够完成原始边列表到邻接矩阵的转换,但在实际应用中可能需要进行一些扩展和优化。

  1. 处理有向图和无向图:目前的代码默认处理无向图,如果是有向图,需要根据具体需求修改代码,只在一个方向上设置邻接关系。

  2. 处理权重:有时边不仅仅是存在与否的关系,还可能有权重。修改代码以支持带权重的图。

  3. 使用稀疏矩阵:对于大型图,邻接矩阵可能会占用大量内存,可以考虑使用稀疏矩阵来节省内存空间。

  4. 性能优化:对于大规模的边列表,需要考虑代码的性能。可以尝试使用更高效的数据结构或算法来实现转换过程。

下面是对代码的一些优化示例:

import numpy as npdef edges_to_adjacency_matrix(edges, directed=False):max_node = max(max(edge) for edge in edges) + 1adjacency_matrix = np.zeros((max_node, max_node))for edge in edges:if directed:adjacency_matrix[edge[0]][edge[1]] = 1else:adjacency_matrix[edge[0]][edge[1]] = 1adjacency_matrix[edge[1]][edge[0]] = 1return adjacency_matrix# 测试
edges = [(0, 1), (0, 2), (1, 2), (2, 3)]
adjacency_matrix = edges_to_adjacency_matrix(edges)
print("无向图的邻接矩阵:")
print(adjacency_matrix)directed_edges = [(0, 1), (0, 2), (1, 2), (2, 3)]
directed_adjacency_matrix = edges_to_adjacency_matrix(directed_edges, directed=True)
print("\n有向图的邻接矩阵:")
print(directed_adjacency_matrix)

在优化后的代码中,我们使用了NumPy库来创建和操作矩阵,这可以提高代码的性能和可读性。同时,我们添加了一个参数 directed 来指示图的类型,从而支持有向图和无向图的转换。

使用稀疏矩阵优化内存占用

在处理大型图时,邻接矩阵可能会变得非常稀疏,其中大部分元素都是零。为了优化内存占用,可以使用稀疏矩阵来表示邻接关系。

Python中有多种库可以处理稀疏矩阵,其中Scipy库提供了稀疏矩阵的各种操作和算法。让我们来看看如何使用Scipy中的稀疏矩阵来优化代码:

import numpy as np
from scipy.sparse import lil_matrixdef edges_to_adjacency_matrix(edges, directed=False):max_node = max(max(edge) for edge in edges) + 1adjacency_matrix = lil_matrix((max_node, max_node), dtype=np.int8)for edge in edges:if directed:adjacency_matrix[edge[0], edge[1]] = 1else:adjacency_matrix[edge[0], edge[1]] = 1adjacency_matrix[edge[1], edge[0]] = 1return adjacency_matrix# 测试
edges = [(0, 1), (0, 2), (1, 2), (2, 3)]
adjacency_matrix = edges_to_adjacency_matrix(edges)
print("无向图的邻接矩阵:")
print(adjacency_matrix.toarray())directed_edges = [(0, 1), (0, 2), (1, 2), (2, 3)]
directed_adjacency_matrix = edges_to_adjacency_matrix(directed_edges, directed=True)
print("\n有向图的邻接矩阵:")
print(directed_adjacency_matrix.toarray())

在这个版本的代码中,我们使用了 scipy.sparse.lil_matrix 来创建稀疏矩阵。它能够有效地处理大型稀疏矩阵,并且只存储非零元素,从而节省内存。

通过这种优化,我们可以处理更大规模的图数据,而不会因为内存占用过高而导致性能下降或内存不足的问题。

处理带权重的边列表

在某些情况下,图的边不仅仅表示节点之间的连接关系,还可能有权重信息。例如,在交通网络中,边可以表示道路,而权重可以表示道路的长度或通行时间。

让我们来看看如何修改代码,以支持带权重的边列表:

import numpy as np
from scipy.sparse import lil_matrixdef edges_to_adjacency_matrix(edges, directed=False, weighted=False):max_node = max(max(edge[0], edge[1]) for edge in edges) + 1adjacency_matrix = lil_matrix((max_node, max_node), dtype=np.float32)for edge in edges:if directed:if weighted:adjacency_matrix[edge[0], edge[1]] = edge[2]else:adjacency_matrix[edge[0], edge[1]] = 1else:if weighted:adjacency_matrix[edge[0], edge[1]] = edge[2]adjacency_matrix[edge[1], edge[0]] = edge[2]else:adjacency_matrix[edge[0], edge[1]] = 1adjacency_matrix[edge[1], edge[0]] = 1return adjacency_matrix# 测试
weighted_edges = [(0, 1, 5), (0, 2, 3), (1, 2, 2), (2, 3, 7)]
weighted_adjacency_matrix = edges_to_adjacency_matrix(weighted_edges, weighted=True)
print("带权重的邻接矩阵:")
print(weighted_adjacency_matrix.toarray())

在这个版本的代码中,我们添加了一个 weighted 参数来指示边是否带有权重。如果 weighted 参数为 True,则从边列表中提取权重信息,并将其保存到邻接矩阵中。否则,邻接矩阵中的值仍然表示边的存在与否。

通过这种修改,我们可以处理带有权重信息的图数据,并在邻接矩阵中保留这些信息,以便进行后续的分析和计算。

图的可视化

在处理图数据时,可视化是一种强大的工具,它可以帮助我们直观地理解图的结构和特征。Python中有许多库可以用来可视化图数据,其中NetworkX是一个常用的库,它提供了丰富的功能来创建、操作和可视化图。

让我们来看看如何使用NetworkX来可视化我们生成的邻接矩阵:

import networkx as nx
import matplotlib.pyplot as pltdef visualize_adjacency_matrix(adjacency_matrix):G = nx.from_numpy_matrix(adjacency_matrix)pos = nx.spring_layout(G)  # 定义节点位置nx.draw(G, pos, with_labels=True, node_color='skyblue', node_size=500, font_size=10)  # 绘制图edge_labels = {(i, j): w['weight'] for i, j, w in G.edges(data=True)}  # 获取边权重nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=10)  # 绘制边权重plt.title("Graph Visualization")plt.show()# 测试
weighted_edges = [(0, 1, 5), (0, 2, 3), (1, 2, 2), (2, 3, 7)]
weighted_adjacency_matrix = edges_to_adjacency_matrix(weighted_edges, weighted=True)
print("带权重的邻接矩阵:")
print(weighted_adjacency_matrix.toarray())visualize_adjacency_matrix(weighted_adjacency_matrix.toarray())

在这段代码中,我们首先使用NetworkX的 from_numpy_matrix 函数将邻接矩阵转换为图对象。然后使用 spring_layout 定义节点的位置,并使用 draw 函数绘制图。最后,我们使用 draw_networkx_edge_labels 函数绘制边的权重。

通过可视化,我们可以清晰地看到图的结构,并直观地了解节点之间的连接关系和权重信息。

邻接矩阵转换为原始边列表

在图数据处理中,有时候我们需要将邻接矩阵转换回原始的边列表形式。这在某些算法和应用中可能很有用,因为一些算法可能更适合使用边列表来表示图。

让我们看看如何编写代码来实现这一转换:

import numpy as npdef adjacency_matrix_to_edges(adjacency_matrix):edges = []for i in range(adjacency_matrix.shape[0]):for j in range(adjacency_matrix.shape[1]):if adjacency_matrix[i, j] != 0:edges.append((i, j, adjacency_matrix[i, j]))return edges# 测试
adjacency_matrix = np.array([[0, 1, 0, 0],[1, 0, 1, 0],[0, 1, 0, 1],[0, 0, 1, 0]], dtype=np.float32)
print("原始邻接矩阵:")
print(adjacency_matrix)edges = adjacency_matrix_to_edges(adjacency_matrix)
print("\n转换后的边列表:")
print(edges)

在这段代码中,我们遍历邻接矩阵的每个元素,如果元素的值不为零,则将其转换为边列表中的一条边。对于有权重的图,我们将权重信息也一并保存在边列表中。

通过这个转换过程,我们可以将邻接矩阵表示的图转换为边列表形式,从而方便进行一些算法的实现和应用。

总结与展望

本文介绍了如何使用Python将原始边列表转换为邻接矩阵,并进行了一系列的扩展和优化,以满足不同场景下的需求。我们从处理无向图和有向图、带权重的边列表,到使用稀疏矩阵优化内存占用,再到图的可视化和邻接矩阵转换为原始边列表,覆盖了图数据处理的多个方面。

在实际应用中,图数据处理是一个非常重要且广泛应用的领域,涉及到网络分析、社交网络、交通规划、生物信息学等诸多领域。掌握图数据处理的技能,能够帮助我们更好地理解和分析复杂的数据结构,从而解决实际问题。

未来,随着数据规模的不断增大和复杂性的增加,图数据处理领域将面临更多挑战和机遇。我们可以期待更多高效、灵活和功能丰富的工具和算法的出现,以应对不断变化的需求和挑战。同时,我们也可以持续学习和探索,不断提升自己在图数据处理领域的能力和水平,为解决实际问题做出更大的贡献。

希望本文对你理解和应用图数据处理有所帮助,也欢迎你进一步深入学习和探索这个领域,为数据科学和工程的发展贡献力量。

在这里插入图片描述


http://www.mrgr.cn/p/10087606

相关文章

计算机DIY之接驳线缆

介绍计算机DIY过程中接驳线缆相关知识,CPU供电、主板主供电、显卡供电、SATA供电、大4pin供电、主板接驳、前面板接驳目录目录 接驳线缆 CPU供电: 主板主供电 显卡供电 SATA供电 大4pin供电 主板接驳 前面板接驳接驳线缆电源插头里还有3条ATX电源专有的线,一条绿色线…

【继承和多态】

闭上眼睛,什么都不听.............................................................................................................. 文章目录 前言 一、【继承】 1.1【继承的概念】 1.2【 继承的定义】 1.2.1【定义格式】 1.2.2【继承关系和访问限定符】 1.2…

硬盘保存及维护基本常识

介绍硬盘使用寿命、硬盘供电、硬盘保存相关小知识点目录目录 硬盘使用寿命简介 硬盘供电简介 硬盘保存简介硬盘使用寿命简介硬盘在连续使用3-4年后就需要注意了(一般为质保期时间后一点), 5-6年后就需要更换硬盘了. 五年左右的时候留意更换机械硬盘,如果不是特备重要的数据,可…

使用restful请求华三模拟器上的设备接口数据

一、resful介绍 RESTful采用C/S模型。RESTful客户端为使用Python、Ruby或Java等编程语言开发出的RESTful客户端程序或脚本。RESTful服务器为网络设备。通过RESTful功能配置和维护设备的过程为: (1) 客户端向服务器发送HTTP/HTTPS请求报文,通过HTTP的方法来操作指定的REST…

芯科SiWx917学习笔记:1-测试Out of Box Demo

实验目的:测试Out of Box Demo 实验环境:Simplicity Studio V5 实验器材:Wireless Starter Kit Mainboard (BRD4002A Rev A06) + SiWG917 Single Band Wi-Fi and BLE 8MB Flash Radio Board (BRD4338A Rev A01) 实验开始: 1. 新建工程:在demos中找到Out of Box Demo(SoC) …

HTML批量文件上传方案——图像预览方式

作者:私语茶馆 1.HTML多文件上传的关键方案 多文件上传包括:文件有效性校验,文件预览、存储和进度展示多个方面,本章节介绍的是文件预览的实现方案。 2.文件上传前预览 2.1.效果 选择文件前: 选择文件后: 2.2.CSS文件代码 StorageCenter.css代码 html {font-family:…

牛客NC371 验证回文字符串(二)【简单 双指针 C++/Java/Go/PHP】

题目 题目链接: https://www.nowcoder.com/practice/130e1a9eb88942239b66e53ec6e53f51 思路 直接看答案,不难参考答案C class Solution {public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可…

合合信息:acge_text_embedding 文本向量化模型登顶 C-MTEB 中文榜单

近期,合合信息的 acge_text_embedding 文本向量化模型在最近的比赛中获得了 MTEB 中文榜单(C-MTEB)榜首!C-MTEB 作为中文文本向量性能的评测标准,以其全面性和权威性在业内享有盛誉值得关注。接下来让我们仔细分析一下…

PID的嵌入式应用

PID 适用范围:二阶以内线性系统。 高阶系统并不适用,但是可以化为二阶系统。 非线性系统也不适用,可以通过其他方式化为线性系统。 优势:应用范围 95% ,不需要对系统进行精细化建模,可以直接上 PID 。…

pwn知识——劫持tcache_perthread_struct(Ubuntu22.04之前)

前言(可忽略) 堆不愧是堆...知识点真的要多用动调查看堆的状态才好理解 tcache_perthread_struct的结构 源码 #define TCACHE_MAX_BINS 64 /* We overlay this structure on the user-data portion of a chunk whenthe chunk is stored in the per-thread cache. */ typedef…

最强AI直播换脸软件,DeepFaceLive下载介绍

DeepFaceLive是一款专注于直播实时换脸的AI软件,使用经过长时间训练的人脸模型替换摄像头中的人脸,能够产生接近电影质量的面部合成效果,提供高保真的视觉体验,在新版本中也支持了图片换脸(视频换脸只能预览,不能保存) DeepFaceLive在直播场景下的效果高度逼真,强大的…

stable-diffusion-webui安装与使用过程中的遇到的error合集

stable-diffusion-webui1.9.2踩坑安装 1. 安装过程1.1 stable-diffusion-webui1.2 在win11或win10系统安装,需修改两个启动脚本1.2.1 修改webui-user.bat1.2.2 修改webui.bat 1.3 双击 webui-user.bat 启动脚本1.3.1 no module xformers. Processing without on fre…

rabbitmq系列03---发布确认

一、发布确认逻辑 生产者将信道设置成 confirm 模式,一旦信道进入 confirm 模式,所有在该信道上面发布的消息都将会被指派一个唯一的 ID (从 1 开始),一旦消息被投递到所有匹配的队列之后,broker 就会发送一个确认给生产者 (包含消息的唯一 ID),这就使得生产者知道消息已经…

生成式AI原理技术详解(一)——神经网络与深度学习

本文主要介绍了生成式AI的最新发展,提到了GPT-5和AI软件工程师在行业中的影响,指出AI技术进步对国家竞争和个人职业发展的潜在影响。 未来已来 最近有两则新闻: sam altman自曝GPT-5细节,公开宣称GPT-5提升将非常大,任…

玩转手机在AidLux上安装宝塔面板

AidLux,手机不用刷机、不用root,直接在手机应用市场就能下载使用。 1.4G的应用包,看起来挺大的,那是因为内嵌了一套完整的AIoT应用开发和部署平台。 不仅Android手机可以玩,华为的Harmony系统也可以使用。 使用它最主…

关于ida f5时报错lumina无法连接到云服务器的问题

在用ida的时候不知道怎么回事突然就f5不了了,报错 Decompilation failure: 4005F7: cloud: Server is not available Please refer to the manual to find appropriate actionslumina: connect: 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。4005F…

在Elasticsearch 7.9.2中安装IK分词器并进行自定义词典配置

Elasticsearch是一个强大的开源搜索引擎,而IK分词器是针对中文文本分析的重要插件。本文将引导您完成在Elasticsearch 7.9.2版本中安装IK分词器、配置自定义词典以及验证分词效果的全过程。 步骤一:下载IK分词器 访问IK分词器的GitHub发布页面&#xf…

排队叫号取号投屏语音播报小程序开源版开发

排队叫号取号投屏语音播报小程序开源版开发 多场景排队叫号系统,支持大屏幕投屏,语音播报叫号,可用于餐厅排队取餐、美甲店排队取号、排队领取、排队就诊、排队办理业务等诸多场景,助你轻松应对各种排队取号叫号场景。 功能特性…

Unity AssetsBundle打包

为什么要使用AssetsBundle包 减少安装包的大小 默认情况下,unity编译打包是对项目下的Assets文件夹全部内容进行压缩打包 那么按照这个原理,你的Assets文件夹的大小将会影响到你最终打包出的安装包的大小,假如你现在正在制作一个游戏项目&…

SQL217 对所有员工的薪水按照salary降序进行1-N的排名

示例: drop table if exists `salaries` ; CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL, `salary` int(11) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`from_date`)); INSERT INTO salaries VALUES(10001,88958,2002-…