The idea of recursive best first search is to simulate A* search with \(O(bd)\) memory, where \(b\) is the branching factor and \(d\) is the solution depth.
is cost so far and 1
g
is the heuristic. The algorithm is reproduced below:1
h
Think of
as the best 1
node.f
where 1
bot_node.g + bot_node.h
is a node from the bottom layer in the subtree from 1
bot_node
.1
node
The part that perplexed me the most is,
If we visit
in 1
node
, it is probable that 1
RBFS(p_node)
returns 1
RBFS(node)
. Then the 1
failure, new_f
s of 1
f
will change their order, and in the next iteration, i.e., in the next recursive call of 1
p_node.successors
, we might have a different 1
RBFS
. Thus, continuing to do so, it could visit 1
min(f_limit, alternative)
twice in 1
node
.1
RBFS(p_node)
If it has already expanded
and got 1
node
, we know that from 1
failure, node.f = new_f
, it will reach a “barrier”, a frontier of at least 1
node
. Then each children, 1
f = node.f
of 1
child_node
, will meet a frontier of at least 1
node
as well. If 1
f = node.f
has 1
child_node
less than 1
child_node.g + child_node.h
, it is underestimating. The algorithm can safely replace its 1
new_f
with 1
f
.1
node.f
With consistent heuristic, the instruction is perfectly fine sine each path has non-decreasing f-values and thus
won’t be replaced by 1
child_node.f
in first 1
node.f
. Problem is, with inconsistent heuristic, sometimes when 1
RBFS(node)
is expanded at the first time, 1
node
isn’t a value from frontier, moreover, it didn’t even reach its successors. Then the 1
node.f = f.g + f.h
action makes 1
max
get a higher 1
child_node
. Therefore, the algorithm doesn’t necessarily behave like naive A* search and expand the node with least 1
f
.1
g + h