2014-09-11 6 views
1

J'ai certaines données relationnelles que je veux charger dans NetworkX, et finalement le convertir en un graphique pondéré.DiagramGraph() en graphe() avec des poids de bord non additionnés, comment additionner des poids?

Par nature, les arêtes relationnelles sont dirigées et pondérées, et je veux conserver l'attribut weight pendant que je transforme le graphe. En utilisant le code suivant, je suis en mesure de charger les bords relationnels à partir d'un dictionnaire à un MultiDiGraph():

MG = nx.MultiDiGraph([(i['source'],i['target']) for i in edges ]) 

Puis, je convertir le MultiDiGraph() à un DiGraph(), et se condensent des bords en double en une seule et mettre à jour le poids de bord pour chaque bord:

G = nx.DiGraph() 
for (u,v) in MG.edges(): 
    G.add_edge(u, v, weight=len(MG[u][v])) 

a partir de là, je veux convertir le DiGraph() à un Graph(), et encore retenir et condenser le poids de bord:

g = G.to_undirected() 

Mais le problème que j'ai, c'est qu'il semble juste conserver le premier poids de bord trouvé pour 'a' -> 'b' ou 'b' -> 'a'.

Ce que je veux, c'est que la somme de ces arêtes soit maintenue comme un poids quand on va vers un bord non orienté.

est Ci-dessous un échantillon montrent ce que je travaille avec:

# relational directed edge data containing duplicate edges 
edges = [{'source': 'a', 'target': 'b'}, 
     {'source': 'a', 'target': 'b'}, 
     {'source': 'a', 'target': 'b'}, 
     {'source': 'b', 'target': 'a'}, 
     {'source': 'a', 'target': 'c'}, 
     {'source': 'c', 'target': 'a'}, 
     {'source': 'c', 'target': 'd'}, 
     {'source': 'c', 'target': 'd'}, 
     {'source': 'd', 'target': 'c'}] 

# load edges into a MultiDiGraph to maintain direction and duplicate edges 
MG = nx.MultiDiGraph([(i['source'],i['target']) for i in edges ]) 

MG.edges(data=True) = [('a', 'c', {}), 
         ('a', 'b', {}), 
         ('a', 'b', {}), 
         ('a', 'b', {}), 
         ('c', 'a', {}), 
         ('c', 'd', {}), 
         ('c', 'd', {}), 
         ('b', 'a', {}), 
         ('d', 'c', {})] 

# convert MultiDiGraph to a DiGraph and update edge weight 
G = nx.DiGraph() 
for (u,v) in MG.edges(): 
    G.add_edge(u, v, weight=len(MG[u][v])) 

G.edges(data=True) = [('a', 'c', {'weight': 1}), 
         ('a', 'b', {'weight': 3}), 
         ('c', 'a', {'weight': 1}), 
         ('c', 'd', {'weight': 2}), 
         ('b', 'a', {'weight': 1}), 
         ('d', 'c', {'weight': 1})] 

# convert DiGraph to a Graph, but edge weight not updated as sum, but first value 
g = G.to_undirected() 

g.edges(data=True) = [('a', 'c', {'weight': 1}), 
         ('a', 'b', {'weight': 1}), 
         ('c', 'd', {'weight': 1})] 

En fin de compte, je veux le poids de bord dans le graphe non orienté être comme suit, mais je ne peux pas savoir si c'est une option avec G.to_undirected ou comment faire:

g.edges(data=True) = [('a', 'c', {'weight': 2}), 
         ('a', 'b', {'weight': 4}), 
         ('c', 'd', {'weight': 3})] 

Répondre

1

G.to_undirected() ne peut pas être utilisé pour contrôler les données les bords non orientés obtenir, voir networkx docs

Vous pouvez plutôt effectuer les opérations suivantes:

import networkx as nx 

G = nx.DiGraph() 
G.add_edges_from([('a', 'c', {'weight': 1}), 
        ('a', 'b', {'weight': 3}), 
        ('c', 'a', {'weight': 1}), 
        ('c', 'd', {'weight': 2}), 
        ('b', 'a', {'weight': 1}), 
        ('d', 'c', {'weight': 1})]) 

print G.edges(data=True) 

g = nx.Graph() 
g.add_edges_from(G.edges_iter(), weight=0) 

print g.edges(data=True) 

for u, v, d in G.edges_iter(data=True): 
    g[u][v]['weight'] += d['weight'] 

print g.edges(data=True) 

Fondamentalement, vous créez un nouveau undirected graphique g et le remplir avec toutes les arêtes du graphe orienté G. À ce stade, vous initialisez aussi les poids des bords à 0. Enfin, vous ajoutez simplement les poids à chaque bord dans le graphique non orienté. Notez que dans le graphique non orienté edge (u, v) est le même que (v, u).

+0

Je suis à votre façon, mais si j'ajoute les mêmes bords, le résultat n'est pas bon. Par exemple, si j'ajoute '('a', 'c', {'weight': 1})' une de plus, 'print g.edges (data = True)' sera '[('a', 'c ', {' weight ': 2}), (' a ',' b ', {' weight ': 4}), (' c ',' d ', {' weight ': 3})] '. C'est la même sortie. Ne devrait-il pas être '[('a', 'c', {'weight': 3}), ('a', 'b', {'weight': 4}), ('c', 'd ', {' weight ': 3})] '? –

Questions connexes