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
имеют разные имена, поэтому команда, которую вы использовали, не будет работать.