Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在NetworkX中查找有向图中后继的后继_Python_Networkx_Directed Graph - Fatal编程技术网

Python 在NetworkX中查找有向图中后继的后继

Python 在NetworkX中查找有向图中后继的后继,python,networkx,directed-graph,Python,Networkx,Directed Graph,我正在为NetworkX中的一个有向图编写一些代码,遇到了一个问题,这可能是我有问题的编程经验造成的。我想做的是: 我有一个有向图G,顶部有两个“父节点”,所有其他节点都从中流出。在绘制这个网络图时,我想将“父1”的后代中的每个节点绘制为一种颜色,所有其他节点绘制为另一种颜色。这意味着我需要一份父1的继任者名单 现在,我可以使用以下工具轻松获得第一层: descend= G.successors(parent1) 问题是这只给了我第一代的接班人。最好,我想要继承人的继承人,继承人的继承人的继承

我正在为NetworkX中的一个有向图编写一些代码,遇到了一个问题,这可能是我有问题的编程经验造成的。我想做的是:

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

现在,我可以使用以下工具轻松获得第一层:

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


你知道怎么做吗?

好吧,继承人的继承人就是继承人的继承人,对吗

# 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级子体,请调用所有子体(d2)等

编辑: 问题1:
alldescent=descent+descend2
为您提供两个集合的组合,对更高级别的子体执行相同操作

问题2:如果图形中有循环,则需要首先修改代码以测试您以前是否访问过该子体,例如:

def allDescendants(d1, exclude):
   d2 = []
   for d in d1:
       d2 += filter(lambda s: s not in exclude, G.successors(d))
   return d2
这样,您就可以将
alldown
作为第二个参数传递给上述函数,这样它就不会包含在以后的子函数中。一直执行此操作,直到
alldescands()
返回一个空数组,在这种情况下,您知道您已经浏览了整个图形,然后停止


既然这看起来像是家庭作业,我就让你自己想办法把这一切拼凑起来

您不需要后代的列表,只需要给它们上色即可。为此,您只需选择一个遍历图形的算法,并使用它为边着色

例如,你可以

from networkx.algorithms.traversal.depth_first_search import dfs_edges

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

请参见

,这样答案会更清晰,更容易为未来偶然发现它的人找到,以下是我最终使用的代码:

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)

我相信,自从几年前@Jochen Ritzel给出答案以来,Networkx已经发生了变化

现在,以下内容仍然有效,只是更改了import语句

import networkx
from networkx import dfs_edges

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

如果要获取所有后续节点,而不通过边,另一种方法可以是:

import networkx as nx
G = DiGraph( ... )
successors = nx.nodes(nx.dfs_tree(G, your_node))
我注意到如果你改打电话:

successors = list(nx.dfs_successors(G, your_node)
底层的节点不包括在内。

Oneliner:

descendents = sum(nx.dfs_successors(G, parent).values(), [])

更多详细信息:

两个问题。1:运行上述代码只会生成第二级子体。有没有一种方法可以附加结果以获得所有子体的运行列表?2:这个解决方案假设我知道我有多少个级别。有没有办法让它运行n个级别,直到它基本上停止生成新的后代?顺便说一句,这不是家庭作业。我已经完成了家庭作业,进入了“好主意,听起来不错,去实现它……”快速评论:使用
+=
附加
更昂贵,因为新的
列表
对象在每次循环迭代中都会被销毁和创建。可以用来观察差异。看起来DFS算法可能是我最好的选择。我没有使用上面建议的代码,而是使用了dfs_继承者,它似乎为我提供了一个来自父1的所有继承者的字典。现在只需要将字典转换成有用的格式。讨厌字典。稍微修改上面的答案,最终使用dfs_继任者(G,parent1),它确实返回了一个包含所有继任者的字典,将该字典转换为一个列表,然后根据列表调整列表。感谢两位评论员的帮助。不起作用。。。示例中没有清楚说明。太好了!我们正在寻找类似于
nx.dfs_tree
的东西,这应该更高,即使接受的答案解决了OP的问题,但问题实际上是以一种只有这个问题才能回答的方式构建的
nx.descendants(G, parent)