在人工智能中,图搜索和树搜索版本在深度优先搜索(DFS)、A*搜索方面有何区别?
在人工智能中,图搜索和树搜索版本在深度优先搜索(DFS)、A*搜索方面有何区别?
根据现有答案,似乎对于这个概念存在很多混淆。
树搜索和图搜索的区别不在于问题图形是树还是一般图形。通常假设你正在处理一般图形。区别在于用于搜索图形的遍历模式,可以是图形状或树形状。
如果你正在处理树形问题,则两种算法变体都会导致等效结果。因此,您可以选择更简单的树搜索变体。
基本的图搜索算法如下所示。使用起始节点 start
、以successors
为指向方向的边和goal
规范用于循环条件。 open
保存当前正在考虑的节点(“open list”)。请注意,以下伪代码在某些方面不正确(2)。
open <- []
next <- start
while next is not goal {
add all successors of next to open
next <- select one node from open
remove next from open
}
return next
根据您如何实现 select from open
,您可以获得不同变种的搜索算法,例如深度优先搜索(DFS)(选择最新的元素)、广度优先搜索(BFS)(选择最旧的元素)或统一代价搜索(选取路径代价最低的元素),通过选择具有最低 代价加启发式 值的节点进行的流行的A星搜索等。
上述算法实际上被称为树搜索。如果在起始状态中存在多条指向它的直接路径,则它将多次访问基础问题图的状态。如果一个状态位于定向循环中,则甚至可能无限次访问该状态。但每次访问对应于我们的搜索算法生成的不同节点中的一个。这种明显的低效率有时是有用的,稍后会解释。
正如我们所看到的,树搜索可以多次访问一个状态。因此它将探索在此状态后找到的"子树"多次,这可能是昂贵的。图搜索通过在封闭列表中跟踪所有已访问的状态来修复这个问题。 如果已知 next
的新继承者,则它不会插入开放列表中:
open <- []
closed <- []
next <- start
while next is not goal {
add next to closed
add all successors of next to open, which are not in closed
remove next from open
next <- select from open
}
return next
我们注意到图搜索需要更多的内存,因为它要跟踪所有已访问的状态。这可以通过更小的开放列表来补偿,从而提高搜索效率。
一些实现“选择”方法的技巧可以保证返回最优解——即最短路径或者具有最小成本(对于拥有边缘代价的图形)。当节点按照成本递增的顺序扩展时,或者成本是非零正常数时,这基本上是可行的。实现此类选择的常见算法包括单调费用搜索,或者如果步骤成本相同,则使用BFS或IDDFS。IDDFS避免了BFS的过度内存消耗,通常推荐在步长恒定的未知搜索(也称为暴力搜索)中使用。
此外,当与一个可接受启发式方法配合使用时,(非常流行的)A*树搜索算法也可以提供最优解。然而,只有在与一个一致(或“单调”)启发条件(比可接受性更强)配合使用时,A*图搜索算法才能提供此功能。
为了简单起见,所示代码不包括以下内容:
图形与树
但是在AI图形搜索和树搜索的情况下
图形搜索具有一个好的属性,无论使用哪种算法,每当算法探索新节点并将其标记为已访问时,该算法通常会探索从当前节点可达的所有其他节点。
例如,考虑以下具有3个顶点A B和C的图形,并考虑以下边缘
A-B,B-C和C-A,嗯,有一个从C到A的循环,
当从A开始进行DFS时,A将生成一个新状态B,B将生成一个新状态C,但是当探索C时,算法将尝试生成一个新状态A,但是A已经被访问,因此将被忽略。酷!
那么树呢?好吧,树算法不会将已访问的节点标记为已访问,但是树没有循环,它如何进入无限循环?
考虑这个树,其中有3个顶点,考虑以下边缘
A-B-C以A为根,向下。假设我们正在使用DFS算法
A将生成一个新状态B,B将生成两个状态A&C,因为树没有“如果探索了一个节点,则标记该节点已访问”,因此可能DFS算法会再次探索A,从而生成一个新状态B,因此我们陷入了无限循环。
但是你是否注意到了什么,我们正在处理无向边,即A-B和B-A之间存在连接。当然这不是一个循环,因为循环意味着顶点必须>= 3并且所有顶点都不同,除了第一个和最后一个节点。
例如A->B->A->B->A不是一个循环,因为它违反了循环属性>= 3。但确实A->B->C->A是一个循环>= 3个不同的节点已检查,第一个和最后一个节点已检查。
再次考虑树边缘,A->B->C->B->A,当然这不是一个循环,因为有两个B,这意味着不是所有节点都不同。
最后,您可以实现树搜索算法,以防止两次探索相同的节点。但是这会产生后果。
state
或node
哪个更合适取决于上下文。但是,在问题图的顶点中使用state
,在遍历图中使用node
可以明确答案。我会尽快重写它。谢谢。 - ziggystar