我正在尝试使用不同的算法(如BFS、DFS、A*等)来解决8数码问题,使用Python编程。对于不熟悉这个问题的朋友,8数码问题是一个由3行3列组成的游戏。你只能水平或垂直移动空白格,0代表空白格。游戏看起来像这样(由于我的账户信誉,我无法添加图片):
https://miro.medium.com/max/679/1*yekmcvT48y6mB8dIcK967Q.png
initial_state = [0,1,3,4,2,5,7,8,6]goal_state = [1,2,3,4,5,6,7,8,0] def find_zero(state): global loc_of_zero loc_of_zero = (state.index(0))def swap_positions(list, pos1, pos2): first = list.pop(pos1) second = list.pop(pos2-1) list.insert(pos1,second) list.insert(pos2,first) return list def find_new_nodes(state): if loc_of_zero == 0: right = swap_positions(initial_state,0,1) left = swap_positions(initial_state,0,3) return(right,left)find_zero(initial_state)print(find_new_nodes(initial_state))
我的问题是,我希望函数”find_new_nodes(state)”返回两个不同的列表,这样我可以根据算法选择最有前景的节点,依此类推。但我的代码输出的是两个相同的列表。
这是我的输出:([4, 0, 3, 1, 2, 5, 7, 8, 6], [4, 0, 3, 1, 2, 5, 7, 8, 6])
我该怎么做才能让它返回两个不同的列表?我的目标是使用find_new_nodes函数返回所有可能的移动,具体取决于0的位置。如果这是一个简单的问题,我深表歉意,这是我第一次做这么复杂的项目。
回答:
问题在于swap_positions
获取的是全局initial_state
的引用,而不是它的克隆。因此,swap_positions
的两次调用都在修改同一个数组。解决方案是在第一次调用时克隆数组:right = swap_positions(initial_state[:],0,1)
对于swap_positions
,可能有一个更好的解决方案:
# 请不要将变量命名为与内置名称相同def swap_positions(lis, pos1, pos2): # 创建一个包含两个元素的新元组并直接解构它 lis[pos1], lis[pos2] = lis[pos2], lis[pos1] return lis
另见这里