问题描述
嗨,我正在研究此python代码,并想知道其用于查找目标状态的搜索算法。 我想知道以下代码是否正在使用BFS或任何其他搜索算法 这段代码解决了经典的农夫,狼,白菜,山羊问题
initial = ['L','L','L']
goal = ['R','R','R']
stack = []
stack.append(initial)
def nextState(state):
if state == goal: return False
farmer = state[3]
for i,s in enumerate(state):
if s == farmer:
tryState = makeState(state,i)
if testState(tryState) and isUnique(tryState):
stack.append(tryState)
return True
return False
def makeState(s,i):
t = []
for x in s: t.append(x)
t[3] = 'R' if t[3] == 'L' else 'L'
if t[3] == 'L':
if not testState(t):
t[i] = 'R' if t[i] == 'L' else 'L'
else:
t[i] = 'R' if t[i] == 'L' else 'L'
return t
def testState(s):
if s[0] == s[1] and s[3] != s[0]: return False
if s[1] == s[2] and s[3] != s[1]: return False
return True
def isUnique(s):
if s in stack: return False
return True
while nextState(stack[-1]): pass
for i,x in enumerate(stack):
print (i)
print (x)
解决方法
简短回答
当您将下一个可能的状态添加到队列时,它将变为BFS;当您将其添加到堆栈时,它将变为DFS。
长期回答
假设我们的起始节点是S,C是某个子节点,并且每个节点都有3个子节点(为简化说明,否则没有关系)。
首先,让我们看看将子状态添加到队列时会发生什么。您将初始状态添加到队列中,队列中的当前节点为:
[S]
您从队列中获得一个节点(当前为起始节点)。您生成其下一个状态并将其添加到队列中,现在队列中的节点为:
[C1,C2,C3]
您从数据结构中选择另一个节点C1,因为它是一个队列,并生成其子节点并将其也添加到队列中:
[C2,C3,C11,C12,C13]
让我们将此过程重复几个步骤,您将从队列中获取C2和C3并执行相同的操作:
[C11,C13,C21,C22,C23,C31,C32,C33]
请注意我们的模式。我们首先扩展到0级(起始状态)的所有节点,然后扩展到1级的所有节点(起始节点的第一个子节点),现在我们将扩展到2级的节点,依此类推。这就是为什么当您找到一种解决方案时,它必须是最接近您的起始状态的原因。
现在让我们看看如果使用堆栈数据结构会发生什么。第一步是相同的,生成起始节点的所有子级并将其放入堆栈后,堆栈现在包含:
[C1,C3]
但是现在不同之处在于,您将选择最后添加的节点进行扩展:
[C1,C33]
[C1,C331,C332,C333]
...
您不必选择先在相同深度处尝试所有可能的状态,而是选择一条路径并尽可能深入。如果在C3331上找到了解决方案,您将无法确定它是否是最佳解决方案,因为C21也是一种解决方案。