简体   繁体   English

在igraph [python]中将两个有向边折叠成一个

[英]Collapsing two directed edges into one in igraph [python]

I have a directed graph where there are edges going both ways in many cases between two nodes, with varying weights. 我有一个有向图,其中在许多情况下,在两个节点之间存在边缘双向,具有不同的权重。 For example, a-->b with weight 3, and b-->a with weight 1. I want to combine these into a graph where only the aggregate weight exists, ie this example would result in a graph where a--> with weight 2. 例如,a - > b的权重为3,而b - > a的权重为1.我想将这些组合成一个只存在聚合权重的图形,即这个例子会产生一个图形,其中一个 - >重量2。

I've seen g.simplify(), but how do I get this to combine opposing edges? 我见过g.simplify(),但是如何让它结合相反的边?

Assuming that there can be multiple edges in the same direction between the same two vertices, and you want to add up their weights if so, you can start with 假设在相同的两个顶点之间可以有相同方向的多个边,并且如果是这样,你想要加权,你可以从

g.simplify(combine_edges='sum')

Then for each pair of vertices a and b , at most one edge goes from a to b . 然后对于每对顶点ab ,最多一个边从ab

To combine these opposing edges into one edge, you can use the instance method to_undirected , which transforms g to an undirected graph. 要将这些相对边组合成一个边,可以使用实例方法to_undirected ,它将g转换为无向图。 After the first step, there should be at most two edges between each pair of vertices, always opposed. 在第一步之后,每对顶点之间应该至多有两条边,总是相对的。 So if you want to subtract the weight in one direction from the other, you could do this: 因此,如果你想从另一个方向减去一个方向的重量,你可以这样做:

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)

But this gives you an undirected graph, and whether the weight of an edge should be taken as going from a to b , or from b to a , is impossible to tell. 但这会给你一个无向图,并且边缘的权重是从ab ,还是从ba ,是不可能分辨出来的。

If instead you want a directed graph, how do you choose whether to make an edge from a to b with weight 2, or from b to a with weight -2? 相反,如果你想有向图,你如何选择是否使边缘体重2到B或从BA与体重-2?

Here is a function which will produce such a directed graph; 这是一个能产生这种有向图的函数; the direction of each edge in the output graph is determined by the first edge encountered between the vertices in the input graph. 输出图中每条边的方向由输入图中顶点之间遇到的第一条边确定。 Also, any edge attributes besides 'weight' are copied from that first edge, ignoring any other edges. 此外,除了“权重”之外的任何边缘属性都是从第一个边缘复制的,忽略任何其他边缘。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM