如何阻止Networkx在无向图中将节点的顺序从(u,v)更改为(v,u)? [英] How to stop Networkx from changing the order of nodes from (u,v) to (v,u) in an undirected Graph?

查看:208
本文介绍了如何阻止Networkx在无向图中将节点的顺序从(u,v)更改为(v,u)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是对我的 this的输入,diGraph产生以下结果

在此有向图中,节点24和28的入度和出度之和为1.但是,我希望箭头从节点24指向28,类似于交通网络中可能存在单向流动的箭头.从24点到28点的流量有不同的路由.Networkx的diGraph创建的方向并不代表我的真实系统.因此,我不想使用diGraph.

解决方案

否,这对于networkx是不可能的.即使您尝试使用 OrderedGraph ,最好的是

一致的订单而不是特定的订单.

当您选择使用代替,您明确指出,它是无向,所以方向没有关系,这将是低效networkx保存有关方向的信息.在基础数据结构中,它不保存边缘列表.而是保存一个字典,该字典说明每个节点的邻居是什么(因此不会存储有关用户输入顺序的信息).重建EdgeView时,它会使用此字典,因此有关用户输入方式的所有信息都已丢失.

如果您需要这样做,我建议您使用DiGraph.如果您需要它是有向的(跟踪边缘的顺序)的混合体,而又仍然是无向的(将每个边缘都具有两个方向进行处理),我建议将边缘的方向与networkx图分开存储.

This is a follow up to my previous question.

The question is on the order in which the nodes are saved in the edge list while creating an undirected graph. I have a graph created using the below code. A simple graph is created and new nodes and edges are added between two nodes that already exist.

import networkx as nx
import matplotlib.pyplot as plt
from pprint import pprint

G = nx.OrderedGraph()
head_nodes = range(0, 9)
tail_nodes = range(1, 10)
edge_ls = list(zip(head_nodes, tail_nodes))
G.add_nodes_from(range(0, 10))
G.add_edges_from(edge_ls)

head = 0
tail = 1
G.remove_edge(head, tail)
Nnodes = G.number_of_nodes()
newnodes = [head, Nnodes+1, Nnodes+2, Nnodes+3, tail] # head and tail already exists
newedges = [(x, y) for x, y in zip(newnodes[0:len(newnodes)-1], newnodes[1:len(newnodes)])]
G.add_edges_from(newedges)
I = nx.incidence_matrix(G)
pprint(I)
pprint(G.edges())
nx.draw(G, with_labels=True)
plt.show()

The output of using an undirected graph is:

EdgeView([(0, 11), (1, 2), (1, 13), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (11, 12), (12, 13)])

From the output, we can observe that the edge that was created using G.add_edge(13,1) is displayed as (1,13). I understand this happens because the graph is undirected.

When a directed graph (G.OrderedDiGraph)is used, the output is:

EdgeView([(0, 11), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (11, 12), (12, 13), (13, 1)])

(13, 1) is as I expected the result to be.

However, I am interested to know if there is a particular way in which the nodes can be named so that one can avoid Networkx from reordering the nodes from (u,v) , which is the user input, to (v,u) in an undirected graph.

EDIT: I am avoiding the use of diGraph because there are inputs like this for which diGraph yields the following result

In this directed graph, nodes 24 and 28 have a sum of indegree and outdegree to be 1. However, I want the arrows to be directed from node 24 to 28, similar to unidirectional flow in a traffic network where there could be different routes for the traffic to flow from point 24 to point 28. The directions created by diGraph of Networkx doesn't represent my real system. Therefore, I don't want to use diGraph.

解决方案

No, this is not possible with networkx. Even if you try to use an OrderedGraph, the best you will get is

a consistent order not a particular order.

When you choose to use a Graph instead of a DiGraph, you are explicitly stating that it is undirected, so direction does not matter, and it would be inefficient for networkx to save information about the direction. In the underlying data structure, it doesn't save an edge list. Rather it saves a dict which says what the neighbors of each node are (so no information is stored about the order the user entered it in). When it reconstructs an EdgeView, it uses this dict, so all information about how the user entered it is already lost.

If you need to do this, I would recommend using a DiGraph. If you need it to be some hybrid of directed (tracking the order of an edge) while still undirected (treating each edge as having both directions), I would recommend storing the edge directions separately from the networkx graph.

这篇关于如何阻止Networkx在无向图中将节点的顺序从(u,v)更改为(v,u)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