我正在尝试使用 numpy 制作一个矩阵列表来表示解决河内塔问题的最小移动次数。当我在每次移动后打印 m 时,我的解决方案有效,但是当我尝试将 m 附加到列表时,结果列表仅包含一遍又一遍重复的最终矩阵。这是我的代码:
def set_up(total,start):
global moves
moves = 0
m = np.empty((3,total+1))
for i in range(3):
for j in range(total+1):
m[i,j] = -1
for i in range(total):
m[start,i] = int(total-i-1)
m_list = [m]
return m,m_list
def move_disk(total,num,m,move_from,move_to,m_list):
global moves
temp =m[move_from,np.where(m[move_from]==-1)[0][0]-1]
m[move_from,np.where(m[move_from]==-1)[0][0]-1]= -1
m[move_to,np.where(m[move_to]==-1)[0][0]] = temp
moves = moves + 1
m_list.append(m)
def towers_algorithm(total,num,m,start,middle,final,m_list):
if num == 0:
return
else:
towers_algorithm(total,num-1,m,start,final,middle,m_list)
move_disk(total,num,m,start,final,m_list)
towers_algorithm(total,num-1,m,middle,start,final,m_list)
我尝试将列表作为参数传递并使 m_list 成为全局变量。两者给出了相同的结果。
您的
set_up
函数创建一个 m
矩阵,并且这是创建此类矩阵的唯一一次。其余代码会变异 m
并执行 m_list.append(m)
。但这会将相同的数组引用多次附加到 m_list
,因此 m_list
只会有重复项。请注意,只有一个 m
数组,因此您不能期望 m_list
以某种方式引用多个不同的数组。
要解决此问题,请确保每次追加到 m_list
时都创建一个新数组。您可以通过不同的方式实现这一点,例如:
m_list.append(m.copy())
m
附加到
m_list
,其中m
仅表示对您创建和分配的一个实例的引用。这意味着每当 m
的值发生变化时,无论您在何处使用引用,它也将指向同一个对象。为了解决该问题,您必须在想要使用其当前值的某个点创建对象的副本。
m_list.append(m.copy())
这将创建一个具有相同值的新实例。