NetworkX:在Python中连接两个单独图形的节点 [英] NetworkX: connect nodes of two separate graphs in Python

查看:562
本文介绍了NetworkX:在Python中连接两个单独图形的节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题与尝试使用NetworkX为相互依赖的网络建立模型有关.有专用的软件包(例如 Pymnet ),但它们没有看起来像NetworkX一样灵活.顺便说一句,我想给NetworkX最后一次机会.

因此,假设我们有2个单独的图形G1和G2,它们在同一图中绘制:

import networkx as nx
import matplotlib.pyplot as plt

G1=nx.barabasi_albert_graph(3, 2) #n=3, m=2 (number of initial links)
G2=nx.barabasi_albert_graph(3, 2)
pos1=nx.spring_layout(G1)
pos2=nx.spring_layout(G2)
nx.draw_networkx(G1,pos=pos1,node_color='red') #G1 is red
nx.draw_networkx(G2,pos=pos2,node_color='green') #G2 is green

现在,如果我们尝试将G1的节点0与G2的节点1连接:

G1.add_edge(G1.nodes()[0], G2.nodes()[1]) 

我们没有收到任何错误,但是如果您再次绘制图形,则图像与以前完全一样.而且,如果您检查边缘的数量,则会得到与以前相同的结果:

In[17]: G1.edges()
Out[17]: [(0, 1), (0, 2), (1, 2)]

In[18]: G2.edges()
Out[18]: [(0, 2), (1, 2)]

表示基本上没有添加边缘,或者没有添加边缘,也没有显示边缘,或者添加了边缘,但是由于它从一个图形延伸到另一个图形,因此它不属于其中任何一个.

您如何建议在不借助其他软件包的情况下在NetworkX中创建从G1到G2的互连?

解决方案

我认为最基本的问题是,对于networkx如何从图中看图,您有一个不同的概念.我相信您认为图的节点是某些node类的对象,这些节点本身本质上具有一些属性,可以说明它们的位置.不是这种情况.没有特殊的node类.一个图可以将任何可散列的对象作为其节点,因为实际上,图只是一个奇特的dict,其键就是我们所谓的节点.

图形G1的节点 是整数0、1和2.G2具有完全相同的节点.您添加的新边介于G1.nodes()[0]中的任何整数和G2.nodes()[1]中的任何整数之间.在您的示例中,我相信G1已经具备了这一优势.

您分别创建了两个不同的字典pos1pos2(它们具有相同的键-形成两个图的节点的整数值).这些命令说出应在何处绘制节点.您已经告诉它使用pos1绘制G1.因此,它将在pos1[0]处的 节点的圆放在1处,同样在1和2处的圆.然后,当您以后告诉它使用pos1绘制G时,它将精确地执行同样的事情.

您可能想做的是在重命名后创建一个新图,其节点由G1和G2的节点组成,以使它们不是相同的节点.这是通过union(interdependent networks with NetworkX. There are dedicated packages (such as Pymnet), but they don't seem as flexible as NetworkX. And by the way, I wanted to give NetworkX one last chance.

So, let's say we have 2 separate graphs, G1 and G2, which we plot in the same figure:

import networkx as nx
import matplotlib.pyplot as plt

G1=nx.barabasi_albert_graph(3, 2) #n=3, m=2 (number of initial links)
G2=nx.barabasi_albert_graph(3, 2)
pos1=nx.spring_layout(G1)
pos2=nx.spring_layout(G2)
nx.draw_networkx(G1,pos=pos1,node_color='red') #G1 is red
nx.draw_networkx(G2,pos=pos2,node_color='green') #G2 is green

Now, if we attempt to connect node 0 of G1 with node 1 of G2:

G1.add_edge(G1.nodes()[0], G2.nodes()[1]) 

we don't get any error, but if you plot the graphs again, the image is exactly as before. And if you check the number of edges you get the same results as before:

In[17]: G1.edges()
Out[17]: [(0, 1), (0, 2), (1, 2)]

In[18]: G2.edges()
Out[18]: [(0, 2), (1, 2)]

meaning that the edge was basically not added, or it was added and is not displayed, or it was added, but because it runs from one graph to another, it doesn't belong to any of them.

How do you suggest to create this interconnection from G1 to G2 in NetworkX, without resorting to other packages?

解决方案

I think the fundamental issue is that you've got a different concept for how networkx thinks of a graph from what it is. I believe you're thinking that the nodes of the graph are objects of some node class that the nodes themselves intrinsically have some attribute saying what their position is. This is not the case. There is no special node class. A graph can have any hashable object as its nodes because really, a graph is just a fancy dict whose keys are what we call nodes.

The nodes of your graph G1 are the integers 0, 1, and 2. G2 has exactly the same nodes. The new edge you've added is between whatever integer is in G1.nodes()[0] and whatever integer is in G2.nodes()[1]. In your example I believe G1 already has that edge.

Separately, you've created two different dicts pos1 and pos2 (which have the same keys - the integer values that form the nodes of the two graphs). These dicts say where the nodes should be plotted. You've told it to plot G1 using pos1. So it puts the circle for the node that is 0 at pos1[0] and similarly for 1 and 2. Then when you later tell it to plot G using pos1 it's going to do exactly the same thing.

What you probably want to do is create a new graph whose nodes consist of the nodes of G1 and of G2, after renaming so that they aren't the same nodes. This is done by union (see documentation.)

G = union(G1, G2, rename=('G1-', 'G2-'))

Then add the edge, noting that the nodes in G have different names, so the command you used won't quite work.

这篇关于NetworkX:在Python中连接两个单独图形的节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