2017-04-02 6 views
0

Je crée un graphique à partir d'une matrice d'adjacence pondérée de la taille de 222 x 222 nœuds. Tous les poids donnés dans la matrice sont des nombres à virgule flottante compris entre 0.42757498546089029 et 1.6671726002927263. nx.minimum_spanning_tree(G, weight = "weight") méthode me donne la première image ci-dessous, pendant ce temps, si je multiplie toutes les valeurs de la matrice par 100.0 la même méthode me donne la deuxième image. Cela ne se produit pas en traçant la même chose avec igraph. La documentation de Networkx est silencieuse sur les problèmes de précision. Savez-vous pourquoi cela pourrait se produire? Minimum spanning tree of a graph with potential precision issues Minimum spanning tree of a graphNetworkx Minimum Spanning Tree - problèmes de précision?

Code NetworkX:

G=nx.from_numpy_matrix(M) 
G1=nx.minimum_spanning_tree(G, weight = "weight") 

labels = {i : node_names[i][1] for i in G1.nodes()} 
colors = {i : node_attributes[labels[i]] for i in G1.nodes()} 
for i in G1.nodes(): 
    G1.node[i]["color"] = 'white' 
    G1.node[i]["style"] = "filled"  
    G1.node[i]["fillcolor"] = colors[i] 
color=nx.get_node_attributes(G1,'color') 
fillcolor=nx.get_node_attributes(G1,'fillcolor') 
H=nx.relabel_nodes(G1,labels) 
nx.draw(H, scale=30, nodelist=H.nodes(), linewidths=0, with_labels = True, node_size=500,font_size=8) 

Code igraph:

g = igraph.Graph.Weighted_Adjacency(M.tolist()) 
    for i, v in enumerate(g.vs): 
     v["color"] = colors[i] 
     v["label"] = labels[i] 
     v["frame_color"] = colors[i] 
     v["label_size"] = 10 
     v["size"] = 26 
    G = g.spanning_tree(weights='weight', return_tree=True) 
    G.to_undirected() 
    igraph.plot(G, labels=False, bbox = (900, 900), margin=40, loops=False 

) 
+0

Ces algorithmes utilisent des nombres à virgule flottante Python et héritent de la précision de ces opérations (les flottants sont de 53 bits selon https://docs.python.org/3/tutorial/floatingpoint.html) – Aric

+0

Peut-être pouvez-vous poster un exemple Nous pouvons donc voir quel est le problème? – Aric

+1

Etes-vous sûr que les arbres sont différents? Je crois que seule la disposition diffère, mais la topologie est la même, du moins au premier coup d'œil. – DyZ

Répondre

-1

Ce que vous voyez est le comportement attendu et non un problème de précision du tout. Comme son nom l'indique, la disposition du ressort «simule» l'action des ressorts entre vos nœuds sur leurs positions. Les positions des noeuds sont initialisées sur un cercle, puis la force des ressorts est appliquée à vos noeuds pendant un certain nombre d'itérations (50 par défaut). Avec des poids de connexion faibles, vos nœuds resteront plus ou moins sur le cercle (premier cas), avec des poids forts, vos nœuds graviteront vers le centre (deuxième cas).

En igraph, par défaut, le graphe non-pondéré est utilisé pour calculer la disposition et vous devez donner explicitement le poids au graphe. Je suppose que vous avez peut-être tracé le graphique sans spécifier le paramètre "poids".

+0

Pourquoi soupçonnez-vous que j'ai tracé un graphique sans poids pour igraph? La réponse est vraie pour networkx et on peut voir que networkx utilise le spring comme layout par défaut. Cependant, igraph n'utilise pas le ressort par défaut. – Leukonoe

+1

En ce qui concerne le réglage du paramètre de poids: juste une estimation. En ce qui concerne la mise en page par défaut: igraph utilise par défaut Kamada-Kawei pour les petits graphiques, et Fruchterman-Reingold (aka disposition du printemps) pour les graphes plus grands. IIRC, le seuil est d'environ 1000 nœuds. – Paul

+0

Ok, donc igraph utilise la disposition de printemps, et le poids est spécifié comme 'G = g.spanning_tree (poids = 'poids', return_tree = True)' donc je pense que j'ai donné les poids à igraph MST. Bien que pourquoi alors 'G.is_weighted()' renvoie 'False'? Est-il possible que les poids n'aient pas été pris en compte? – Leukonoe