聪明的搜索算法’ A*算法

A*算法

    是一种启发式的搜索算法。

了解BFS、DFS或者Dijkstra算法的人应该知道。这些算法都是一种向四周盲目式搜索的方法。

 

启发式搜索:

    启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无畏的搜索路径,提到了效率。在启发式搜索中,对位置的估价是十分重要的。不同的估价可以有不同的效果。因此,A*算法的关键就在于如何建立这个启发函数。

   公式表示为:f(n)=g(n)+h(n),

  f(n) 是从初始点经由节点n到目标点的估价函数,

   g(n) 是在状态空间中从初始节点到n节点的实际代价,

   h(n) 是从n到目标节点最佳路径的估计代价。

 

A* 算法与广度、深度优先和 Dijkstra 算法的联系:

   1、g(n) = 0 时:该算法类似于DFS。

2、h(n) = 0 时:该算法类似于BFS。

3、如果h(0) = 0,只需求出g(n)(即起点到任意点n的最短路径)时,则转化成单源最短路径问题。

 

A*算法浅析:

A*算法与其他搜索路径的算法的最大区别在于其估计函数的设计,也就是公式:f(n)=g(n)+h(n)中h(n)的设计

一般计算h(n)的方法有下面几种:

1、曼哈顿距离: |x1-x2| + |y1-y2|。

2、欧式距离:  两点之间的直线距离。

3、切比雪夫距离:max(|x2-x1|,|y2-y1|)。

 这幅图中绿色的线代表欧式距离,其他均为曼哈顿距离

该图中,F6E2切比雪夫距离为:4

接下来的分析中,我们的h(n)为曼哈顿距离,g(n)为欧式路径

假设我们需要搜索的情况如下:

绿色为起始点,红色为目标,蓝色为障碍物,黑色为可通行路径。

F的值是G和H的和。第一步搜索的结果可以在下面的图表中看到。F,G和H的评分被写在每个方格里。正如在紧挨起始格右侧的方格所表示的,F被打印在左上角,G在左下角,H则在右下角

接下来我们来讲讲A*算法的流程:

1,把起始格添加到开启列表。

2,重复如下的工作:

a) 寻找开启列表中F值最低(最佳估值)的格子,把它切换到关闭列表。

b) 对相邻的格中的每一个格子进行判断

* 如果它不可通过或者已经在关闭列表中,略过它。反之如下。

* 如果它不在开启列表中,把它添加进去。把当前格作为这一格的父节点。记录这一格的F,G,和H值。

* 如果它已经在开启列表中,用G值为参考检查新的路径是否更好。更低的G值意味着更好的路径。如果是这样,就把这一格的父节点改成当前格,并且重新计算这一格的G和F值。如果你保持你的开启列表按F值排序,改变之后你可能需要重新对开启列表排序。

c) 停止,当你

* 把目标格添加进了关闭列表(注解),这时候路径被找到,或者

* 没有找到目标格,开启列表已经空了。这时候,路径不存在。

3.保存路径。从目标格开始,沿着每一格的父节点移动直到回到起始格。这就是你的路径。

下篇文章,我将使用A*算法解决一个经典的八数码问题。

from: http://blog.csdn.NET/cyh_24/article/details/8018752

时间: 2024-10-09 12:23:46

聪明的搜索算法’ A*算法的相关文章

N数码问题的启发式搜索算法--A*算法python实现

一.启发式搜索:A算法 1)评价函数的一般形式 : f(n) = g(n) + h(n) g(n):从S0到Sn的实际代价(搜索的横向因子) h(n):从N到目标节点的估计代价,称为启发函数(搜索的纵向因子); 特点: 效率高, 无回溯, 搜索算法 OPEN表 : 存放待扩展的节点. CLOSED表 : 存放已被扩展过的节点. 2)评价函数  f(x) = g(x) + h(x) 当f(x) = g(x)   时,为宽度优先搜索 当f(x) = 1/g(x)时,为深度优先搜索 当f(x) = h

算法学习笔记二(深度搜索算法)

