我正在實施迭代加深深度優先搜索以找到8 puzzle problem的解決方案。我對找到自己的實際搜索路徑並不感興趣,而只是爲了計算程序運行需要多長時間。 (我還沒有實現定時功能)。Python中的無限循環和遞歸
但是,我有一些問題試圖實現實際的搜索功能(向下滾動查看)。我粘貼了迄今爲止所有的代碼,因此如果您複製並粘貼此代碼,則也可以運行它。這可能是描述我遇到的問題的最好方法......我只是不理解爲什麼在遞歸期間我會遇到無限循環,例如,在拼圖2(p2)的測試中,第一次擴展應該產生一個解決方案。我認爲這可能與在代碼行之前不添加「返回」有關(它在下面進行了評論)。當我添加回報時,我可以通過拼圖2的測試,但像拼圖3這樣更復雜的測試失敗,因爲看起來現在的代碼只是展開最左邊的分支......
在此處for幾小時,並放棄希望。如果你能指出我的錯誤,我會非常感激這一點。謝謝!
#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)
已經有不少於3個約8拼圖其他問題在過去2天。試試[搜索](http://stackoverflow.com/search?tab=active&q=8-puzzle)。特別是[Ashwin's](http://stackoverflow.com/questions/13053455/8-puzzle-solution-executes-infinitely)問題與你的問題看起來非常相似。 – Junuxx
只是一個說明,python具有非常有限的遞歸深度。因此,明智地使用遞歸 –
有人可以解釋爲什麼(或指出我在正確的方向),爲什麼該節點不返回在DLS函數爲p2,即使if語句滿意?但是,節點IS在p1中返回(其中輸入只是解決方案)。 – Amaranthine