我正在使用动态编程来实现Matrix_Chain问题,即找出通过括号进行矩阵乘法的最小乘法数。在更改列表m
的初始化方式之前,我的代码无法正常工作。有人可以解释为什么即使m = [[0]*n]*n
和m = [[0 for x in range(n)] for x in range(n)]
组成看似相同的列表时,m = [[0]*n]*n
也会导致矩阵条目无法正确更新为最低成本吗?
我制作了列表m = [[0]*5]*5
并打印
for a in m:
print(a)
我制作了清单n = [[0 for x in range(5)] for x in range(5)]
,并以相同的方式打印。结果是相同的。
import sys
def Matrix_Chain (p, n):
m = [[0]*n]*n #problematic step
for i in range (1,n):
m[i][i] =0
for L in range(2, n):
for i in range(1,n-L+1):
j = i + L -1
m[i][j] = sys.maxsize
for k in range (i, j):
q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]
if q < m[i][j]:
m[i][j] = q
return m[1][n-1]
对于参数p = [1,2,3,4]
和n = 4
,我希望看到18
,即最小乘法数。但是,m = [[0]*n]*n
方法将返回9223372036854775807
,即sys.maxsize
。 m = [[0 for x in range(n)] for x in range(n)]
方法返回正确的答案18
。
答案 0 :(得分:3)
这是因为
m = [[0]*n]*n
在m中引用同一对象。所以m [0]是m [1]是...是m [n-1]。通过示例可以更好地理解这一点。假设您有:
m = [[0] * 3] * 3
print(a)
m[0][0] = 2
print(a)
输出为:
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
[[2, 0, 0], [2, 0, 0], [2, 0, 0]]
如您所见,更改m [0]中的元素会更改m [1]和m [2]中的相同位置。这是因为m [1]和m [2]只是对m [0]的引用。
对于
m = [[0 for x in range(n)] for x in range(n)]
您实际上为m中的每个位置创建了一个新列表。更改m [0]不会影响m [i](对于0