深度搜索算法,主要是利用递归实现.递归就要有终止条件,否则就会进入死循环. 一般深度搜索算法的算法模板是: 创建一个大表, data[m][n]; int DFS(int i, int j) { max=0;用于返回的数值 if(满足递归条件) { DFS(int a,int b);//再进入下一层递归 } .... return max+1;   //以上递归不满足的话,就返回. } 一般为了更高的效率,使用了剪枝法 用另外一个数组记录 count[m][n]; DFS(int i, int

数据结构(DataStructure)与算法(Algorithm)、STL应用

catalogue 0. 引论 1. 数据结构的概念 2. 逻辑结构实例 2.1 堆栈 2.2 队列 2.3 树形结构 2.3.1 二叉树 3. 物理结构实例 3.1 链表 3.1.1 单向线性链表 3.1.2 单向循环链表 3.1.3 双向线性链表 3.1.4 双向循环链表 3.1.5 数组链表 3.1.6 链表数组 3.1.7 二维链表 3.2 顺序存储 4. 算法 4.1 查找算法 4.2 排序算法 0. 引论 0x1: 为什么要学习数据结构 N.沃思(Niklaus  Wirth)教授提

我们为什么不能只用O记号来谈论算法?

在刷LeetCode-1TwoSum的时候,有个人在论坛留言,大致意思如下: 我的算法击败了90%的人,O(nlgn)算法比O(n)算法快. 我觉得这个人是不懂算法的.让我一步一步解释. # O的含义 通俗的说,O表示忽略系数的复杂度上限,常常用一个量级表示,比如n,nlgn. # 忽略的系数重要吗 重要.我觉得<算法>比<算法导论>优秀的原因之一是,作者用实例证明,在不少情况下,复杂度之前的系数很重要.比如,系数可以导致O(n^2)的插入排序可以比O(nlgn)快速排序快. 可以

JVM垃圾回收算法 总结及汇总

先看一眼JVM虚拟机运行时的内存模型: 1.方法区 Perm(永久代.非堆) 2.虚拟机栈 3.本地方法栈 (Native方法) 4.堆 5.程序计数器 1 首先的问题是:jvm如何知道那些对象需要回收 ? 目前两种标识算法.三种回收算法.两种清除算法.三种收集器 引用计数法 每个对象上都有一个引用计数,对象每被引用一次,引用计数器就+1,对象引用被释放,引用计数器-1,直到对象的引用计数为0,对象就标识可以回收 这个可以用数据算法中的图形表示,对象A-对象B-对象C 都有引用,所以不会被回收,

JVM垃圾回收算法(最全)

JVM垃圾回收算法(最全) 下面是JVM虚拟机运行时的内存模型: 1.方法区 Perm(永久代.非堆) 2.虚拟机栈 3.本地方法栈 (Native方法) 4.堆 5.程序计数器 1 首先的问题是:jvm如何知道那些对象需要回收 ? 目前两种标识算法.三种回收算法.两种清除算法.三种收集器 引用计数法 每个对象上都有一个引用计数,对象每被引用一次,引用计数器就+1,对象引用被释放,引用计数器-1,直到对象的引用计数为0,对象就标识可以回收 这个可以用数据算法中的图形表示,对象A-对象B-对象C

谈论算法

不能只用O记号来谈论算法? 在刷LeetCode-1TwoSum的时候,有个人在论坛留言,大致意思如下: 我的算法击败了90%的人,O(nlgn)算法比O(n)算法快. 我觉得这个人是不懂算法的.让我一步一步解释. # O的含义 通俗的说,O表示忽略系数的复杂度上限,常常用一个量级表示,比如n,nlgn. # 忽略的系数重要吗 重要.我觉得<算法>比<算法导论>优秀的原因之一是,作者用实例证明,在不少情况下,复杂度之前的系数很重要.比如,系数可以导致O(n^2)的插入排序可以比O(

游戏中的AI算法总结与改进

参考文章: http://games.sina.com.cn/zl/duanpian/2014-03-11/105973.shtml http://www.oschina.net/translate/understanding-steering-behaviors-collision-avoidance?cmp http://blog.csdn.net/ityuany/article/details/5509750 一. 人工智能的定义 人工智能(AI, Artificial Intellige

算法艺术与信息学竞赛书摘

<算法艺术与信息学竞赛>这本书我详细看了1.1.1.2.1.3,之后就看得不是很懂了,所以还是把摘要写出来,方便让我知道到底能学到什么. 第一章 算法与数据结构 “数据结构+算法=程序设计” 从理论分析和实际应用两方面阐述了算法与数据结构的基本知识. 1.1 概括的叙述了算法.数据结构.以及计算理论的一些概念. 1.2从实例出发,概括的介绍了一些基本算法,包括美剧.贪心.递归.递推. 1.3介绍基本数据结构,包括线性表队列.栈.树.二叉树.以及图遍历与拓扑排序. 1.4介绍了一些实用数据结构,