nx.adjacency_matrix计算邻接矩阵与真实结果不一致的解决
作者:小猪上吊ing 发布时间:2023-12-06 14:23:56
问题描述
我自己根据edgelist计算的邻接矩阵,与调用networkx.adjacency_matrix(g)返回的结果不一样,经过调试发现了问题原因以及解决办法,记录如下。
原来的代码
edgelist = [
(0, 1),
(1, 3),
(2, 4),
(1, 5),
(1, 3),
(5, 5),
(1, 3)
]
"""由于nx.MultiGraph()可累计多条重复边作为权重,所以(1,3)出现3次权重是3"""
g = nx.MultiGraph() # 无向多边图
g.add_edges_from(edgelist)
adj = sp.lil_matrix(nx.adjacency_matrix(g))
print(adj.todense())
实际运行输出
[[0 1 0 0 0 0]
[1 0 3 0 0 1]
[0 3 0 0 0 0]
[0 0 0 0 1 0]
[0 0 0 1 0 0]
[0 1 0 0 0 1]]
理论结果
[[0 1 0 0 0 0]
[1 0 0 3 0 1]
[0 0 0 0 1 0]
[0 3 0 0 0 0]
[0 0 1 0 0 0]
[0 1 0 0 0 1]]
节点id从0开始。对于边(1,3),矩阵的第二行第四列应当为权重3,可以看到实际运行输出结果中,3却出现在了第二行第三列!
调试过程
查看了networkx.adjacency_matrix()的源代码,其中有一条说明如下:
def adjacency_matrix(G, nodelist=None, weight='weight'):
"""Return adjacency matrix of G.
Parameters
----------
G : graph
A NetworkX graph
nodelist : list, optional
The rows and columns are ordered according to the nodes in nodelist.
If nodelist is None, then the ordering is produced by G.nodes().
weight : string or None, optional (default='weight')
The edge data key used to provide each value in the matrix.
If None, then each edge has weight 1.
...
...
"""
return nx.to_scipy_sparse_matrix(G, nodelist=nodelist, weight=weight)
第二个参数的说明需要格外注意!对于nodelist这个参数,说明是这样的:邻接矩阵的行和列的排序按照nodelist中节点顺序来!如果不传这个参数,默认是按照传进来的图G调用G.nodes()时返回的节点的顺序!
所以我查看了我传进去的图g的节点默认顺序是什么样的:
edgelist = [
(0, 1),
(1, 3),
(2, 4),
(1, 5),
(1, 3),
(5, 5),
(1, 3)
]
"""由于nx.MultiGraph()可累计多条重复边作为权重,所以(1,3)出现3次权重是3"""
g = nx.MultiGraph() # 无向多边图
g.add_edges_from(edgelist)
print(g.nodes())
adj = sp.lil_matrix(nx.adjacency_matrix(g))
print(adj.todense())
运行结果居然:
[0, 1, 3, 2, 4, 5]
[[0 1 0 0 0 0]
[1 0 3 0 0 1]
[0 3 0 0 0 0]
[0 0 0 0 1 0]
[0 0 0 1 0 0]
[0 1 0 0 0 1]]
图g的节点列表居然不是按照从小到大的顺序排列,id为3的节点居然是第三而不是第四位序,这就是为什么边(1,3)的权重会写在矩阵的第三列…因为矩阵第三列对应节点3!
那…为什么图g的节点列表不是排好序的,为什么是[0, 1, 3, 2, 4, 5]这个顺序?
因为:加新边sdd_edges的时候会自动加新节点!!!
边(0,1)加进去的时候,节点列表是[0,1];加边(1, 3)的时候,节点列表[0,1,3];…。所以节点默认列表的顺序,跟你加新边时候哪个节点先出现有关系。
解决方案
那么在添加新边之前,先把节点按id从小到大顺序排好同意添加,就可以了。
具体就是:在g.add_edges_from(edgelist)操作之前,先把edgelist中的节点抽取出来按顺序排好,用操作g.add_nodes_from()把节点统一添加进图g中。修改后的代码如下:
修改后的代码
edgelist = [
(0, 1),
(1, 3),
(2, 4),
(1, 5),
(1, 3),
(5, 5),
(1, 3)
]
"""由于nx.MultiGraph()可累计多条重复边作为权重,所以(1,3)出现3次权重是3"""
g = nx.MultiGraph() # 无向多边图
""" 节点id按照顺序排!!否则生成的邻接矩阵不一样 """
nodeset = sorted(set(itertools.chain(*edgelist)))
g.add_nodes_from(nodeset)
g.add_edges_from(edgelist)
print(g.nodes())
adj = sp.lil_matrix(nx.adjacency_matrix(g))
print(adj.todense())
修改代码后的运行结果
[0, 1, 2, 3, 4, 5]
[[0 1 0 0 0 0]
[1 0 0 3 0 1]
[0 0 0 0 1 0]
[0 3 0 0 0 0]
[0 0 1 0 0 0]
[0 1 0 0 0 1]]
函数说明
nodeset = sorted(set(itertools.chain(*edgelist)))这行的功能,是把edgelist中的元素展开,去重,按顺序排序。分开演示就是:
edgelist = [
(0, 1),
(1, 3),
(2, 4),
(1, 5),
(1, 3),
(5, 5),
(1, 3)
]
""" 把edgelist中的每个(a,b)元素打平成a,b """
nodes = list(itertools.chain(*edgelist))
print(nodes)
# 输出:
# [0, 1, 1, 3, 2, 4, 1, 5, 1, 3, 5, 5, 1, 3]
""" 利用set元素唯一的性质,将重复元素去重 a,a => a """
nodeset = set(nodes)
print(nodeset)
# 输出:
# {0, 1, 2, 3, 4, 5}
""" set中的元素是无序、非空、唯一的,所以对set再sorted一下,确保顺序是对的 """
nodeset = sorted(nodeset)
print(nodeset)
# 输出:
# [0, 1, 2, 3, 4, 5]
来源:https://blog.csdn.net/yingluo54/article/details/113325108
猜你喜欢
- 实现功能:删除当前目录下,除保留目录和文件外的所有文件和目录#!bin/env pythonimport osimport os.pathi
- 本文实例讲述了php实现图片转换成ASCII码的方法。分享给大家供大家参考。具体如下:php图片转换成ASCII码,转换后可以直接通过字符串
- 安装库位置和显示方式简单总结:一、位置的不同 1.自带库在环境的 lib\\os.py&nb
- 报错:Uncaught SyntaxError: Unexpected token o in JSON at position 1at JS
- pytorch做标准化利用transforms.Normalize(mean_vals, std_vals),其中常用数据集的均值方差有:i
- 绪论java默认精度是毫秒级别的,生成的时间戳是13位,而python默认是10位的,精度是秒。那么python是如何生成13位时间戳,以及
- 在上一篇博客中,我们学习了python遗传算法包geatpy。并用它展示了一个不带约束的单目标规划问题,对往期内容感兴趣的同学可以参考👇:链
- 本文实例讲述了pymongo实现控制mongodb中数字字段做加法的方法。分享给大家供大家参考。具体分析如下:这个非常实用,比如我们需要给文
- CSS写法:overflow-y:visible本代码适用平台:IE6,IE7演示:<textarea style="wid
- Pycharm作为一款强力的Python IDE,在使用过程中感觉一直找不到全面完整的参考手册,因此决定对官网的Pycharm教程进行简要翻
- 2020年11月22日最新分享pycharm激活码,这次分享的pycharm激活码适用pycharm2020最新版及pycharm2019、
- 使用apidoc管理RESTful风格Flask项目接口文档方法apidoc项目地址flask扩展包地址文档示例地址1.安装nodejssu
- python提供了4种方式来满足进程间的数据通信1. 使用multiprocessing.Queue可以在进程间通信,但不能在Pool池创建
- 在开发一些需要网络通信的应用中,经常会用到各种网络协议进行通信,博主在开发实验室的机器人的时候就遇到了需要把机器人上采集到的图片传回服务器进
- 我有个MM在网上面安了家,想做一个关于特效的网站。她虽然懂一点网页制作,但是她的机器配置比较低,有时为了反复试验页面上一些特殊效果,而打开D
- 以前跟同事开玩笑时说过,我们遇到的用户在访谈测试过程中的表现基本上就三种类型,发泄型,赞美型和实话实说型。发泄型用户通常是在产品的使用过程中
- 在近几年Python的呼声越来越高,很多刚开始起步想要学习编程的朋友都会犹豫要不要选择学习Python,毕竟作为人工智能时代的首选语言这个诱
- 在实现贪吃蛇游戏时,首先需要使用python内置的turtle模块来实现创建游戏窗体与键盘按键的监听工作,然后使用freegames模块进行
- 现在很多地方都需要用到关键词过滤功能。比如一般的服务器都不允许一些词出现在网页上,站长有时候会对在本网站发布信息的内容进行一个广告过滤等。雨
- 前言本文给大家详细介绍了解决php-fpm.service not found问题的相关内容,文中介绍的非常详细,下面来一起看看详细的介绍: