赞
踩



k = min(k, h);
设 k k k 始终保持变化的 h h h 的最小值。也就是说,对于标识为 n e w new new 的点,表明还未遍历到, k = h = i n f ( ∞ ) k=h=inf(∞) k=h=inf(∞)
对于标识为 o p e n open open 或 c l o s e d closed closed 的点, k = m i n { k , h n e w } k=min\{k,h_{new}\} k=min{k,hnew}
这样就保证了 o p e n open open 或 c l o s e d closed closed 的点代价最小
节点 X X X 根据 k k k 与 h h h 的大小还有两种状态:若 h = k h=k h=k,记为 L o w e r Lower Lower 态;若 h > k h>k h>k,记为 R a i s e Raise Raise 态,表明有更优的路径(因为此时有 k k k 更小的值,肯定有最优路径)
由于 A ∗ A* A∗ 和 D ∗ D* D∗ 的路径搜索方向相反,为避免混淆不同算法所定义的父节点、子节点概念,统一将离搜索起点更近的节点作为父节点
注意这里是搜索起点, D ∗ D* D∗ 与 A ∗ A* A∗ 反着来的,所以 D ∗ D* D∗ 的搜索起点是目标点,而 A ∗ A* A∗ 的搜索起点是 真正的那个起点
在 A ∗ A* A∗ 算法里面,是把离起点更近的点称为父节点,离目标点近的就是子节点
在 D ∗ D* D∗ 算法里面,因为搜索路径相反,所以离起点最近的点称为子节点,离目标点近的就是父节点


步骤1. 在 O p e n L i s t OpenList OpenList 中找到 k k k 值最小的那个节点 X X X 及对应的 k o l d k_{old} kold 值,并从 O p e n L i s t OpenList OpenList 当中移除
X = MIN_STATE();
if X = NULL then return -1;
k_old = GET_K_MIN();
DELETE(X);
步骤2. 判断 k o l d k_{old} kold 是否小于 h ( X ) h(X) h(X),若确实小于的话,表明节点 X X X 已经受到障碍的影响(之前说过了,假如当某一个点变成障碍物的时候,那么 h h h 值可能就会增大),那么就遍历 X X X 的邻节点看是否能够以某个邻节点作为父节点,使 N o d e s ( ) . h Nodes().h Nodes().h 变小(如果变小了,那么就变成了 L o w e r Lower Lower 态,这个前面也说过,若 h = k h=k h=k,记为 L o w e r Lower Lower 态;若 h > k h>k h>k,记为 R a i s e Raise Raise 态,表明有更优的路径(因为此时有 k k k 更小的值,肯定有最优路径))。执行上述步骤只表明 h ( X ) h(X) h(X) 可以减小,但更新之后的 h ( X ) h(X) h(X) 与 k o l d k_{old} kold 相比,谁大谁小还尚未可知,需要继续判断,所以这一步是用来判断 X X X 的父节点的
if k_old < h(X) then
for each neighbor Y of X:
if h(Y) <= k_old and h(X) > h(Y) + c(Y, X) then
//上面这条语句就是说,h(X)也就是X直接到G的代价,是要比G到Y,再加上Y到X的代价要大的,如下图解释
b(X) = Y;//找到代价更小的,就Y成为父节点
h(X) = h(Y) + c(Y, X);//然后置换之前的代价

b(X) = Y;,就是
Y
Y
Y 变成
X
X
X 的父节点if k_old = h(X),如果不能减小到
k
o
l
d
k_{old}
kold,就看步骤4步骤3. 因为不知道更新后的 k o l d k_{old} kold 与 h ( X ) h(X) h(X) 谁大谁小,所以需要继续判断,若 k o l d = h ( X ) k_{old} = h(X) kold=h(X), L o w e r Lower Lower 态,此时 X X X 无需判断,但需判断邻节点 Y Y Y 是否有必要以 X X X 作为父节点,也就是如下图
if k_old = h(X) then
for each neighbor Y of X:
if t(Y) = NEW or
(b(Y) = X and h(Y) 不等于 h(X) + c(X, Y)) or
(b(Y) = X;
INSERT(Y, h(X) + c(X, Y))


t(Y) = NEW,表明邻节点
Y
Y
Y 还未纳入
O
p
e
n
L
i
s
t
OpenList
OpenList,那么就以
X
X
X 作为父节点;b(Y) = X and h(Y) 不等于 h(X) + c(X, Y) ,表明虽然
Y
Y
Y 的父节点是
X
X
X,但是
h
(
Y
)
h(Y)
h(Y) 却与
h
(
X
)
+
C
(
X
,
Y
)
h(X) + C(X, Y)
h(X)+C(X,Y) 不相等了,表明
Y
Y
Y 的父节点
X
X
X 的
h
(
X
)
h(X)
h(X) 有过更新,可能是由于障碍引起的;b(Y) 不等于 X and h(Y) > h(X) + c(X, Y),表明现在
Y
Y
Y 的父节点不是
X
X
X,但是
Y
Y
Y 可以通过将
X
X
X 作为父节点,使得
h
(
Y
)
h(Y)
h(Y) 更小;k_old 不等于 h(X)步骤4. 若 k o l d k_{old} kold 不等于 h ( X ) h(X) h(X),则处于 R a i s e Raise Raise 态,说明节点 X X X 受到了影响,还未恢复为 L o w e r Lower Lower 态,遍历其邻域 Y Y Y
for each neighbor Y of X:
步骤4.1.
for each neighbor Y of X:
if t(Y) = NEW or
(b(Y) = X and h(Y) 不等于 h(X) + c(X, Y)) then
(b(Y) = X;
INSERT(y, h(X) + c(X, Y))
步骤4.2.
//接上面的if
else
if b(Y) 不等于 X and h(Y) > h(X) + c(X, Y) then
INSERT(X, h(X))
else
if b(Y) 不等于 X and h(Y) > h(X) + c(X, Y) and
t(Y) = CLOSED and h(Y) > k_old then
INSERT(Y, h(Y))

以上就是 D ∗ D* D∗ 算法最核心的几个步骤,可以看出算法是相当复杂,怪不得后面出现了这么多改进的 D ∗ D* D∗ 算法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。