A*算法

作者: LEO_青蛙 | 来源:发表于2020-06-01 15:38 被阅读0次

完整的A*算法描述如下:

  • 初始化open_set和close_set;
  • 将起点加入open_set中,并设置优先级为0(优先级最高);
  • 如果open_set不为空,则从open_set中选取优先级最高的节点n:
    • 如果节点n为终点,则:
      • 从终点开始逐步追踪parent节点,一直达到起点;
      • 返回找到的结果路径,算法结束;
    • 如果节点n不是终点,则:
      • 将节点n从open_set中删除,并加入close_set中;
      • 遍历节点n所有的邻近节点:
        • 如果邻近节点m在close_set中,则:
          • 跳过,选取下一个邻近节点
        • 如果邻近节点m不在open_set中,则:
          • 设置节点m的parent为节点n
          • 计算节点m的优先级
          • 将节点m加入open_set中
class Node
{
  public Node parent;
  public bool canWalk;
  public int gridX, gridY;
  public int gCost, hCost;
  public int fCost
  {
    get { return gCost + hCost; }
  }
}
void FindPath(Node startNode, Node endNode)
{
  List<Node> openSet = new List<Node>();
  List<Node> closeSet = new List<Node>();
  openSet.Add(startNode);
  while(openSet.Count > 0)
  {
    Node curNode = openSet[0];
    for(int i=1; i<openSet.Count; ++i)
    {
      if(openSet[i].fCost < curNode.fCost)
      {
        curNode = openSet[i];
      }
    }
    
    if(curNode == endNode)
    {
       GeneratePath(startNode, endNode);
       return;
    }
    
    openSet.Remove(curNode);
    closeSet.Add(curNode);

    foreach(Node node in GetNeibourhood(curNode))
    {
      if(node.canWalk == false || closeSet.Contains(node)) continue;
      if(openSet.Contains(node))
      {
        if(node.gCost > curNode.gCost + GetDistance(curNode, node))
        {
          node.gCost = curNode.gCost + GetDistance(curNode, node);
          node.parent = curNode;
        }
      }
      else
      {
        node.gCost = curNode.gCost + GetDistance(curNode, node);
        node.hCost = GetDistance(node, endNode);
        node.parent = curNode;
        openSet.Add(node);
      }
    }
  }
}

优先级计算公式:F(n) = G(n) + H(n)
G(n):节点n到开始节点的距离
H(n):节点n到结束节点的距离

启发函数:
(1)如果图形中只允许朝上下左右四个方向移动,使用曼哈顿距离(Manhattan distance)。

int deltaX = Mathf.Abs(a.gridX - b.gridX);
int deltaY = Mathf.Abs(a.gridY - b.gridY);
int distance = deltaX+deltaY;

(2)如果图形中允许朝八个方向移动,则可以使用对角距离。

int deltaX = Mathf.Abs (a.gridX - b.gridX);
int deltaY = Mathf.Abs (a.gridY - b.gridY);
if (deltaX > deltaY) {
  return 14 * deltaY + 10 * (deltaX - deltaY);
} else {
  return 14 * deltaX + 10 * (deltaY - deltaX);
}

(3)如果图形中允许朝任何方向移动,则可以使用欧几里得距离(Euclidean distance)。

int deltaX = Mathf.Abs(a.gridX - b.gridX);
int deltaY = Mathf.Abs(a.gridY - b.gridY);
float distance = Mathf.Sqrt(deltaX * deltaX + deltaY * deltaY);

相关文章

  • 匈牙利算法

    算法思想 算法流程 算法步骤 算法实现 python 算法应用

  • web开发需要知道的几个算法

    算法分类 快速排序算法 深度优先算法 广度优先算法 堆排序算法 归并排序算法

  • 机器学习算法

    机器学习的算法分监督算法和无监督 算法。监督算法包括回归算法,神经网络,SVM;无监督算法包括聚类算法,降维算法。...

  • 字符串匹配

    BF 算法和 RK 算法BM 算法和 KMP 算法

  • 垃圾回收算法有几种类型? 他们对应的优缺点又是什么?

    常见的垃圾回收算法有: 标记-清除算法、复制算法、标记-整理算法、分代收集算法 标记-清除算法 标记—清除算法包括...

  • 头条-手撕代码

    [toc] 图算法 以及最短路径算法 树算法 手写LRU 排序算法 链表算法

  • 关于一些算法

    我们平常说的算法按照使用方向加密算法,排序算法,搜索算法,优化算法,音视频处理算法,图片处理算法 1.加密解密算法...

  • 给我巨大影响的技术书籍

    算法《算法概论》《算法设计与分析基础》 Anany Levitin《算法引论》Udi Manber《算法导论》《什...

  • 缓存相关

    cache淘汰算法:LIRS 算法 缓存那些事 Redis缓存淘汰算法,LRU算法,LRU算法讲解

  • LZW压缩算法

    参考链接:超级简单的数据压缩算法—LZW算法压缩算法——lzw算法实现LZW算法 LZW 压缩算法正确图解

网友评论

      本文标题:A*算法

      本文链接:https://www.haomeiwen.com/subject/petszhtx.html