【发布时间】:2012-10-27 20:24:35
【问题描述】:
我正在实施迭代深化深度优先搜索,以找到8 puzzle problem 的解决方案。我对自己找到实际的搜索路径不感兴趣,而只是计算程序运行需要多长时间。 (我还没有实现定时功能)。
但是,我在尝试实现实际搜索功能时遇到了一些问题(向下滚动查看)。我粘贴了到目前为止的所有代码,所以如果你复制并粘贴它,你也可以运行它。这可能是描述我遇到的问题的最佳方式......我只是不明白为什么我在递归期间会出现无限循环,例如在拼图 2 (p2) 的测试中,第一次展开应该产生一个解决方案。我认为这可能与未在其中一行代码前面添加“Return”有关(下面对此进行了评论)。当我添加返回时,我可以通过拼图 2 的测试,但是像拼图 3 这样更复杂的东西失败了,因为现在代码似乎只扩展了最左边的分支......
已经在这几个小时,放弃了希望。如果您能指出我的错误,我将非常感谢您对此有另一种看法。谢谢!
#Classic 8 puzzle game
#Data Structure: [0,1,2,3,4,5,6,7,8], which is the goal state. 0 represents the blank
#We also want to ignore "backward" moves (reversing the previous action)
p1 = [0,1,2,3,4,5,6,7,8]
p2 = [3,1,2,0,4,5,6,7,8]
p3 = [3,1,2,4,5,8,6,0,7]
def z(p): #returns the location of the blank cell, which is represented by 0
return p.index(0)
def left(p):
zeroLoc = z(p)
p[zeroLoc] = p[zeroLoc-1]
p[zeroLoc-1] = 0
return p
def up(p):
zeroLoc = z(p)
p[zeroLoc] = p[zeroLoc-3]
p[zeroLoc-3] = 0
return p
def right(p):
zeroLoc = z(p)
p[zeroLoc] = p[zeroLoc+1]
p[zeroLoc+1] = 0
return p
def down(p):
zeroLoc = z(p)
p[zeroLoc] = p[zeroLoc+3]
p[zeroLoc+3] = 0
return p
def expand1(p): #version 1, which generates all successors at once by copying parent
x = z(p)
#p[:] will make a copy of parent puzzle
s = [] #set s of successors
if x == 0:
s.append(right(p[:]))
s.append(down(p[:]))
elif x == 1:
s.append(left(p[:]))
s.append(right(p[:]))
s.append(down(p[:]))
elif x == 2:
s.append(left(p[:]))
s.append(down(p[:]))
elif x == 3:
s.append(up(p[:]))
s.append(right(p[:]))
s.append(down(p[:]))
elif x == 4:
s.append(left(p[:]))
s.append(up(p[:]))
s.append(right(p[:]))
s.append(down(p[:]))
elif x == 5:
s.append(left(p[:]))
s.append(up(p[:]))
s.append(down(p[:]))
elif x == 6:
s.append(up(p[:]))
s.append(right(p[:]))
elif x == 7:
s.append(left(p[:]))
s.append(up(p[:]))
s.append(right(p[:]))
else: #x == 8
s.append(left(p[:]))
s.append(up(p[:]))
#returns set of all possible successors
return s
goal = [0,1,2,3,4,5,6,7,8]
def DFS(root, goal): #iterative deepening DFS
limit = 0
while True:
result = DLS(root, goal, limit)
if result == goal:
return result
limit = limit + 1
visited = []
def DLS(node, goal, limit): #limited DFS
if limit == 0 and node == goal:
print "hi"
return node
elif limit > 0:
visited.append(node)
children = [x for x in expand1(node) if x not in visited]
print "\n limit =", limit, "---",children #for testing purposes only
for child in children:
DLS(child, goal, limit - 1) #if I add "return" in front of this line, p2 passes the test below, but p3 will fail (only the leftmost branch of the tree is getting expanded...)
else:
return "No Solution"
#Below are tests
print "\ninput: ",p1
print "output: ",DFS(p1, goal)
print "\ninput: ",p2
print "output: ",DLS(p2, goal, 1)
#print "output: ",DFS(p2, goal)
print "\ninput: ",p3
print "output: ",DLS(p3, goal, 2)
#print "output: ",DFS(p2, goal)
【问题讨论】:
-
在过去的 2 天里,关于 8-puzzles 的其他问题不少于 3 个。试试the search。尤其是Ashwin's 的问题似乎和你的很相似。
-
请注意,python 的递归深度非常有限。所以明智地使用递归
-
有人可以解释为什么(或指出我正确的方向)为什么在 p2 的 DLS 函数中没有返回节点,即使满足 if 语句?但是,节点 IS 在 p1 中返回(其中输入只是解决方案)。
标签: python depth-first-search iterative-deepening sliding-tile-puzzle