如何在Python中分析和识别有向图关系(节点之间)

如何在Python中分析和识别有向图关系(节点之间),python,python-3.x,networkx,Python,Python 3.x,Networkx,我想用Python来解决一个图论问题(我是图论的新手) 数据格式如下: edges = [('Child1', 'Parent1'), ('Child2', 'Parent2'), ('Child3', 'Parent1'), ('Child4', 'Parent3'), ('Child2', 'Parent1')] 我需要分析的关系包括: Child2的父母是Parent1和Parent2 Parent1是Child1、Child2和Child3的父级 使用Python查找上

我想用Python来解决一个图论问题(我是图论的新手)

数据格式如下:

edges = [('Child1', 'Parent1'), ('Child2', 'Parent2'), ('Child3', 'Parent1'), 
     ('Child4', 'Parent3'), ('Child2', 'Parent1')]
我需要分析的关系包括:

  • Child2的父母是Parent1和Parent2
  • Parent1是Child1、Child2和Child3的父级

使用Python查找上面列出的关系的最佳方法是什么?

我将在父母和孩子之间建立映射:

>>> edges = [
...     ('Child1', 'Parent1'), ('Child2', 'Parent2'), ('Child3', 'Parent1'), 
...     ('Child4', 'Parent3'), ('Child2', 'Parent1')
... ]

>>> from collections import defaultdict
>>> parents = defaultdict(list)  # Key: child, value: list of parents
>>> children = defaultdict(list)  # Key: parent, value: list of children
>>> for child, parent in edges:
...     parents[child].append(parent)
...     children[parent].append(child)
... 
>>> parents['Child2']  # Child2's parents are Parent1 and Parent2
['Parent2', 'Parent1']
>>> children['Parent1'] # Parent1 is a parent to Child1, Child2 and Child3.
['Child1', 'Child3', 'Child2']

我会在父母和孩子之间做一个映射:

>>> edges = [
...     ('Child1', 'Parent1'), ('Child2', 'Parent2'), ('Child3', 'Parent1'), 
...     ('Child4', 'Parent3'), ('Child2', 'Parent1')
... ]

>>> from collections import defaultdict
>>> parents = defaultdict(list)  # Key: child, value: list of parents
>>> children = defaultdict(list)  # Key: parent, value: list of children
>>> for child, parent in edges:
...     parents[child].append(parent)
...     children[parent].append(child)
... 
>>> parents['Child2']  # Child2's parents are Parent1 and Parent2
['Parent2', 'Parent1']
>>> children['Parent1'] # Parent1 is a parent to Child1, Child2 and Child3.
['Child1', 'Child3', 'Child2']

既然您标记了
networkx
,下面是一个使用该库的解决方案

在下面的代码中,我创建了一个方向图,然后从列表中添加边。重要提示:边中的第一个节点将是源节点,第二个节点将是目标节点,即子节点将指向其父节点

temp = [edge[1] for edge in G.out_edges('Child2')]
print('Parents of Child2:', temp)

temp = [edge[0] for edge in G.in_edges('Parent1')]
print('Children of Parent1:', temp)
为了得到我使用的孩子的父母,为了得到我使用的父母的孩子。请注意,这两个函数都返回一个边列表

import networkx as nx

edges = [('Child1', 'Parent1'), ('Child2', 'Parent2'), ('Child3', 'Parent1'), 
     ('Child4', 'Parent3'), ('Child2', 'Parent1')]

G = nx.DiGraph()
G.add_edges_from(edges)

print(G.out_edges('Child2'))  # parents of Child2
print(G.in_edges('Parent1'))  # children of Parent1
输出:

[('Child2', 'Parent2'), ('Child2', 'Parent1')]
[('Child2', 'Parent1'), ('Child1', 'Parent1'), ('Child3', 'Parent1')]
Parents of Child2: ['Parent2', 'Parent1']
Children of Parent1: ['Child2', 'Child1', 'Child3']
您可以使用列表理解来获取单个孩子或家长的列表

temp = [edge[1] for edge in G.out_edges('Child2')]
print('Parents of Child2:', temp)

