2015-09-18 9 views
12

sagen, dass ich zwei NetworkX Graphen haben, G und H:Kombinieren (Join) NetworkX Graphen

G=nx.Graph() 
fromnodes=[0,1,1,1,1,1,2] 
tonodes=[1,2,3,4,5,6,7] 
for x,y in zip(fromnodes,tonodes): 
    G.add_edge(x,y) 

H=nx.Graph() 
fromnodes=range(2,8) 
tonodes=range(8,14) 
for x,y in zip(fromnodes,tonodes): 
    H.add_edge(x,y) 

Was ist der beste Weg, um die beiden NetworkX Graphen zu verbinden?

Ich möchte die Knotennamen beibehalten (beachten Sie die gemeinsamen Knoten, 2 bis 7). Als ich nx.disjoint_union(G,H) verwendet, dies ist nicht geschehen:

>>> G.nodes() 
[0, 1, 2, 3, 4, 5, 6, 7] 
>>> H.nodes() 
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] 
>>> Un= nx.disjoint_union(G,H) 
>>> Un.nodes() 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] 
# 

Die H Knoten Etiketten geändert wurden (nicht das, was ich will). Ich möchte die Graphen an den Knoten mit der gleichen Nummer verbinden.

Hinweis. Dies ist kein Duplikat von Combine two weighted graphs in NetworkX.

+1

Was möchten Sie tun, wenn in beiden eine Kante vorhanden ist? Sollte es eine doppelte Kante werden? oder nur eine einzelne Kante? – Joel

+0

@Joel hmm Ich interessiere mich für beide Fälle. Sagen wir Single Edge. – atomh33ls

+1

Der Ein-Rand-Fall wird mit dem Code, den Sie geschrieben haben, in Ordnung gebracht. Der Multidge-Fall, den Sie gerade tun 'U = nx.MultiGraph()' – Joel

Antwort

23

Die Funktion, die Sie suchen ist compose.

import networkx as nx 
G=nx.Graph() 
G.add_edge(1,2) 
H=nx.Graph() 
H.add_edge(1,3) 
F = nx.compose(G,H) 
F.edges() 
> [(1, 2), (1, 3)] 

Es gibt auch andere Möglichkeiten, die symmetric difference, intersection zu tun, ...

Wenn Sie mehrere Graphen haben miteinander zu verbinden, können Sie compose_all, die nur um compose for-Schleife umschließt.

+0

Wie erzwingen, dass alle Graphen die gleiche Position für Knoten mit demselben Label haben, wenn wir alle mit' nx.draw_networkx (G) nx.draw_networkx (H) nx.draw_networkx (F) plt.show() '? Ich meine, die Koordinaten des Knotens "1" sollten für alle 3 Graphen gleich sein. – Sigur

+0

@Sigur Die Plotbefehle nehmen einen (optionalen) Eingang 'pos' wie' nx.draw_networkx (G, pos = pos) '. 'pos' ist ein Wörterbuch, dessen Schlüssel die Knoten sind und deren Werte ihre (x, y) -Koordinaten sind. Sie können es selbst definieren oder über einige der 'Layout'-Befehle. z. B. 'pos = nx.spring_layout (F)'. – Joel

+0

Ich möchte zuerst das Layout verwenden, um eine gute Anzeige zu erhalten, und dann dieselben Koordinaten verwenden, wenn ich neue Kanten hinzufüge und erneut in einem anderen Fenster plotte. Mehr oder weniger möchte ich eine Abfolge von Zahlen erzeugen, um eine Art Zeitlinie für Graphen zu zeigen. – Sigur

4

Das hat es getan.

U=nx.Graph() 
    U.add_edges_from(G.edges()+H.edges()) 
    U.add_nodes_from(G.nodes()+H.nodes()) #deals with isolated nodes 

oder Attribute den Rand Erhaltung:

U.add_edges_from(G.edges(data=True)+H.edges(data=True)) 

und auch erhalten die Knotenattribute:

U.add_nodes_from(G.nodes(data=True)+H.nodes(data=True))