4

我正在为 NetworkX 中的有向图编写一些代码,并且遇到了一个问题,这可能是我有问题的编程经验的结果。我想要做的是以下几点:

我有一个有向图 G,顶部有两个“父节点”,所有其他节点都从中流出。在绘制此网络图时,我想将作为“父 1”后代的每个节点绘制为一种颜色,而将所有其他节点绘制为另一种颜色。这意味着我需要一份 Parent 1 的继任者名单。

现在,我可以使用以下方法轻松获得它们的第一层:

descend= G.successors(parent1)

问题是这只给了我第一代接班人。最好是,我想要后继者的后继者,后继者的后继者等。任意,因为能够运行分析并制作图表而不必确切知道其中有多少代,这将是非常有用的.

知道如何解决这个问题吗?

4

7 回答 7

6

您不需要后代列表,您只想为它们着色。为此,您只需选择一种遍历图形的算法并使用它为边缘着色。

例如,你可以做

from networkx.algorithms.traversal.depth_first_search import dfs_edges

G = DiGraph( ... )
for edge in dfs_edges(G, parent1):
    color(edge)

请参阅https://networkx.github.io/documentation/stable/reference/algorithms/generated/networkx.algorithms.traversal.depth_first_search.dfs_edges.html?highlight=traversal

于 2011-07-31T01:10:57.623 回答
3

如果您想获得所有后继节点,而不通过边缘,另一种方法可能是:

import networkx as nx
G = DiGraph( ... )
successors = nx.nodes(nx.dfs_tree(G, your_node))

我注意到,如果您改为致电:

successors = list(nx.dfs_successors(G, your_node)

底层的节点不知何故不包括在内。

于 2017-08-07T17:53:08.113 回答
1

那么,继承人的继承人只是后代的继承人吧?

# First successors
descend = G.successors(parent1)
# 2nd level successors
def allDescendants(d1):
   d2 = []
   for d in d1:
       d2 += G.successors(d)
   return d2

descend2 = allDescendants(descend)

要获得 3 级后代,请调用 allDescendants(d2) 等。

编辑:问题 1: allDescend = descend + descend2为您提供两组组合,对后代的其他级别执行相同操作。

问题2:如果您的图表中有循环,那么您需要首先修改代码以测试您之前是否访问过该后代,例如:

def allDescendants(d1, exclude):
   d2 = []
   for d in d1:
       d2 += filter(lambda s: s not in exclude, G.successors(d))
   return d2

这样,您将allDescend作为第二个参数传递给上述函数,因此它不会包含在未来的后代中。你一直这样做,直到allDescandants()返回一个空数组,在这种情况下你知道你已经探索了整个图表,然后你停下来。

既然这开始看起来像家庭作业,我会让你弄清楚如何自己拼凑所有这些。;)

于 2011-07-31T00:56:26.370 回答
1

为了让将来偶然发现它的人更容易找到答案,这是我最终使用的代码:

G = DiGraph() # Creates an empty directed graph G
infile = open(sys.argv[1])
for edge in infile:
    edge1, edge2 = edge.split() #Splits data on the space
    node1 = int(edge1) #Creates integer version of the node names 
    node2 = int(edge2)
    G.add_edge(node1,node2) #Adds an edge between two nodes

parent1=int(sys.argv[2])   
parent2=int(sys.argv[3])

data_successors = dfs_successors(G,parent1)
successor_list = data_successors.values()
allsuccessors = [item for sublist in successor_list for item in sublist]

pos = graphviz_layout(G,prog='dot') 
plt.figure(dpi=300)
draw_networkx_nodes(G,pos,node_color="LightCoral")
draw_networkx_nodes(G,pos,nodelist=allsuccessors, node_color="SkyBlue")
draw_networkx_edges(G,pos,arrows=False) 
draw_networkx_labels(G,pos,font_size=6,font_family='sans-serif',labels=labels)
于 2011-07-31T19:05:30.673 回答
1

我相信自几年前@Jochen Ritzel 的回答以来,Networkx 已经发生了变化。

现在以下成立,仅更改导入语句。

import networkx
from networkx import dfs_edges

G = DiGraph( ... )
for edge in dfs_edges(G, parent1):
    color(edge)
于 2013-05-15T20:16:59.483 回答
0

单线:

descendents = sum(nx.dfs_successors(G, parent).values(), [])
于 2020-04-17T09:46:40.347 回答
0
nx.descendants(G, parent)

更多细节:https ://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.dag.descendants.html

于 2021-04-11T01:47:32.740 回答