temp = [edge[0] for edge in G.in_edges('Parent1')]
print('Children of Parent1:', temp)
输出:

[('Child2', 'Parent2'), ('Child2', 'Parent1')]
[('Child2', 'Parent1'), ('Child1', 'Parent1'), ('Child3', 'Parent1')]
Parents of Child2: ['Parent2', 'Parent1']
Children of Parent1: ['Child2', 'Child1', 'Child3']

既然您标记了
networkx
,下面是一个使用该库的解决方案

在下面的代码中,我创建了一个方向图,然后从列表中添加边。重要提示:边中的第一个节点将是源节点,第二个节点将是目标节点,即子节点将指向其父节点

temp = [edge[1] for edge in G.out_edges('Child2')]
print('Parents of Child2:', temp)

temp = [edge[0] for edge in G.in_edges('Parent1')]
print('Children of Parent1:', temp)
为了得到我使用的孩子的父母,为了得到我使用的父母的孩子。请注意,这两个函数都返回一个边列表

import networkx as nx

edges = [('Child1', 'Parent1'), ('Child2', 'Parent2'), ('Child3', 'Parent1'), 
     ('Child4', 'Parent3'), ('Child2', 'Parent1')]

G = nx.DiGraph()
G.add_edges_from(edges)

print(G.out_edges('Child2'))  # parents of Child2
print(G.in_edges('Parent1'))  # children of Parent1
输出:

[('Child2', 'Parent2'), ('Child2', 'Parent1')]
[('Child2', 'Parent1'), ('Child1', 'Parent1'), ('Child3', 'Parent1')]
Parents of Child2: ['Parent2', 'Parent1']
Children of Parent1: ['Child2', 'Child1', 'Child3']
您可以使用列表理解来获取单个孩子或家长的列表

temp = [edge[1] for edge in G.out_edges('Child2')]
print('Parents of Child2:', temp)

temp = [edge[0] for edge in G.in_edges('Parent1')]
print('Children of Parent1:', temp)
输出:

[('Child2', 'Parent2'), ('Child2', 'Parent1')]
[('Child2', 'Parent1'), ('Child1', 'Parent1'), ('Child3', 'Parent1')]
Parents of Child2: ['Parent2', 'Parent1']
Children of Parent1: ['Child2', 'Child1', 'Child3']

你说的分析是什么意思?您要解决哪些查询?拓扑排序?最短路径?欧拉循环?我想了解节点之间的方向联系。例如,节点A是节点B和C的子节点,也是这些节点D、E、F的父节点。您对analyze的意思是什么?您要解决哪些查询?拓扑排序?最短路径?欧拉循环?我想了解节点之间的方向联系。例如,节点A是节点B和C的子节点,这些节点D、E、F的父节点。是否有方法执行以下操作:
[('Child1','Parent1'),('Child2','Parent2'),('Child3','Parent1'),('Child4','Parent3'),('Child2','Parent1')]->[('Parent1',('Child1','Child2','Child3'),('Parent3'),('Child4'))]
@Dave这可能需要一个新问题,但这里有一个解决方案(两行):首先是
parents=sorted(list(set([edge[1]表示edge-in-edges]))
然后是
edges2=[(p,tuple(sorted([e[0]表示e-in-edges,如果e[1]=p]))表示p-in-parents]
。我知道使用列表理解是一个相当丑陋的解决方案,所以下面我们来做同样的事情。有没有办法做到以下几点:
[('Child1','Parent1'),('Child2','Parent2'),('Child3','Parent1'),('Child4','Parent3'),('Child2','Parent1')]-->[('Parent1','Child1','Child2','Child3'),('Parent3'),',('Child4')]
@Dave这可能需要一个新的问题,但这里有一个解决方案(分两行):首先
父项=排序(列表(设置([edge[1]表示边中的边]))
然后
edges2=[(p,tuple(排序([e[0]表示边中的e,如果e[1]==p]))表示父项中的p]
。我知道使用列表理解是一个相当丑陋的解决方案,所以下面我们来做同样的事情。