【发布时间】:2021-04-02 15:11:13
【问题描述】:
以下是伪代码实现深度优先搜索(DFS),使用一个堆栈和一个大表来标记访问过的节点:
DFS(N0):
StackInit(S)
S.push((N0, null))
if isGoal(N0) then do
return true
markVisited(N0)
S.push((null, N0))
while !isEmpty(S) then do
(N, parent) := S.pop()
R := next((N, parent))
if isNull(R) then do
continue // So no new node add to this layer.
S.push((R, parent))
if marked(R) then do
continue
if isGoal(R) then do // If it's goal don't have to explore it.
return true
markVisited(R)
if depthMax((R, parent)) then do
continue
S.push((null, R))
return false
我要解决的问题是对其进行修改:它将堆栈 S 替换为 PriorityQueue PQ。该算法用于模拟IDA*算法(这在教科书中有说明,可惜不是用英文写的,所以我不会提供参考/书名):
DFS2(N0, f, LIMIT):
PriorityQueueInit(PQ)
// A node (N, parent) stored in PQ represents a path from `N0` to `N`\
passing the node `parent`; A node with smaller value on f() is \
prioritized than those with larger value.
PQ.push((N0, null))
if isGoal(N0) then do
return true
markVisited(N0)
PQ.push((null, N0))
while !isEmpty(PQ) then do // (1)
(N, parent) := PQ.poll()
R := next((N, parent)) // (2)
if isNull(R) then do
continue
PQ.offer((R, parent))
if marked(R) then do
continue
if isGoal(R) then do
return true
markVisited(R)
if f((R, parent)) > LIMIT then do
continue
PQ.offer((null, R))
return false
- (1):在A*算法中,优先级队列用于存储还没有被探索过的节点,即open list。虽然在我提供的第一个 DFS 伪代码中,堆栈
S是关闭列表,所以我假设在第二个伪代码中PQ也是关闭列表。那么第二个伪代码如何模拟 IDA* 算法,并带有一个关闭列表? - (2):它从
PQ获取当前最小的节点,这可能不是节点N的兄弟,即它从当前子树跳转到另一个包含N的子树.这条线的目的是什么?
谁能告诉我第二种算法的正确性,即为什么它可以用于 IDA* 算法?
更新了更多信息:我在这个问题上花费了很多时间和精力,但由于以下几点,它似乎非常困难:
-
教科书中出现的所有图表都是树状绘制的,即每个节点只有一个父节点,以显示概念。这让我很困惑:第二种算法是否只适用于树?
-
考虑线
if f((R, parent)) > LIMIT then do ...如果第二个也适用于图形,而不仅仅是树,那么可能会有很多父母去
R,我应该考虑所有情况还是只考虑当前的情况,parent?
【问题讨论】:
-
(之前没遇到过Iterative Deepening A*。你能指出为什么simulate比perform更合适 i> / 实现?)
-
@greybeard:是的,我的意思是,
DFS2(N0, f, LIMIT)可以用来实现迭代深化 A*。 -
由于这篇文章中有几个问题,我不确定您期望得到什么样的答案。回答正确需要哪些分数?
-
@TomerShetah:我的困惑是我不相信第二种算法会实现 IDA* 算法。所以你只能回答这一行:“谁能告诉我第二种算法的正确性,即为什么它可以用于 IDA* 算法?”
-
@TomerShetah:不客气。
标签: algorithm search priority-queue depth-first-search