WEB开发网
开发学院软件开发VC 在A*寻路中使用二叉堆 阅读

在A*寻路中使用二叉堆

 2006-07-23 11:33:11 来源:WEB开发网   
核心提示: 无疑,我们不能只建立堆,在A*寻路中使用二叉堆(8),当不需要的时候,我们也要从堆中删除元素,这确保了你把它和较低的子节点交换,如果做错会造成不完整的堆,特别的,在A*寻路中

无疑,我们不能只建立堆,当不需要的时候,我们也要从堆中删除元素。特别的,在A*寻路中,我们在检查和切换到关闭列表之后,从堆顶需要删除F值最低的元素。

如前所述,你从把末元素移动到堆顶开始,然后把堆中的元素总数减1。伪代码是这样:

openList(1) = openList(numberOfOpenListItems)
numberOfOpenListItems = numberOfOpenListItems - 1

接着我们需要依次比较它和两个子节点的数值。如果它的F值更高,我们就把它和更低F值的子节点交换。然后我们把它和新的子节点比较(看它是否更低)。如果它的F值比两个子节点更高,我们把它和较低的一个交换。我们重复这个过程直到找到它的正确位置,这可能会一直持续到堆底,但并不是完全必要。伪代码看起来是这样:

v = 1
;Repeat the following until the item sinks to its proper spot in the binary heap.
Repeat
  u = v
  If 2*u+1 <= numberOfOpenListItems ;if both children exist
    ;Select the lowest of the two children.
    If Fcost(openList(u)) >= Fcost(openList(2*u))then v = 2*u ;SEE NOTE BELOW
    If Fcost(openList(v)) >= Fcost(openList(2*u+1))then v = 2*u+1 ;SEE NOTE BELOW
  Else If 2*u <= numberOfOpenListItems ;if only child #1 exists
    ;Check if the F cost is greater than the child
    If Fcost(openList(u)) >= Fcost(openList(2*u))then v = 2*u
  End If
  If u <> v then ; If parent''s F > one or both of its children, swap them
    temp = openList(u)
    openList(u) = openList(v)
    openList(v) = temp
  Else
    Exit ;if item <= both children, exit repeat/forever loop
  End if
Forever ;Repeat forever

请注意两行代码中粗体(红色)的u和v的数值。在第二行,你应该使用 v而不是u,这不是很显而易见。这确保了你把它和较低的子节点交换。如果做错会造成不完整的堆,完全打乱你的寻路。

上一页  3 4 5 6 7 8 9  下一页

Tags:路中 使用

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接