[英]Maximum recursion depth exceeded in dfs using recursion in python
I have written a python code to solve the missionaries and cannibals problem using recursive dfs in python. 我编写了一个python代码,以在python中使用递归dfs解决传教士和食人族的问题。 However I keep getting this error: RecursionError: maximum recursion depth exceeded
但是我不断收到此错误:RecursionError:超过最大递归深度
I have no idea what to do about it, and I have been stuck at it for so long. 我不知道该怎么办,我已经坚持了很长时间。 Any help or suggestion will be life saving for me.
任何帮助或建议对我来说都会挽救生命。 Thanks.
谢谢。 Here is the code:
这是代码:
class State(object):
#left = 1
#right = 0 for boat
def __init__(self, missionaries, cannibals, boat):
self.missionaries = missionaries
self.cannibals = cannibals
self.boat = boat
#def __str__(self):
# return "%s, %s %s %s" % (self.by_move, self.missionaries, self.cannibals, self.boat)
def is_valid(self):
if self.missionaries < 0 or self.missionaries > 3:
return False
if self.cannibals < 0 or self.cannibals > 3:
return False
if self.boat > 1 or self.boat < 0:
return False
if self.missionaries < self.cannibals and self.missionaries > 0:
return False
# Check for the other side
if self.missionaries > self.cannibals and self.missionaries < 3:
return False
return True
def is_goal(self):
return self.missionaries == 0 and self.cannibals == 0 and self.boat == 0
def new_states(self):
op = -1 # Subtract
boat_move = "from left shore to right"
if self.boat == 0:
op = 1 # Add
boat_move = "from right shore to left"
for x in range(3):
for y in range(3):
by_move = "Move %s missionaries and %s cannibals %s" % (x, y, boat_move)
new_state = State(self.missionaries + op * x, self.cannibals + op * y, self.boat + op * 1)
if x + y >= 1 and x + y <= 2 and new_state.is_valid():
yield new_state
class Node(object):
def __init__(self, parent, state, depth):
self.parent = parent
self.state = state
self.depth = depth
def children(self):
for state in self.state.new_states():
yield Node(parent=self, state=state, depth=self.depth + 1)
def extract_solution(self):
print
"Extracting soln"
solution = []
node = self
solution.append(node)
while node.parent is not None:
solution.append(node.parent)
node = node.parent
solution.reverse()
return solution
def dfs(root,visited,sol = None):
if root in visited:
return
if root is None:
return
visited.append(root)
if root.state.is_goal():
sol = root
return
for child in root.children():
if child not in visited:
dfs(child,visited,sol)
def main():
initial_state = State(3,3,1)
root = Node(parent = None, state = initial_state,depth = 0)
visited = []
sol = Node(parent = None, state = initial_state,depth = 0)
dfs(root,visited,sol)
ans = sol.extract_solution()
print(ans)
if __name__ == '__main__':
main()
There were two issues: 有两个问题:
1: your list 'visited' didn't properly keep track of all the states. 1:您的“已访问”列表未正确跟踪所有状态。 This can easily be fixed by making visited a global variable (by putting it in front of the def main() as done in the final solution)
可以通过访问全局变量来轻松解决此问题(如最终解决方案中所述,将其放在def main()前面)
2: The program was searching possibilities that weren't going to ever help (eg: bringing the same guy back and forth), this 2:程序正在寻找永远无法帮助的可能性(例如:来回带同一个家伙),这
if root in visited:
return
if root is None:
return
didn't solve this because it's never the same root object (even if the root.state.missionaries, cannibals and boat are the same value), so I changed this using a dictionary object: 不能解决这个问题,因为它永远不会是同一个根对象(即使root.state.missionaries,cannibals和boat是相同的值),因此我使用了一个字典对象来更改它:
if root is None:
return
state = str(root.state.missionaries) + ',' + str(root.state.cannibals) + ',' + str(root.state.boat)
if state in routes:
if routes[state] < root.depth:
return
else:
routes[state] = root.depth
else:
routes[state] = root.depth
visited.append(root)
This results in the following code (it returns an answer, I'm not sure if it's the correct one because I don't know the missionaries and cannibals problem) 这将导致以下代码(它返回一个答案,我不确定这是正确的答案,因为我不知道传教士和食人族的问题)
class State(object):
#left = 1
#right = 0 for boat
def __init__(self, missionaries, cannibals, boat):
self.missionaries = missionaries
self.cannibals = cannibals
self.boat = boat
#def __str__(self):
# return "%s, %s %s %s" % (self.by_move, self.missionaries, self.cannibals, self.boat)
def is_valid(self):
if self.missionaries < 0 or self.missionaries > 3:
return False
if self.cannibals < 0 or self.cannibals > 3:
return False
if self.boat > 1 or self.boat < 0:
return False
if self.missionaries < self.cannibals and self.missionaries > 0:
return False
# Check for the other side
if self.missionaries > self.cannibals and self.missionaries < 3:
return False
return True
def is_goal(self):
return self.missionaries == 0 and self.cannibals == 0 and self.boat == 0
def new_states(self):
op = -1 # Subtract
boat_move = "from left shore to right"
if self.boat == 0:
op = 1 # Add
boat_move = "from right shore to left"
for x in range(3):
for y in range(3):
by_move = "Move %s missionaries and %s cannibals %s" % (x, y, boat_move)
new_state = State(self.missionaries + op * x, self.cannibals + op * y, self.boat + op * 1)
if x + y >= 1 and x + y <= 2 and new_state.is_valid():
yield new_state
class Node(object):
def __init__(self, parent, state, depth):
self.parent = parent
self.state = state
self.depth = depth
def children(self):
for state in self.state.new_states():
yield Node(parent=self, state=state, depth=self.depth + 1)
def extract_solution(self):
print "Extracting soln"
solution = []
node = self
solution.append(node)
while node.parent is not None:
solution.append(node.parent)
node = node.parent
solution.reverse()
return solution
def dfs(root,sol = None):
if root is None:
return
state = str(root.state.missionaries) + ',' + str(root.state.cannibals) + ',' + str(root.state.boat)
if state in routes:
if routes[state] < root.depth:
return
else:
routes[state] = root.depth
else:
routes[state] = root.depth
visited.append(root)
if root.state.is_goal():
sol = root
return
for child in root.children():
if child not in visited:
dfs(child,sol)
visited = []
routes = {}
def main():
initial_state = State(3,3,1)
root = Node(parent = None, state = initial_state,depth = 0)
sol = Node(parent = None, state = initial_state,depth = 0)
dfs(root,sol)
ans = sol.extract_solution()
print(ans)
if __name__ == '__main__':
main()
PS. PS。 as @PM 2Ring said, for next time: please fix your indentation when asking questions, it makes reading your code easier to understand.
就像@PM 2Ring所说的那样,下一次:问问题时请修正缩进,这会使阅读代码更容易理解。 You can do this by selecting all your code, adding a tab to all lines selected and then copying it.
您可以通过选择所有代码,在所有选中的行中添加一个标签,然后复制它来完成此操作。 Before you paste it make sure there's an empty line.
粘贴之前,请确保有一个空行。 :)
:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.