简体   繁体   English

在 Karger 的最小割算法中,消除图中的自环

[英]In Karger's min cut algorithm, eliminating self-loops in a graph

I'm trying to implement Karger's algorithm for finding the minimum cut of a graph.我正在尝试实现Karger 算法来找到图形的最小割。 The key part is the contract method which performs a single contraction.关键部分是执行单次收缩的contract方法。 Here is my implementation so far (with a 'test'):这是我到目前为止的实现(带有“测试”):

import pytest
import random


class Graph(object):
    def __init__(self, G):
        self.G = G      # Adjacency list

    @property
    def edges(self):
        E = list()
        for vertex in self.G:
            for adjacent_vertex in self.G[vertex]:
                if vertex < adjacent_vertex:
                    E.append([vertex, adjacent_vertex])
        return E

    def randomized_contract(self):
        edge = random.choice(self.edges)
        self.contract(edge)

    def contract(self, edge):
        vertex, adjacent_vertex = edge
        self.G[vertex].remove(adjacent_vertex)
        self.G[adjacent_vertex].remove(vertex)
        self.G[vertex] += self.G[adjacent_vertex]
        del self.G[adjacent_vertex]
        for v in self.G:
            for n, av in enumerate(self.G[v]):
                if av == adjacent_vertex:
                    self.G[v][n] = vertex
        self.remove_self_loops()

    def remove_self_loops(self):
        for vertex in self.G:
            for n, adjacent_vertex in enumerate(self.G[vertex]):
                if adjacent_vertex == vertex:
                    del self.G[vertex][n]

    def contract_till_cut(self):
        while len(self.G) > 2:
            self.randomized_contract()


def test_contract_till_cut():
    graph = Graph({1: [2,3], 2: [1,3], 3: [1,2,4], 4: [3]})
    graph.contract_till_cut()
    print(graph.G)


if __name__ == "__main__":
    pytest.main([__file__, "-s"])

My problem is that on one particular run (you might have to run it a few times to reproduce this result), the get the adjacency list我的问题是,在一次特定运行中(您可能需要运行几次才能重现此结果),获取邻接列表

{1: [1, 4], 4: [1]}

where node 1 has a 'self-loop' - that is, it occurs in its own adjacency list.其中节点 1 有一个“自循环”——也就是说,它出现在它自己的邻接列表中。 I don't see how this can happen;我不明白这怎么会发生; every call to contract is topped off by a call to remove_self_loops which seems to work.每个对contract的调用都以对remove_self_loops的调用remove_self_loops ,这似乎有效。 Can anyone spot the bug in this code?任何人都可以发现此代码中的错误吗?

The problem was with the remove_self_loops method: it was terminating after remove only one self-loop.问题在于remove_self_loops方法:它在仅删除一个自循环后终止。 I replaced it by the following:我用以下内容替换了它:

def remove_self_loops(self):
    for vertex in self.G:
        self.G[vertex] = [av for av in self.G[vertex] if not av == vertex]

Now after the 'problem' case (which corresponds to contracting along edges [1,2] and [1,3] consecutively) I get the expected (minimum) cut:现在在“问题”案例(对应于沿边[1,2][1,3]连续收缩)之后,我得到了预期的(最小)切割:

{1: [4], 4: [1]}

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

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