在Python 2.7中实现Karger Min Cut时出错
我在Python中实现Karger Min Cut算法时遇到了死锁。我打破了我的头,但仍然不明白为什么我的实现不工作,而它的工作与铅笔和纸 考虑一个有四个节点1、2、3、4和五条边的图在Python 2.7中实现Karger Min Cut时出错,python,Python,我在Python中实现Karger Min Cut算法时遇到了死锁。我打破了我的头,但仍然不明白为什么我的实现不工作,而它的工作与铅笔和纸 考虑一个有四个节点1、2、3、4和五条边的图 [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],折叠它,从节点列表中删除
[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]
,折叠它,从节点列表中删除节点=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):产生错误的代码的实际部分是
edgeChosen = edges[idx]
i = edgeChosen[0]
j = edgeChosen[1]
j
不在节点中
如果您发布完整的代码,我们可以提供更多帮助。代码中出现错误的实际部分是
edgeChosen = edges[idx]
i = edgeChosen[0]
j = edgeChosen[1]
j
不在节点中
如果您发布完整的代码,我们可以提供更多帮助。这是一个非常基本的工作版本。这段代码可以在很多方面得到改进,但它是有效的,应该为您指明如何正确处理事情的方向
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)
这是一个相当基本的工作版本。这段代码可以在很多方面得到改进,但它是有效的,应该为您指明如何正确处理事情的方向
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)
铅笔纸
通常使用更高版本的python解释器,该解释器从人类
导入常识
和手波
。。。哪一步在Python中不起作用?请给出实际运行的代码:)。SSCCE铅笔纸
通常使用更高版本的python解释器,该解释器从人类
导入常识
和手波
。。。哪一步在Python中不起作用?请给出实际运行的代码:)。感谢您的回复:)。实际上,这几乎是我的全部代码。在此“while”之前有一些读取txt文件和数据处理代码。我的意图是在一次kargerMinCut中尝试它。如果它有效,我会添加一些其他内容,这样它最终可以给我一个列表,比如说,500次跑步中的最小切数,并在这500次跑步中选择最小值。但这一次失败了。不管怎样,我都会编辑上面的代码。谢谢回复:)。实际上,这几乎是我的全部代码。在此“while”之前有一些读取txt文件和数据处理代码。我的意图是在一次kargerMinCut中尝试它。如果它有效,我会添加一些其他内容,这样它最终可以给我一个列表,比如说,500次跑步中的最小切数,并在这500次跑步中选择最小值。但这一次失败了。不管怎样,我都会编辑上面的代码。