说我在NetworkX中制作了一个DiGraph:
import networkx as nx
G = nx.DiGraph()
n = ["A","B","C","D","E","F","H","I","J","K","L","X","Y","Z"]
e = [("A","Z"),("Z","B"),("B","Y"),("Y","C"),("C","G"),("G","H"),("G","I"),("I","J"),("K","J"),("J","L"),("F","E"),("E","D"),("D","X"),("X","C")]
G.add_nodes_from(n)
G.add_edges_from(e)
如何删除所有具有in-degree和out-degree等于1的节点,以便我的图形看起来像这样?:
import networkx as nx
G = nx.DiGraph()
n = ["A","C","F","G","H","J","K","L"]
e = [("A","C"),("C","G"),("G","H"),("G","J"),("K","J"),("J","L")
G.add_nodes_from(n)
G.add_edges_from(e)
我们的想法是删除“流通”节点并保持连接。
答案 0 :(得分:6)
以下代码可以满足你的需要,虽然我没有看到你在最终结果中从哪里获得边缘(“A”,“C”)和(“G”,“J”)。
import networkx as nx
def remove_edges(g, in_degree=1, out_degree=1):
g2=g.copy()
d_in=g2.in_degree(g2)
d_out=g2.out_degree(g2)
print(d_in)
print(d_out)
for n in g2.nodes():
if d_in[n]==in_degree and d_out[n] == out_degree:
g2.remove_node(n)
return g2
G_trimmed = remove_edges(G)
G_trimmed.edges()
#outputs [('C', 'G'), ('G', 'H'), ('K', 'J'), ('J', 'L')]
G_trimmed.nodes()
#outputs ['A', 'C', 'G', 'F', 'H', 'K', 'J', 'L']
答案 1 :(得分:4)
基本上,只需遍历节点并检查它们是否是“流通节点”,使用remove_node
和add_edge
重新连接图形。定义一个函数:
def remove_flow_through(graph):
for n in graph.nodes():
pred = graph.predecessors(n)
succ = graph.successors(n)
if len(pred) == len(succ) == 1:
graph.remove_node(n)
graph.add_edge(pred[0], succ[0])
该功能可以就地修改图形,因此如果需要,可以处理图形的副本。
现在反复调用remove_flow_through
,直到图表中的节点数不再减少:
while True:
prev_len = len(G)
remove_flow_through(G)
if len(G) == prev_len:
break
示例图包含所有流通节点,只需调用remove_flow_through
。然而,有可能移除节点再现现有边缘,这导致具有剩余流通节点的图形。一个例子是:
dg = nx.DiGraph([(1,2), (2,3), (3,4), (2,5), (5,3)])