Computer science 如何修改回溯算法,使其能够在;和/或;图?

Computer science 如何修改回溯算法,使其能够在;和/或;图?,computer-science,artificial-intelligence,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 C

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

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:当前状态
我理解这一点,不仅手工运行了算法,而且在课堂上编写了利用它的程序

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

(示例和/或图表)

教科书中有一句话是关于回溯和/或图表的:

“和/或图形搜索只需要 略多于 搜索正则图,一个例子 其中包括回溯算法。 子体被选中为 他们回到了正轨:曾经有一条路 找到了将目标连接到起点的方法 沿节点的节点,问题 将被解决。如果路径指向 如果失败,算法可能会回溯 尝试另一个分支。在搜索中 节点,但是,必须求解(或证明为真)节点的所有后代才能求解 父节点

虽然我理解“和/或”图是什么,但我在修改上述回溯算法以使其适用于“和/或”图时遇到了困难。正如书中所说,如果它们是“或”节点,则应正常进行,但我遇到的困难是“和”节点。我需要做如下操作:

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?  

这在我的脑海中已经是概念性的接近了,但感觉还是不对。有人能帮我进一步充实一下吗?

你列出的书摘有你想要的解决方案

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

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

在或节点上,您假设每个人都为假,直到至少一次被证明为真。在和节点上,您假设每个人都为真,直到至少一次被证明为假

您添加的修改应该放在原始算法的else子句中。您知道它有子项,所以您需要做的就是强制它检查所有子代,而不是停止在单个好的实例和节点上。您列出的修改是正确的想法,但它不适合原始ps的方式eudo代码已编写。您列出的算法不允许调用“解析CS的所有子项”“因为这将是一个递归调用,而您的算法需要一个直接循环。同样,如果所有子级都为true,那么将它们添加到NSL也需要递归,因为您不知道树超出当前状态和直接子级的深度

我建议将其重写为递归解决方案。如果这不是一个选择,答案不会突然出现在我面前


如果你有一个小时的时间,这里有一个例子。

我刚刚添加了书中描述的变量。我同意,迭代(vs递归)解决方案掩盖了回溯算法概念上的简单性。但我不同意一般的长变量名和标识符:一个解释每个变量作用的传奇故事通常就足够了。长标识符会将代码量扩展到这样的程度,以至于它们会掩盖代码的重复模式,您可以在函数/宏中对其进行分解和参数化。通过这种重构,我看到了代码量的显著减少和代码清晰度的提高。