我是Python的新手。
我尝试制作一个Kruskal算法。这是我的代码:
#c={('v','a'):5,('v','g'):5,('g','a'):5,('v','b'):7,('v','e'):4,('f','e'):8,('f','b'):8,('f','c'):11,('c','e'):9,('c','d'):7,('c','b'):9,('e','d'):8}
#n=8
def argmin(c):
m=1e100
r=()
for i in c:
if c[i]<m:
m=c[i]
r=i
return r
def kruskal (n, c):
T=[]
B=[]
while len(T)<n-1:
E=argmin(c)
c.pop(E)
e=[]
e+=E
a0=0
a1=0
f0=-1
f1=-1
cross=0
# print('e avant',e)
for i in range(len(B)):
for j in range(len(B[i])):
if e[0]==B[i][j]:
cross+=1
f0=i
if e[1]==B[i][j]:
cross+=1
f1=i
if cross==2: break
else: cross=0
if cross==2: continue
# print('e apres',e)
T.append(e)
# print('T',T)
if f0!=-1 and f1!=-1:
B[f0].extend(B[f1])
B.pop(f1)
elif f0!=-1:
B[f0].extend(e[1])
elif f1!=-1:
B[f1].extend(e[0])
else :
B.append(e)
# print('B', B)
return T
我遇到的问题是:&#34; T.append(e)&#34; 在结果中,T [0]不是我所期望的。 如果我输入以下内容:
c={('v','a'):5,('v','g'):5,('g','a'):5,('v','b'):7,('v','e'):4,('f','e'):8,('f','b'):8,('f','c'):11,('c','e'):9,('c','d'):7,('c','b'):9,('e','d'):8}
n=8
然后我调用我的函数: kruskal(8,c) 我明白了:
[['v', 'e', 'g', 'a', 'b', 'f', 'c', 'd'], ['v', 'g'], ['v', 'a'], ['v', 'b'], ['c', 'd'], ['f', 'b'], ['e', 'd']]
我期望以下内容:
[['v', 'e'], ['v', 'g'], ['v', 'a'], ['v', 'b'], ['c', 'd'], ['f', 'b'], ['e', 'd']]
答案 0 :(得分:1)
没有找到你的所有代码。但是有些东西被发现,你有时会追加references
list
。所以只需要修复:
from copy import deepcopy
T.append(deepcopy(e)) #in place of T.append(e)
将输出
[['v', 'e'], ['g', 'a'], ['v', 'a'], ['v', 'b'], ['c', 'd'], ['f', 'b'], ['e', 'd']]
示例强>
a = [1, 2]
b = a
b.append(3)
>>>a
[1,2,3]
>>>b
[1,2,3]
这里发生了什么
a = [1,2]
b = a
>>>id(a), id(b)
(140526873334272, 140526873334272)
列表[1,2]
由tagged
和a
两个变量b
组成。因此,对列表的任何更改都会影响标记到它的每个varables
。
答案 1 :(得分:0)
The answer by itzmeontv关于问题的根本原因是正确的T
的第一个成员是一个可变列表,然后您可以在代码中进一步修改。在您的情况下发生这种情况的代码路径有点复杂:
e
追加到T
- 因此T[0]
引用此时的列表名称e
(内容['v','e']
})在同一次迭代中,你总是点击这个块:
else :
B.append(e)
B[0]
现在也引用了名为e
的列表 - 即T[0]
引用与<{1}中的相同的列表 B[0]
的任何更改都会反映在B[0]
中,因为列表是可变的。T[0]
- ,但 e
中引用的列表和B[0]
仍然是同一个列表,即{{1} } T[0]
为零的情况下执行['v','e']
时继续扩展此列表这是在Python中分配不复制的列表的一种症状,如果您想加深理解,则会给出详细的处理in this question。有关如何将列表附加到B[f0].extend(B[f1])
is given以及timings的一系列选项 - 例如,您可能喜欢编写f0
,并使用切片表示法隐式制作<{1}}的副本,在您追加它的位置。
您可能需要考虑的一件事是,T
成员加入T.append(e[:])
后是否需要e
成员mutable。如果你不这样做 - 一个选择可能是追加T
而不是T
- 即。
tuples