簡體   English   中英

在Python 2.7中實現Karger Min Cut時出錯

[英]An error when implementing Karger Min Cut in Python 2.7

在Python中實現Karger Min Cut算法時,我陷入了僵局。 我傷了腦袋,但仍然無法弄清楚為什么我的實現無法正常工作,盡管可以用鉛筆和紙正常工作...

考慮具有四個節點1、2、3、4和5個邊的圖

[1, 2], [1, 3], [2, 3], [2, 4], [3, 4]

在python中,我用兩個列表表示它們:

nodes = [1, 2, 3, 4]
edges = [[1, 2], [1, 3], [2, 3], [2, 4], [3, 4]]

我的想法是:隨機選擇一條邊,說[1, 3] ,將其折疊,從節點列表中刪除node = 3 ,就好像將3合並為1一樣,然后從邊列表中刪除邊[1, 3]

現在,兩個列表看起來像:

nodes = [1, 2, 4]
edges = [[1, 2], [2, 3], [2, 4], [3, 4]]

當3合並為1時,邊列表進一步更新為

edges = [[1, 2], [2, 1], [2, 4], [1, 4]] 

通過將結果邊列表中的所有3更改為1。

這樣就完成了第一個循環。

在第二個循環中,假設從邊列表中隨機選擇了邊[1, 2] ,然后重復我得到的上述步驟,以便

nodes = [1, 4]
edges = [[2, 1], [2, 4], [1, 4]] 

進一步更改為[[1, 1], [1, 4], [1, 4]] 由於[1, 1]表示自循環,因此將其刪除,並且此回合的最終邊列表為[[1, 4], [1, 4]]

當節點數為2時,過程結束,最小切割數為2,即最終邊列表的長度。

所以我在Python中的實現如下:

import numpy as np


nodes = []
edges = []


f = open("kargerMinCut.txt", "r")
# The txt file has the form of an adjacency list
# The link to the txt file is at the very end          

for l in f:
    v = l.split()
    # The first element of each line is a (distinct)
    # vertex and is appended to nodes list.    
    nodes.append(int(v[0]))
    for u in v[1:]:
        # Edges list has the form as described in my 4 nodes example
        # above, which is unlike what in an typical adjacency list for
        # an undirected graph is. Here, if node 1 and node 2 share 
        # an edge, then edge [1, 2] only appears once in the "edges"
        # list, edge [2, 1] is not, which is why I used "set" below.
        edge = [int(v[0])]
        edge.append(int(u))
        count = 0
        for edg in edges:
            if (set(edg) == set(edge)):
                count += 1
        if (count == 0):
            edges.append(edge)

f.close()


while (len(nodes) > 2):
    # Number of current edges
    m = len(edges)
    # Choose a random edge uniformly 
    idx = np.random.randint(m)
    edgeChosen = edges[idx]
    # Two corresponding nodes of the chosen edge
    i = edgeChosen[0]
    j = edgeChosen[1]

    # Remove the second one from nodes list
    nodes.remove(j)
    # Remove the chosen edge from edges list
    del edges[idx]

    # Change all "j"s to "i"
    for ed in edges:
        for e in ed:
            if e == j:
                e = i

    # Remove those [i, i] edges (self loop)
    for ed in edges[:]:
        if len(set(ed)) == 1:
            edges.remove(ed)


print len(edges)

這只是Karger Min Cut算法的一次運行。 盡管while循環中的for循環效率不高,但我只是想嘗試一下這個想法。 我在具有200個節點和2000多個邊的輸入上試驗了上面的代碼。

但是,不管我做什么,Python在成功刪除幾個節點和邊后都會給出以下錯誤:

nodes.remove(j)
ValueError: list.remove(x): x not in list

這很有趣。 如果x不在節點列表中,則表示x是先前包含在所選邊中的“ j”之一,並且已被刪除或更改為相應的“ i”。

但是,我找不到我的代碼有什么問題。 我想念什么嗎? 有什么想法嗎? 非常感謝。

鏈接到數據文件(感謝GitHub上的nischayn22): https : //github.com/nischayn22/PythonScripts/blob/master/kargerMinCut.txt

這是一個非常基本的工作版本。 可以通過很多方式來改進此代碼,但是它可以工作,並且應該為您指明正確做事的方向。

from random import randint

nodes = [1,2,3,4]
edges = [[1, 2], [1, 3], [2, 3], [2, 4], [3, 4]]


while (len(nodes) > 2):
    target_edge = edges[randint(0, len(edges) - 1)]
    replace_with = target_edge[0]
    num_to_replace = target_edge[1]
    for edge in edges:
        if(edge[0] == num_to_replace):
            edge[0] = replace_with
        if(edge[1] == num_to_replace):
            edge[1] = replace_with
    edges.remove(target_edge)
    nodes.remove(num_to_replace)
    #remove self loops
    for edge in edges:
        if(edge[0] == edge[1]):
            edges.remove(edge)
    print(edges)

print(nodes)
print(edges)

導致錯誤的代碼的實際部分是

edgeChosen = edges[idx]
i = edgeChosen[0]
j = edgeChosen[1]

j不在節點中。

如果您發布完整的代碼,我們可以提供更多幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM