【问题标题】:Usage of forEdges iterator in networkit (python)在 networkit (python) 中使用 forEdges 迭代器
【发布时间】:2018-03-16 11:29:42
【问题描述】:

我仔细阅读了文档,但我仍然不清楚如何使用 G.forEdges(),它被描述为“实验性边缘迭代器接口”。

假设我想降低图表的密度。我有一个排序的权重列表,我想根据它们的权重删除边,直到图形分成两个连通分量。然后,我将选择保持图表连接的最少链接数。我会这样做:

cc = components.ConnectedComponents(G).run()
while cc.numberOfComponents()==1:
    for weight in weightlist:
        for (u,v) in G.edges():
            if G.weight(u,v)==weight:
                G=G.removeEdge(u,v)

顺便说一句,我从docs 知道有这个边缘迭代器,它可能以更有效的方式进行迭代。但是从文档中我真的无法理解如何正确使用这个forEdges,而且我在互联网上找不到一个例子。有任何想法吗?

或者也许是做我想做的事情的另一种想法:因为它是一个巨大的图表(1.25 亿个链接),所以即使我正在处理一个集群,迭代也将永远持续下去。

【问题讨论】:

    标签: python graph network-analysis networkit


    【解决方案1】:

    NetworKit 迭代器接受一个回调函数,所以如果你想迭代边缘(或节点),你必须定义一个函数,然后将它作为参数传递给迭代器。您可以找到更多信息here。例如,一个只打印所有边的简单函数是:

    # Callback function.
    # To iterate over edges it must accept 4 parameters
    def myFunction(u, v, weight, edgeId):
        print("Edge from {} to {} has weight {} and id {}".format(u, v, weight, edgeId))
    
    # Using iterator with callback function
    G.forEdges(myFunction)
    

    现在,如果您想继续删除权重在权重列表中的边,直到图形分成两个连通分量,您还必须更新图形的连通分量,因为 ConnectedComponents 不会自动为您执行此操作(这也可能是迭代需要永远的原因之一)。为了有效地做到这一点,您可以使用 DynConnectedComponents 类(请参阅下面的示例)。在这种情况下,我认为边缘迭代器对你没有多大帮助,所以我建议你继续使用 for 循环。

    from networkit import *
    
    # Efficiently updates connected components after edge updates
    cc = components.DynConnectedComponents(G).run()
    
    # Removes edges with weight equals to w until components split
    def removeEdges(w):
        for (u, v) in G.edges():
            if G.weight(u, v) == weight:
                G.removeEdge(u, v)
                # Updating connected components
                event = dynamic.GraphEvent(dynamic.GraphEvent.EDGE_REMOVAL, u, v, weight)
                cc.update(event)
                if cc.numberOfComponents() > 1:
                    # Components did split
                    return True
        # Components did not split
        return False
    
    if cc.numberOfComponents() == 1:
        for weight in weights:
            if removeEdges(weight):
                break
    

    这应该会加快您的原始代码速度。但是,它仍然是顺序代码,因此即使您在多核机器上运行它也只会使用一个内核。

    【讨论】:

    • 很好的解释,我很感激!特别是对于 graphEvent 部分:这对我来说是完全模糊的另一件事,因为我在文档中找不到任何东西。事实上,在networkit.dynamic 下并没有什么关于它的内容。再次,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2014-07-19
    • 2012-02-17
    • 1970-01-01
    • 2017-09-12
    • 2012-04-20
    • 2012-10-30
    • 2020-07-11
    相关资源
    最近更新 更多