更新:搜索第一个解决方案。
对于普通的深度优先搜索,很简单,只需使用哈希集合。
bool DFS (currentState) =
{
if (myHashSet.Contains(currentState))
{
return;
}
else
{
myHashSet.Add(currentState);
}
if (IsSolution(currentState) return true;
else
{
for (var nextState in GetNextStates(currentState))
if (DFS(nextState)) return true;
}
return false;
}
然而,当它受到深度限制时,我不能简单地这样做。
bool DFS (currentState, maxDepth) =
{
if (maxDepth = 0) return false;
if (myHashSet.Contains(currentState))
{
return;
}
else
{
myHashSet.Add(currentState);
}
if (IsSolution(currentState) return true;
else
{
for (var nextState in GetNextStates(currentState))
if (DFS(nextState, maxDepth - 1)) return true;
}
return false;
}
因为在达到
maxdepth
之前,它不会进行完整的搜索(从某种意义上说,总能找到解决方案),应该如何修复它?这会增加算法的空间复杂度吗?还是根本不需要记忆状态。更新:例如,一个决策树如下:
A - B - C - D - E - A
|
F - G (Goal)
从状态 A 开始,G 是目标状态。很明显,在深度 3 下有解决方案。
然而,在深度 4 下使用我的实现时,如果搜索方向恰好为
A(0) -> B(1) -> C(2) -> D(3) -> E(4) -> F(5)
超出深度,则会返回到 A
,但 E
已被访问,它将忽略检查方向 A - E - F - G
。
DFS(child)
,而应该是for (each child) DFS(child)
。否则,你永远无法回溯。 - ShahbazmyHashSet.Contains(E)
将被检查,因为它是在 currentState = A 下的 for 循环中从DFS(E,maxDepth-1)
调用的。所以,当它回溯到 A 并检查其子节点 E 时,由于它已经被访问过了,它将自动被忽略。 - colinfang