在 igraph [python] 中将两条有向边折叠成一条
Collapsing two directed edges into one in igraph [python]
我有一个有向图,在许多情况下,两个节点之间的边有两个方向,具有不同的权重。例如,权重为 3 的 a-->b 和权重为 1 的 b-->a。我想将这些组合成一个只存在总权重的图表,即这个例子会产生一个图表,其中 a-->权重为 2。
我已经看过 g.simplify(),但是我如何才能用它来组合相对的边?
假设在相同的两个顶点之间可以有多个方向相同的边,如果是的话你想把它们的权重加起来,你可以从
开始
g.simplify(combine_edges='sum')
然后对于每对顶点a和b,最多有一条边从a 至 b.
要将这些相对的边组合成一条边,可以使用实例方法to_undirected
,它将g
转换为无向图。第一步之后,每对顶点之间最多应该有两条边,总是相对的。所以如果你想从另一个方向减去一个方向的重量,你可以这样做:
def subwt(attrs):
if len(attrs) == 1:
return attrs[0]
assert len(attrs) == 2
return attrs[0] - attrs[1]
g.to_undirected(combine_edges=subwt)
但这给了你一个无向图,一条边的权重是否应该取为从a到b,或从 b 到 a,是无法分辨的。
如果你想要一个有向图,你如何选择从 a 到 b 的边,权重为 2,或者从 b 到 a 权重 -2?
这里有一个函数可以生成这样的有向图;输出图中每条边的方向由输入图中顶点之间遇到的第一条边决定。此外,除了 'weight' 之外的任何边属性都从第一条边复制,忽略任何其他边。
def combine_edges(graph):
combe = graph.copy() # copies graph attributes, vertex attributes
combe.delete_edges(None) # removes all edges
for e in graph.es:
src, targ = e.tuple
if combe.are_connected(src, targ):
ced = combe.es(_source=src, _target=targ)[0]
ced['weight'] += e['weight']
elif combe.are_connected(targ, src):
ced = combe.es(_source=targ, _target=src)[0]
ced['weight'] -= e['weight']
else:
combe.add_edge(src, targ, **e.attributes())
return combe
我有一个有向图,在许多情况下,两个节点之间的边有两个方向,具有不同的权重。例如,权重为 3 的 a-->b 和权重为 1 的 b-->a。我想将这些组合成一个只存在总权重的图表,即这个例子会产生一个图表,其中 a-->权重为 2。
我已经看过 g.simplify(),但是我如何才能用它来组合相对的边?
假设在相同的两个顶点之间可以有多个方向相同的边,如果是的话你想把它们的权重加起来,你可以从
开始g.simplify(combine_edges='sum')
然后对于每对顶点a和b,最多有一条边从a 至 b.
要将这些相对的边组合成一条边,可以使用实例方法to_undirected
,它将g
转换为无向图。第一步之后,每对顶点之间最多应该有两条边,总是相对的。所以如果你想从另一个方向减去一个方向的重量,你可以这样做:
def subwt(attrs):
if len(attrs) == 1:
return attrs[0]
assert len(attrs) == 2
return attrs[0] - attrs[1]
g.to_undirected(combine_edges=subwt)
但这给了你一个无向图,一条边的权重是否应该取为从a到b,或从 b 到 a,是无法分辨的。
如果你想要一个有向图,你如何选择从 a 到 b 的边,权重为 2,或者从 b 到 a 权重 -2?
这里有一个函数可以生成这样的有向图;输出图中每条边的方向由输入图中顶点之间遇到的第一条边决定。此外,除了 'weight' 之外的任何边属性都从第一条边复制,忽略任何其他边。
def combine_edges(graph):
combe = graph.copy() # copies graph attributes, vertex attributes
combe.delete_edges(None) # removes all edges
for e in graph.es:
src, targ = e.tuple
if combe.are_connected(src, targ):
ced = combe.es(_source=src, _target=targ)[0]
ced['weight'] += e['weight']
elif combe.are_connected(targ, src):
ced = combe.es(_source=targ, _target=src)[0]
ced['weight'] -= e['weight']
else:
combe.add_edge(src, targ, **e.attributes())
return combe