如何修改回溯算法以便它可以在“和/或”图形上运行?

时间:2009-10-09 01:20:06

标签: computer-science artificial-intelligence

在人工智能中,我们研究了回溯算法。这是我们的书提供的伪代码:

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
  • SL :状态列表,列出当前路径中的状态 试过。
  • NSL :新状态列表,包含等待评估的节点。
  • DE :死胡同,列出后代未能包含的状态 目标节点。
  • CS :当前状态

我理解这一点,不仅可以手动运行算法,还可以在课堂上编写使用它的程序。

但是,现在我们的任务是修改它,以便它可以在“和/或”图表上运行。

(示例和/或图表) 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?  

这就像我在脑海中概念性地接近一样,但它仍然感觉不对。任何人都可以帮助我进一步充实它吗?

1 个答案:

答案 0 :(得分:1)

您列出的图书摘录中包含您正在寻找的解决方案。

首先,如果您不知道变量代表什么,那么您列出的伪代码很难看。我首先理解的是CS,它是当前状态的标准。然后我猜测DE是死路一条,SL是当前节点的当前状态,NSL是所有未经检查的分支。之后,我只是使用了自己对回溯算法的理解,我通常以递归方式实现。将来,请在发布一般问题时尝试使用更多描述性变量。

基本上当你到达一个OR节点时,你可以继续使用未经修改的回溯算法进行搜索,因为只要你点击一个真正的节点,它就会将成功渗透回源。但是当你到达一个AND节点时,你必须检查那个位置的所有后代并确保所有后代都是真的,或者更容易理解,只要其中一个后代是假的,你就可以回溯。

在OR节点,你假设每个人都是假的,直到被证明是真的至少一次。在AND节点,你假设每个人都是真的,直到被证明是假的至少一次。

您添加的修改应放在原始算法的else子句中。你知道它有子节点,所以你需要做的就是强制一种方法来检查所有的后代,而不是停在AND节点的单个良好实例上。您列出的修改是正确的想法,但它不符合原始伪代码的编写方式。您列出的算法不允许调用“解析CS的所有子节点”,因为这将是一个递归调用,并且您的算法需要一个直接循环。同样,如果所有子节点都是真的,将它们添加到NSL也需要递归,因为您不知道树在当前状态和直接子节点之外的深度。

我建议将其重写为递归解决方案。如果那不是一个选项,答案就不会突然出现在我身上。

如果你有一个小时,这是一个good video to watch