授课视频:算法设计与分析(进阶篇) 5.3
https://www.bilibili.com/video/BV1aE411p7pt?p=18
1.A*简介
A算法试图寻找best-First算法的最优解,什么情况下可能是最优解?
A算法和分支界限的不同?
- 分支界限算法的策略主要是剪掉不能得到最优解的侧枝
- A*算法的核心是告诉我们在某些情况下, 我们得 到的解一定是优化解, 于是算法可以停止,试图尽早地发现优化解 ,常使用Best-first策略求解优化问题
2. A*算法
2.1 A*算法关键—代价函数
对于任意节点n
- g ( n ) = g(n)= g(n)=从树根到n的代价,这个很好计算
- h ∗ ( n ) = h^*(n)= h∗(n)=从n到目标节点的优化路径的代价
- f ∗ ( n ) = g ( n ) + h ∗ ( n ) f^*(n)=g(n) + h^*(n) f∗(n)=g(n)+h∗(n)是节点n的代价 。
但是如何得到h*(n)?
- 不知道
那咋办嘛?
- 估计h*(n)
怎么估计?
- 使用任何方法去估计h*(n), 用h(n)表示h*(n)的估计
- 只要保证h(n)≤h*(n)总为真即可
- 于是f(n)=g(n)+h(n)≤g(n)+h*(n)=f*(n) 定义为n的总代价(包含之前和之后的代价)
举个例子
对于一个最短路径问题:
要求输出: 发现一个从S到T的最短路径
首先我们从S点出发:
显然有 g(
V
1
V_1
V1)=2, g(
V
2
V_2
V2)=3, g(
V
3
V_3
V3)=4
估计
h
∗
(
n
)
:
h^*(n):
h∗(n):
然后我们再看
V
1
V_1
V1,直观分析这个图我们可以知道这个点到T的距离
2
+
3
=
5
2+3=5
2+3=5,
但是在搜索的时候,因为我们还没有遍历后面的节点,所以我们无法提前确定这个
2
+
3
=
5
2+3=5
2+3=5
在搜索的时候我们可以看到的只有
V
1
V_1
V1的两条出边,分别是权值为
3
3
3的到
V
2
V_2
V2点和权值为
2
2
2的到
V
4
V_4
V4点,那么显然就有要是从
V
2
V_2
V2出发走到T的话,走过路径的权重必然大于2与3中的最小值(2),
h
∗
h^*
h∗(
V
1
V_1
V1)≥2, 那么我们就可以选择h(n)=2为
h
∗
h^*
h∗(
V
1
V_1
V1)的估计值
则
f
(
V
1
)
=
g
(
V
1
)
+
h
(
V
1
)
=
4
f(V_1)=g(V_1)+h(V_1)=4
f(V1)=g(V1)+h(V1)=4为对
V
1
V_1
V1估算的代价
2.2 A*算法本质—已经发现的解是优化解
定理1 使用Best-first策略搜索树, 如果A*选择的节点是目标节点, 则该节点表示的解是优化解.
证明. 令n是任意扩展到的节点, t是选中目标节点.
往证: f ( t ) = g ( t ) f(t)=g(t) f(t)=g(t) 是优化解代价.
(1)A算法使用Best-first策略, f ( t ) ≤ f ( n ) f(t)≤f(n) f(t)≤f(n). (Best-first总选择代价最小的扩展)
(2)A算法使用 h ( n ) ≤ h ∗ ( n ) h(n)≤h*(n) h(n)≤h∗(n) 估计规则, f ( t ) ≤ f ( n ) ≤ f ∗ ( n ) f(t)≤f(n)≤f^*(n) f(t)≤f(n)≤f∗(n).
(3) { f ∗ f^* f∗(n) }中必有一个为优化解的代价, 令其为 f ∗ ( s ) f^*(s) f∗(s). 我 们有 f ( t ) ≤ f ∗ ( s ) f(t)≤f^*(s) f(t)≤f∗(s)
(4). t t t是目标节点 h ( t ) = 0 h(t)=0 h(t)=0, 所以 f ( t ) = g ( t ) + h ( t ) = g ( t ) ≤ f ∗ ( s ) f(t)=g(t)+h(t)=g(t)≤f^*(s) f(t)=g(t)+h(t)=g(t)≤f∗(s).
(5). f ( t ) = g ( t ) f(t)=g(t) f(t)=g(t)是一个可能解, g ( t ) ≤ f ∗ ( s ) g(t)≤f^*(s) g(t)≤f∗(s), f ( t ) = g ( t ) = f ∗ ( s ) f(t)=g(t)=f^*(s) f(t)=g(t)=f∗(s).
2.3 如何使用A*算法?
- 使用Best-first策略搜索树;
- 节点n的代价函数为 f ( n ) = g ( n ) + h ( n ) f(n)=g(n)+h(n) f(n)=g(n)+h(n), g ( n ) g(n) g(n)是从 根到n的路径代价, $ h(n)$是从n到某个目标节点的优化路径代价;
- 对于所有 n n n, 保证 h ( n ) ≤ h ∗ ( n ) h(n)≤h^*(n) h(n)≤h∗(n);
- 当选择到的节点是目标节点时, 算法停止, 返回一个优化解.
2.4 A*实战
问题的输入:
首先我们从S点出发:
g
(
V
1
)
=
2
;
g
(
V
3
)
=
4
;
g
(
V
2
)
=
3
g(V_1)=2 ;g(V_3)=4 ;g(V_2)=3
g(V1)=2;g(V3)=4;g(V2)=3
h
(
V
1
)
=
h(V_1)=
h(V1)=min{2,3}
=
2
=2
=2 ;
h
(
V
3
)
=
h(V_3)=
h(V3)=min{2}
=
2
;
=2;
=2;
h
(
V
2
)
=
h(V_2)=
h(V2)=min{2,2}
=
2
=2
=2
f
(
V
1
)
=
2
+
2
=
4
f(V_1)=2+2=4
f(V1)=2+2=4 ;
f
(
V
3
)
=
4
+
2
=
6
f(V_3)=4+2=6
f(V3)=4+2=6;
f
(
V
2
)
=
2
+
2
=
5
f(V_2)=2+2=5
f(V2)=2+2=5
然后对
f
(
)
f()
f()函数大小进行比较,选择
V
1
V_1
V1 继续拓展
每次拓展之后,选择
f
(
)
f()
f()函数大小最小的继续拓展
直到拓展到所有节点中目标节点为代价最小的节点
那么我们就可以把
T
T
T拿出来得到最优解
因为T是目标节点, 所以我们得到解:
S
→
V
1
→
V
4
→
T
S→ V_1→V_4→T
S→V1→V4→T
以上就是一个A*算法的扩展流程
3.练习题
-
批处理作业调度问题:有N个作业,分别是J1, J2, …, Jn。有2台机器。每一个作业Ji需要分别在机器1、机器2上完成。每个作业必须先由机器1处理,然后再由机器2处理。作业Ji需要机器j处理的时间为tji(1<=i<=n, j=1或2)。
对于一种作业调度方案,所有作业在机器2上最终完成处理的时间点Fji的总和称为作业调度的完成时间和。
求解最佳调度方案使其完成时间和最小。 -
素数环问题:对于正整数N,把从1到N的正整数无重复地排列成一个环,使相邻两个数的和均为素数。求解给定正整数N时的所有可行方案。例:N6时,存在“1 4 3 2 5 6”、“1 6 5 2 3 4”两个答案;N3时,无答案。
-
生日蛋糕问题:制作一个体积为Nπ的M层生日蛋糕(N<=10000, M<=20),每层都是一个圆柱体。设第i层蛋糕的为半径Ri、高度Hi的圆柱,满足Ri>Ri+1、Hi>Hi+1(i==M时除外)。现需求解一个方案使外表面面积最小。外表面面积不统计最下面一层蛋糕的下底面。
- 请写出利用A算法求解下图中S到T最短路径的计算过程,请设计其中的代价函数并说明其满足A算法所需要的条件。
5.利用A*搜索计算下图中S到T的最短路径,要求写出计算过程
- 给定一个图,设计A*算法求其前k最短路径,要求写出伪代码并证明算法能得到最优解。
- 设计A*算法求解TSP问题,要求写出伪代码并证明算法能得到最优解。
- 判断对错: A*算法一定能够得到最优解
- 比较best-first算法和A*算法