使用Networkx(Python)进行图形遍历
我正在使用Networkx来管理依赖关系图。 假设我有一个图表,每个字母代表一个服务器使用Networkx(Python)进行图形遍历,python,networkx,Python,Networkx,我正在使用Networkx来管理依赖关系图。 假设我有一个图表,每个字母代表一个服务器 >>> G = nx.Graph() >>> G.add_edge("A","B") >>> G.add_edge("A","H") >>> G.add_edge("H","C") >>> G.add_edge("B","C") >>> G.add_edge("B","D") A
>>> G = nx.Graph()
>>> G.add_edge("A","B")
>>> G.add_edge("A","H")
>>> G.add_edge("H","C")
>>> G.add_edge("B","C")
>>> G.add_edge("B","D")
A
/ \
H B
/ / \
C C D
在这里我们可以看到,在开始A之前,我们需要开始H和B,开始H,我们需要开始C,然后开始B,我们需要开始C和D
通过稍微摆弄一下Networkx,我发现我可以通过进行dfs遍历来实现这一点
print nx.dfs_successors(G,"A")
{A:[H,B], H:[C], B:[D] }
但我对这种方法有一个问题。正如您所看到的,当树中有两个相同的字母时,Networkx只选择将其中一个放入最终结构中(这是正确的),但我需要完整的结构
如何强制Networkx添加到结构B:[D,C]
我想通过这样做来精确说明这一点
>>> nx.dfs_successors(G,"B")
{'B': ['C', 'D']}
所以一切都是“内部”正确的,只是dfs_的继任者没有以我希望的方式显示它
谢谢你接受了你的代码,你的图表并没有像你期望的那样出来。如果您这样做:
import pylab as p
import networkx as nx
G = nx.Graph()
G.add_edge("A","B")
G.add_edge("A","H")
G.add_edge("H","C")
G.add_edge("B","C")
G.add_edge("B","D")
nx.draw(G)
p.show()
您将看到以下图形:
这是由于G的逻辑造成的。添加边缘(“A”、“B”)
:
G
没有id为“A”的节点,则添加它G
没有id为“B”的节点,则添加它import pylab as p
import networkx as nx
class Node(object):
nodes = []
def __init__(self, label):
self._label = label
def __str__(self):
return self._label
nodes = [Node(l) for l in ["A","B","C","C","D","H"]]
edges = [(0,1),(0,5),(5,2),(1,3),(1,4)]
G = nx.Graph()
for i,j in edges:
G.add_edge(nodes[i], nodes[j])
nx.draw(G)
p.show()
给我们
这就是你想要的。我想你想要的是拓扑排序 这仅在具有DAG(有向无环图)时有效。 如果是这样,您也可以绘制所需的树-如下所示:
import uuid
import networkx as nx
import matplotlib.pyplot as plt
G = nx.DiGraph()
G.add_edge("A","B")
G.add_edge("A","H")
G.add_edge("H","C")
G.add_edge("B","C")
G.add_edge("B","D")
order = nx.topological_sort(G)
print "topological sort"
print order
# build tree
start = order[0]
nodes = [order[0]] # start with first node in topological order
labels = {}
print "edges"
tree = nx.Graph()
while nodes:
source = nodes.pop()
labels[source] = source
for target in G.neighbors(source):
if target in tree:
t = uuid.uuid1() # new unique id
else:
t = target
labels[t] = target
tree.add_edge(source,t)
print source,target,source,t
nodes.append(target)
nx.draw(tree,labels=labels)
plt.show()
图形使用标签映射将节点的ID映射到原始标签
感谢您绘制图表。这就是我“认为”Networkx在我背后所做的。因此,我的问题是:如何使用Networkx创建我的示例中的树?典型的理想情况是,当我创建G.add_边(“B”,“C”)时,创建一个新节点“C”是为了重用连接到H的on。然后,您需要将该新节点称为其他节点。可能是C1和C2。据我所知,NetworkX不允许多个节点具有相同的标签。但我需要节点具有相同的标签。就像我在主线中说的。我的节点是servername,我不能更改名称,否则我不知道哪个是哪个。。。但实际上,托尔斯滕·克兰兹不是“错”的,而是正确的,B取决于“C和D”。只是算法“dfs_successivers()”的输出B只依赖于D,如果我的树不能用于Networkx,那么这是错误的,是否可以用于其他库?感谢第二个例子,希望这符合你的需要。