在人工智能中,我们研究了回溯算法。这是我们的书提供的伪代码:
function backtrack;
begin
SL:= [Start]; NSL := [Start]; DE := [] CS := Start;
while NSL != [] do
begin
if CS = goal (or meets goal description)
then return SL;
if CS has no children (excluding nodes already on DE, SL, and NSL)
then begin
while SL is not empty and CS = the first element of SL do
begin
add CS to DE
remove first element froM SL;
remove first element from NSL;
CS := first element of NSL;
end
add CS to SL;
end
else begin
place children of CS (except nodes already on DE, SL or NSL) on NSL;
CS := first element of NSL;
add CS to SL;
end
end
return FAIL;
end
我理解这一点,不仅可以手动运行算法,还可以在课堂上编写使用它的程序。
但是,现在我们的任务是修改它,以便它可以在“和/或”图表上运行。
(示例和/或图表) alt text http://starbase.trincoll.edu/~ram/cpsc352/notes/gifs/whereisfred.gif
教科书中有以下句子谈论回溯和/或图表:
“和/或图表搜索只需要 记录保存比 搜索常规图表,一个例子 其中是回溯算法。 或后代被检查为 他们处于回溯状态:曾经是一条道路 发现将目标连接到一个开始 节点沿或节点出现问题 将被解决。如果路径通向a 失败,算法可能会回溯 并尝试另一个分支。在搜索中 然而,和节点必须解决(或证明为真)的所有和后代才能解决 父节点。
虽然我理解“和/或”图形是什么,但我在修改上述回溯算法时遇到了麻烦,因此它可以使用“和/或”图形。正如书中所说,如果它们是“OR”节点,它应该正常进行,但我遇到的困难是“和”节点。我是否需要做以下事情:
if CS has children and is "AND" node then
resolve all children of CS
if children are all true, add children to NSL
else backtrack?
这就像我在脑海中概念性地接近一样,但它仍然感觉不对。任何人都可以帮助我进一步充实它吗?
答案 0 :(得分:1)
您列出的图书摘录中包含您正在寻找的解决方案。
首先,如果您不知道变量代表什么,那么您列出的伪代码很难看。我首先理解的是CS,它是当前状态的标准。然后我猜测DE是死路一条,SL是当前节点的当前状态,NSL是所有未经检查的分支。之后,我只是使用了自己对回溯算法的理解,我通常以递归方式实现。将来,请在发布一般问题时尝试使用更多描述性变量。
基本上当你到达一个OR节点时,你可以继续使用未经修改的回溯算法进行搜索,因为只要你点击一个真正的节点,它就会将成功渗透回源。但是当你到达一个AND节点时,你必须检查那个位置的所有后代并确保所有后代都是真的,或者更容易理解,只要其中一个后代是假的,你就可以回溯。
在OR节点,你假设每个人都是假的,直到被证明是真的至少一次。在AND节点,你假设每个人都是真的,直到被证明是假的至少一次。
您添加的修改应放在原始算法的else子句中。你知道它有子节点,所以你需要做的就是强制一种方法来检查所有的后代,而不是停在AND节点的单个良好实例上。您列出的修改是正确的想法,但它不符合原始伪代码的编写方式。您列出的算法不允许调用“解析CS的所有子节点”,因为这将是一个递归调用,并且您的算法需要一个直接循环。同样,如果所有子节点都是真的,将它们添加到NSL也需要递归,因为您不知道树在当前状态和直接子节点之外的深度。
我建议将其重写为递归解决方案。如果那不是一个选项,答案就不会突然出现在我身上。
如果你有一个小时,这是一个good video to watch。