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

введите описание изображения здесь

Теперь, если мы попытаемся соединить узел 0 из G1 с узлом 1 из G2:

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)]

Это означает, что ребро в основном не было добавлено, или оно было добавлено и не отображается, или оно было добавлено, но поскольку оно работает от одного графика к другому, оно не принадлежит ни одному из них.

Как вы предлагаете создать это соединение между G1 и G2 в NetworkX, не прибегая к другим пакетам?

1 ответ

Решение

Я думаю, что фундаментальная проблема заключается в том, что у вас есть другое представление о том, как networkx думает о графе с того, чем он является. Я полагаю, вы думаете, что узлы графа являются объектами некоторых node Класс, в котором сами узлы имеют некоторый атрибут, говорящий о том, какова их позиция. Это не вариант. Там нет специального node учебный класс. Граф может иметь любой хешируемый объект в качестве его узлов, потому что на самом деле граф - это просто причудливый диктант, ключи которого - это то, что мы называем узлами.

Узлами вашего графа G1 являются целые числа 0, 1 и 2. G2 имеет точно такие же узлы. Новое ребро, которое вы добавили, находится между любым целым числом в G1.nodes()[0] и что бы ни было целое число в G2.nodes()[1], В вашем примере я считаю, что G1 уже имеет это преимущество.

Отдельно вы создали два разных диктанта pos1 а также pos2 (которые имеют одинаковые ключи - целочисленные значения, которые образуют узлы двух графиков). Эти дикты говорят, где должны быть построены узлы. Вы сказали это для сюжета G1 с помощью pos1, Таким образом, он помещает круг для узла, который равен 0 в pos1[0] и аналогично для 1 и 2. Затем, когда вы позже скажете, что это сюжет G с помощью pos1 это будет делать то же самое.

Вероятно, вы захотите создать новый граф, узлы которого состоят из узлов G1 и G2 после переименования, чтобы они не были одинаковыми узлами. Это сделано union ( см. документацию.)

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

Затем добавьте ребро, отметив, что узлы в G имеют разные имена, поэтому команда, которую вы использовали, не будет работать.

Другие вопросы по тегам