python - 移动功能不适用于 N-Puzzle 问题
问题描述
我正在尝试为一个 n-puzzle 问题制作一个 IDDFS 算法。但是,移动功能无法正常工作。它将输出下一步,但会更改前一个(参数)的值。任何有关如何防止这种情况发生的建议将不胜感激:)
def move_blank(i, j, n):
if i + 1 < n:
yield i + 1, j
elif i - 1 >= 0:
yield i - 1, j
elif j + 1 < n:
yield i, j + 1
elif j - 1 >= 0:
yield i, j - 1
def move(state):
[i, j, grid] = state
n = len(grid)
for pos in move_blank(i, j, n):
i1, j1 = pos
grid[i][j], grid[i1][j1] = grid[i1][j1], grid[i][j]
yield [i1, j1, grid]
grid[i][j], grid[i1][j1] = grid[i1][j1], grid[i][j]
def is_goal(state, goal):
return state == goal
def dfs_rec(puz, goal):
if is_goal(puz[-1], goal):
return puz
else:
for next_state in move(puz[-1]):
if next_state not in puz:
next_path = puz + [next_state]
solution = dfs_rec(next_path, goal)
if solution != None:
return solution
return None
goal = [0, 2, [[3, 2, 0], [6, 1, 8], [4, 7, 5]]]
test = [0, 0, [[0, 7, 1], [4, 3, 2], [8, 6, 5]]]
path = dfs_rec([test], goal)
解决方案
The problem is in move_blank
. The generated moves are not mutually exclusive, yet only one of them will be generated. Replace all elif
s with a simple if
:
def move_blank(i, j, n):
if i + 1 < n:
yield i + 1, j
if i - 1 >= 0:
yield i - 1, j
if j + 1 < n:
yield i, j + 1
if j - 1 >= 0:
yield i, j - 1
There are other, less critical, issues with implementation:
if next_state not in puz
is awfully expensive. Enumerating states and storing their id in a set would be much better (there are 362k states for an 8-puzzle, list lookup is faster than set only up to ~30 elements)- reliance on mutable arguments isn't a good practice. No immediate issues here but it might bite when you don't expect. Storing state as a 9-tuple would fix this and the previous concern.
solution = dfs_rec(next_path, goal)
This problem is solvable and would be much cheaper without recursion. Yes, wikipedia pseudocode is not optimal.- it is not IDDFS - there is no depth limit per iteration
推荐阅读
- java - 如何处理具有相同xpath的多个对象的动态变化xpath
- kendo-grid - Kendo.Grid 在“创建”操作时不会向控制器发送一些数据
- python - 使用 ib_sync 使用 Python 获取许多实时股票报价
- python-3.x - 如何更改图像中指定像素的颜色?
- sql - 从 SQL Server 到 SAP BW 的数据类型转换
- ios - Firebase 无故注销某些用户
- python - 如何使用此代码仅获取我想移动到新数据框的列?
- r - 有没有办法将多个excel文件读入R,但只能到某个创建日期?(注意:实际的 excel 文件中不存在日期。)
- javascript - 每次我调用它的树枝模板时执行 javascript
- r - R - 满足条件时替换多个字段中的值