Transcript AI: ****

AI: 问题求解
基本理论与方法
内容提要

搜索的定义

具体问题的形式化

盲信息搜索

有信息搜索/启发式搜索

优化问题的搜索算法

联机/在线搜索
搜索的定义
三国华容道
找出:
一个移动序列,放出曹操
类似游戏:数码(8,15,…, n2-1,…)
8
2
3
4
5
1
1
2
3
4
7
5
6
7
8
6
9
10 11 12
Introduced in 1878
by Sam Loyd, who
dubbed himself
“America’s greatest
puzzle-expert”
....
13 14 15
1 2 3 4
1 2 3 4
5 6 7 8 ? 5 6 7 8
=$1000
9 10 11 12
9 10 11 12
13 15 14
13 14 15
三国华容道
不
同
的
初
始
布
局
编程求解三国华容道
状态:每个“局面”
行动:可行的“移动”
实现问题:如
何在计算机内
表示“状态”和
“行动”
定义一个“搜索”问题
S
1
3
2
 State space S
 Successor function:
x  S  SUCCESSORS(x)  2S
 Initial state s0
 Goal test:
xS  GOAL?(x) =T or F
 Arc cost,路径耗散
State space S ==〉 State graph
 每个节点表示一个状态
 弧及其两个端点表示后继函
数
 可能包括多个不连通的分量
解:从初始节点“I”
到任何目标节点“G”的
一条路径(沿箭头方向)
搜索问题的“解”
G
解是路径,可能存在多条
从I到G的路径,最优解就
是路径耗散(路径上cost之
和)最小的路径
最短路径问题?
I
搜索问题的“解”
 无解
I
 解就是连通源点和
目标点的路径
G
构建好的状态空间
问题
状态定义
状态数目
8-数码
每个格子放置一个数
9!=362,880
15-数码
每个格子放置一个数
16! ~ 2.09 x 1013
24-数码
每个格子放置一个数
25! ~ 1025
八皇后问题
每行放一个皇后
88
N皇后问题
每行放一个皇后
NN
N皇后问题
任何一个位置都可以放一
个皇后
(N2)!/(N2-N+1)!
存在大量“不可达/违背约束”的状态!
n2-1 数码问题的状态空间
1 2 3 4
1 2 3 4
5 6 7 8 ? 5 6 7 8
9 10 11 12
9 10 11 12
13 15 14
13 14 15
 逆序值(每个数被逆序的次数之和)的奇偶
性,将整个状态图分为两个不联通的分量
如何证明?
 所以Sam
1
3
4
5 10 7
8
9
2
Loyd不用担心他的钱被领走!!!
6
11 12
13 14 15
n2 = 0 n3 = 0 n4 = 0
n5 = 0 n6 = 0 n7 = 1
n8 = 1 n9 = 1 n10 = 4
n11 = 0 n12 = 0n13 = 0
n14 = 0n15 = 0
 逆序值 = 7
什么是“好的”状态空间
所有状态?所有“可达的”状态?
 “不可达”状态的判断,在无解时非常重要!


状态数目: 少,越少越好?最少?状态数目一般情形
下,太多!(无法全部在计算机内表示出来<存储空间
受限>,或者遍历一次<计算时间受限>)

状态空间/状态图的设计和后继函数密切相关!
我们的搜索问题是寻找一个“状态”迁移的序列,为什么
搜索状态空间大小个状态就一定可以完成搜索任务?
数码问题的搜索时间
8-puzzle  362,880 states
0.036 sec
15-puzzle  2.09 x 1013 states
~ 55 hours
24-puzzle  1025 states
> 109 years
100 millions states/sec
基准算法:搜索整个状态图

图的宽度优先搜索算法
 生成树
Search tree
我们关心的搜索算法
仅仅搜索整个状态空间
的一小部分
 相同点:(与基准算法
比)
 算法大框架
 所有的解(可行+不可
行)构成的集合

 不同点:
 从状态图中选择的子
集S不一样
 S构成的状态图(弧)
不一样,后继函数
空间大小/解的数
量为N,则搜索过
的部分是log(N)的
多项式函数
获得状态空间/状态图后,执行“搜索”

8皇后问题和n2-1数码问题的求解方法的异同!
 8皇后问题,简单的解法就是在空棋盘上不停添加
皇后,其解是“构造”出来,构造出一个状态,然
后对状态进行目标测试,不同状态之间不迁移,
相邻两次目标测试之间的“动作序列”是“后继函
数”!(深度优先?)
 n2-1数码问题,求解过程是从初态出发,不停地
在不同状态之间迁移,直到到达目标状态
状态的解释

事物可能的抽象表示,关键属性上相同,不重要细节的影响可以忽略不计


比如棋盘的布局,棋子偏移1毫米,对布局/状态没有影响
状态空间是离散的,有限或者无限
后继函数的解释

数独求解器的例子。

每个状态可行的所有“行动”
的集合

函数的返回值,行动的结果
(后继状态)和行动的代价
(cost)

后继函数是算法设计的“关
键”!最复杂的部分
路径耗散/代价


路径耗散/代价是沿着某条边/弧,转移到下一个状态,执行动作的代价(后继函
数执行的代价),一般总是正数;

数码问题,每移动一次,代价为1

N皇后问题,每放置/撤回一个皇后,代价为1,从一个状态转移到下一个状态,花费的
代价<=2N
我们总是假设,任何一条边/弧的路径耗散/代价c总是大于等于某个正常数ε,即
c>= ε >0
Why?
目标状态

可以是一个被精确定义的状态

可以是满足某些条件的状态

可以是满足某些条件的状态集合
搜索问题

状态/状态空间/状态图

后继函数/状态转移

目标状态

初始状态

路径耗散/代价

解

形式化搜索问题,设计算法求解
具体问题的形式化
例子:8皇后问题

国际象棋棋盘上放置8个皇后,彼此间不能吃掉对方
正确的解
错误的解
形式化8皇后问题:方法一

状态,任何0,1,2,……,8个皇后在棋盘上
时的布局代表一个状态

初始状态:0个皇后在棋盘上

目标测试/目标状态:8个皇后在棋盘上,彼
此间不互吃

路径耗散:放置一个皇后,代价为1

后继函数:在一个空的格子上放置一个皇
后,得到一个新状态

高度为9的64-叉树
 ~ 64x63x...x57 ~ 3x1014 states
形式化8皇后问题:方法二
 2,057 states

状态,任何0,1,2,……,8个皇后在棋盘左
侧,且互不攻击时代表一个状态;所谓棋
盘左侧互不攻击,就是前k列每列一个皇
后,互不攻击;

初始状态:0个皇后在棋盘上

目标测试/目标状态:8个皇后在棋盘上

路径耗散:放置一个皇后,代价为1

后继函数:在k+1列放置第k+1个皇后到一
个不受攻击的位置

状态数目急剧减少!
N皇后问题

“解”是一个状态,而非从初始态到目标状态的序列;这类搜索问题,一般称为“设
计问题”

上述形式化方法二是否能“简单”求解N皇后问题?


8皇后  2057个状态

100皇后  1052个状态
能否有算法能快速求解N皇后问题?

问题特点:很多个解,解的分布较好(较均匀)
路径规划问题
禁止触碰障碍物

状态空间是什么?如何形式化?
路径规划问题的形式化:方法一

网格化地图

令小网格边长为1,则对角线距离为√2
路径规划问题的形式化:方法一

最优解,仅仅是网格化的离散空间中的最优解

解释一个序列
路径规划问题的形式化:方法二
扫描线

假设垂直扫描线从左
到右进行扫描;

遇到障碍物的顶点
(不妨设障碍物为多
边形)则暂停,标记

标记方法:对两次暂
停之间的被扫描区域
染上不同的颜色

被障碍物割裂的扫描
线获得不同颜色的区
域
路径规划问题的形式化:方法二
路径规划问题的形式化:方法二

每个染色区域用
其重心点表示

每个重心点代表
一个状态,获得
状态空间
路径规划问题的形式化:方法二

后继函数:具有相
邻边界线的色块之
间互为后继

获得状态图

边/弧的路径耗散/
代价为状态点之间
的距离
路径规划问题的形式化:方法二

解为一条路径

路径需要通过特定
的边界点

最优路径需要进一
步优化和平滑
路径规划问题的形式化:方法三

取障碍物(不妨设
为多边形)的顶点
以及初始地点和目
标地点构成图的顶
点;

对任何顶点,连接
其可视顶点(没有
被障碍物阻挡),
获得后继函数

路径耗散/代价:边
/弧的长度,顶点间
的距离
路径规划问题的形式化:方法三

最优解是连续的
搜索与AI

AI系统中搜索无处不在

路径搜索与导航

打包/邮件分发

超大规模集成电路布局设计

蛋白质比对和折叠

制药

电脑游戏

……
无信息搜索/盲搜索
(Un-informed Search)
状态图和搜索树
State graph

某些节点可能会被重复访问!!!
Search tree
搜索节点和状态
8 2
同样的状态,在树中可
能有多个节点表示,我
们先暂时认为“不同的节
点代表不同的状态”,也
就是说“节点”和“状态”
暂时是同义词
3 4 7
5 1
6
8
2
7
3
4
5
1
如果状态允许被重复访问,则即使
状态有限,搜索树也可能是无限的
6
8
2
8
2
8 4
2
7
3
4
7
3
4
7
3
5
1
6
5
1
6
5
1
6
8 2
3 4 7
5 1
6
搜索算法设计细节:节点数据结构
8 2
3 4 7
5 1
状态
父节点
6
存储信息
子节点
Depth
...
Path-Cost 3
Expanded
节点N的Depth
= 从根到N的路径长度
(根的深度为0)
3
yes
搜索算法设计细节:节点扩展
8

节点N的扩展,包括的处理:
1.
评估状态/节点N的后继函数
2
3
4
7
5
1
6
N
对后继函数返回的所有状
态,在搜索树上产生一个子
节点
节点产生  节点扩展
2.
8
2
8 4
2
3
4
7
3
7
5
1
6
5
1
6
8 2
3 4 7
5 1
6
搜索算法设计细节:搜索树的边界

搜索树的边界:未被扩展的节点集合,可能在排队等待扩展!
注意与叶节点进行区别!!
8 2
3 4 7
5 1 6
8 2 7
3 4
5 1 6
8
2
3 4 7
5 1 6
8 2
3 4 7
5 1 6
8 4 2
3
7
5 1 6
8 2
3 4 7
5 1 6
搜索算法设计细节:搜索策略

搜索树的边界实际就是等待扩展的节点集合!

等待扩展的节点用“优先队列”FRINGE来实现


INSERT(node, FRINGE)

REMOVE(FRINGE)
等待扩展节点的优先次序我们称之为“搜索策略”
搜索算法设计细节:算法框架(基准算
法)
1.
if (GOAL?(S0) ==T ) then return S0
2.
INSERT(S0, FRINGE)
3.
Repeat:
a)
if (empty(FRINGE)==T) then return failure
a.
s  REMOVE(FRINGE)
b.
For every state s’ in SUCCESSORS(s)
i.
If (GOAL?(s’) ==T ) then return path or goal state
ii.
INSERT(s’,FRINGE)
节点/状态扩展
度量算法求解问题的性能

完备性:问题有解时,算法能否保证返回一个解?问题无解
时,算法能否保证返回failure?

最优性:能否找到最优解?返回代价/路径耗散最小的路
径?

复杂性:算法需求的时间和内存
1.
状态图的大小:初态和后继函数决定,影响因素:分支因子
(后继的最大个数),最前目标状态的深度,路径的最大长
度
2.
时间复杂度:访问过的节点数目
3.
空间复杂度:同时保存在内存中节点数目的最大值
我们研究搜索算法的目标

很多搜索问题是NP-hard,比如TSP,数码问题

因此,别期望能在多项式时间内(时间复杂度是问
题规模的多项式函数)求解出问题的所有实例
(instances),没有通用算法!

没有免费的午餐

算法设计的意义:对每个instance/每类instances找
到其最有效(尽可能高效)的求解算法
无信息搜索和有信息搜索的差异
Uninformed/Blind
未扩展节点集
合FRINGE是
“无序”
Informed/Heuristic
将更有希望的节点放在未
扩展节点集合FRINGE的
前面,优先扩展
Q:如何排序或者
判断优先扩展节点?
例子:盲搜索和启发式搜索
8
2
3
4
7
5
1
6
1
2
4
5
7
8
STATE
盲搜索:s1和s2的次序是
“随机的”,树的结构确定
的,在算法实现时预先
“确定”下来的

启发式搜索:状态s2更
接近目标状态(错误位
置更少),因此可以优
先扩展状态s2
s1
3
STATE
6

s2
1
2
3
4
5
6
7
8
Goal state
基准算法(宽度优先搜索算法)的进一步解释
新节点/状态插入到未扩展节点队列FRINGE的队尾
1
2
4
FRINGE = (3, 4, 5)
3
5
6
7
FRINGE = (4, 5, 6, 7)
基准算法(宽度优先搜索算法)的进一步解释
 算法的重要参数
1.
分支因子b,后继函数返回的最大状态数目
2.
从初态到目标状态的最小深度d,或者说是
宽度优先生成树上“埋藏最浅”的目标节点的
深度
基准算法(宽度优先搜索算法)的进一步解释
 评价基准算法
 完备性?
完备的
 最优性?
如果边的权值都为1
 复杂性?
访问节点数:
1 + b + b 2 + … + bd =
(bd+1-1)/(b-1) = O(bd)
时间和内存需求的直观认知
d
2
4
6
8
10
12
14
# Nodes
111
11,111
~106
~108
~1010
~1012
~1014
Time
.01 msec
1 msec
1 sec
100 sec
2.8 hours
11.6 days
3.2 years
Memory
11 Kbytes
1 Mbyte
100 Mb
10 Gbytes
1 Tbyte
100 Tbytes
10,000 Tbytes
假设: b = 10; 1,000,000 nodes/sec; 100bytes/node
基准算法(宽度优先搜索算法)的进一步解释
 关于无解的讨论
 问题无解时,若状态空间无限大或者任意状态可被任意次
重复访问,则宽度优先搜索算法不会停止
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
?
1
2
3
4
5
6
7
8
9
10
11
12
13
15
14
基准算法的改进策略: 双向搜索
2个未扩展节点集合: FRINGE1 和 FRINGE2
s
时间和空间复杂度是 O(bd/2)  O(bd)
(假设两个方向的分支因子都是b)
问题: 两个方向的分支因子不一样会怎样?
双向搜索的进一步解释

时间复杂度:获得极大的优化O(bd/2)  O(bd) ,但是“问题本质”(指数时间
复杂度)没有变化。这已经是双向搜索带来的明显进步;

空间复杂度: O(bd/2)>>O(b),极大地“恶化”了

完备性: 完备的

最优性:边的代价都为1时,能保证最优性

双向搜索,是策略/算法框架,而非“原子的”的搜索算法,双向搜索的两个方
向(前向/反向)搜索算法,可以一样,也可以不一样

问题:总是能找到“好”的反向搜索算法吗?目标状态是单个精确描述的状态?
满足某个条件的状态集合?后继函数的逆函数“前驱函数”能方便地描述或表达
吗?(比如象棋的目标状态:获胜的布局,个数?如何描述,等等)
无信息搜索算法:深度优先搜索
 新状态/节点总是插入到队列的“队头”(栈)
1
2
4
FRINGE = (4, 5, 3)
5
3
深度优先搜索算法的评价
 完备性?
若搜索树有限,则是完备的
 最优性?
不一定是最优的
 复杂性?
访问节点数(最坏情形):
1 + b + b2 + … + bm = O(bm)
空间复杂度O(bm)
注:m是叶子节点的最大深度
深度优先搜索变型I: 回溯搜索

每次扩展节点的时候,只扩展一个节点,节省内存,最
多同时保存O(m)个节点

若深度优先搜索树是无限的,则搜索可能是不完备的,
也可能无法得到最优解
深度优先搜索变型II: 深度受限搜索


设置扩展节点的深度阈值k,当节点深度大于k时,
节点不再扩展
算法返回结果:
解
 无解failure
 深度阈值k内无解
如何容易得到k,算法性能将会
得到提升
Q: k比d(最浅目标状态的深度)大
或小时,会怎样?
深度优先搜索变型III: 迭代深入搜索

思想:使用不同的受限深度参数k=0,1,2,...不断重复执行“深度受限搜索”

目的:寻找合适的深度受限深度参数k值

带来的好处:结合了宽度优先和深度优先二者的长处(时空复杂度,完备性
和最优性)

付出的代价?
迭代深入搜索的评价
 完备性?
完备的 ,当k=d时
 最优性?
最优的,当边权值都是1时
 复杂性?
访问节点数(最坏情形):
(d+1)(1) + db + (d-1)b2 + …
+ (1) bd = O(bd)
空间复杂度O(bd)
迭代深入搜索付出的额外代价
d = 5 and b = 2
宽度优先
1
2
4
8
16
32
63
迭代深入
1x6=6
2 x 5 = 10
4 x 4 = 16
8 x 3 = 24
16 x 2 = 32
32 x 1 = 32
120
d = 5 and b = 10
宽度优先
1
10
100
1,000
10,000
100,000
111,111
迭代深入
6
50
400
3,000
20,000
100,000
123,456
对未知问题,解
的深度未知,付
出较小的代价,
迭代深入搜索是
首选的盲搜索算
法
盲搜索的比较
避免状态重复访问



深度优先搜索标记存储
需要的内存空间同宽度
优先搜索!!!!
行动可逆,则有可能会出现重复状态,如“三国华容
道”;搜索树是无限的
行动不可逆,不会出现重复状态,如“8皇后问题”的形式
化方法二;搜索树有限
如何避免?(宽度优先搜索)
 条件1:对扩展出来的状态进行标记和存储标记到visited
中(用hash table实现)
 条件2:进行比较,若新扩展出来的状态在visited中,则
放弃该状态
 问题:空间需求是多少?
深度优先搜索?
避免状态重复访问:记住所有访问过的状态

增加CLOSED表,存储所有访问过(扩展过)的节点/状态

未扩展的节点/状态用OPEN表来标识

若当前待扩展的节点/状态已经在CLOSED表中,则丢弃该
状态/节点;否则扩展当前节点/状态

上述算法框架称为“图搜索”,直接探索“状态图”空间(内存需
求巨大!)
 最优性如何保证?宽度优先搜索的实现方式可以保证!
区分“树搜索”和“图搜索”

树搜索中,不同的节点N1,N2可能表示的是相同的状态s,分
别表示从初态出发,到达状态s的两条不同路径(可能具有
不同的路径耗散)

图搜索中,相同的状态只有一个节点来表示;不同的节点代
表不同的状态;可以想象成把“树搜索”中具有相同状态的节
点合并为一个节点,得到了“图”

树的“层次遍历”算法和图的“宽度优先搜索”遍历算法
基本认知

若状态空间是无限的,一般来说,搜索是不完备的

若状态空间有限,但允许状态被任意次重复访问,
搜索一般是不完备的

若状态空间有限,访问时重复访问的节点被丢弃,
则搜索是完备的,但是一般不是最优的
代价一致的搜索

宽度优先搜索,未扩展节点集合是“随机”次序,具有隐含的
约束:

单步路径耗散都是1

优先扩展“扩展深度最小”的节点

若单步耗散因边不同而不同,会怎样?

所谓代价一致搜索:扩展的节点是使得路径消耗最低的节点。
 确保代价c>=
ε >0,(为0则会陷入无穷循环)
 未扩展节点进行了排序
 性能分析变得复杂,因问题而异。
代价一致的搜索:避免状态重复访问

采用图搜索来实现
 CLOSED表中保存每个状态的最优路径耗散(从初态出
发)
 若s在CLOSED表中,则检查s的代价(从初始状态到s的
路径耗散),并和当前路径+s的总路径耗散进行比较,取
较小的路径耗散,更新状态s的路径耗散;若s不在
CLOSED表中,则放入CLOSED中,并开始扩展;
 将s的所有不在CLOSED表中的后继状态放入OPEN表中
 重复上两步
启发式搜索/有信息的搜索
(Informed Search)
未扩展节点集合的次序,表示了搜索的“策
略”
1.
if (GOAL?(S0) ==T ) then return S0
2.
INSERT(S0, FRINGE)
3.
Repeat:
a)
if (empty(FRINGE)==T) then return failure
a.
s  REMOVE(FRINGE)
b.
For every state s’ in SUCCESSORS(s)
i.
If (GOAL?(s’) ==T ) then return path or goal state
ii.
INSERT(s’,FRINGE)
节点/状态扩展
策略:最佳优先搜索



从FRINGE中选择最佳节点进行扩展。

何为“最佳”节点?

如何求得“最佳”节点?
利用状态信息/状态描述来估计节点的“好/坏”

设计评估函数f,将搜索树的节点N映射为一个非负实数f(N) ,表示从初始状态到达某
个节点的路径耗散(越小越好!)

将整个未扩展节点集合FRINGE按增序排列,排在最前面的称为“最佳”(best),
优先进行扩展(first), Best-first search

若两个节点f值相等,则可任意指定其次序,或者添加其他的信息进行进一步排序
注意“最佳”的概念,并非指最后获得的解是最佳的;(局部贪婪)

什么时候能获得最优解?
如何设计评估函数f


搜索问题求解  算法框架  搜索策略  评估函数f的设计
常用两种方法来估计f值



符号解释:




f(N) = g(N)+h(N),完整解的路径耗散(A*算法)
f(N) = h(N),从当前节点到目标节点的路径耗散(贪婪算法)
N:当前待判决/估计/评价的节点
g(N):从初始节点到N的路径耗散
h(N):从N到目标节点的路径耗散
函数f的具体形式,因问题而异!
启发式函数,
估计值
搜索问题求解  算法框架  搜索策略  评估函数f的设计

启发式函数

一般情形下,启发式函数值由当前节点和目标节点二者所确定

例如:
5
8
1
2
3
6
4
2
1
4
5
7
3
6
7
8
N
Goal
h1(N) = 错误放置的格子数 = 6
h(N)应该保证的性质:h(N)>=0,h(Goal)=0,h(N)越小,离目标越近
数码问题的不同启发式函数
5
8
1
2
3
6
4
2
1
4
5
7
3
6
7
8

h1(N) = 错误放置的格子数 = 6

h2(N) = 所有数字到其正确位置的Manhattan距离之和
= 2 + 3 + 0 + 1 + 3 + 0 + 3 + 1 = 13

h3(N) = 逆序数之和
= n5 + n8 + n4 + n2 + n1 + n7 + n3 + n6
=4 +6 +3 +1 +0 +2 +0 +0
= 16
N
Goal
8数码问题的搜索过程:
f(N)=h(N) = 错误放置的格子数
3
5
3
4
3
4
2
4
2
3
3
0
4
5
4
1
8数码问题的搜索过程:
f(N)=g(N) + h(N)
h(N) = 错误放置的格子数
3+3
1+5
2+3
3+4
5+2
0+4
3+2
1+3
2+3
5+0
3+4
1+5
2+4
4+1
8数码问题的搜索过程:
f(N)=h(N) =所有数字到其正确位置的Manhattan距离之和
6
5
2
5
2
4
3
0
4
6
5
1
路径规划问题
N
yN
yg
h1 (N) =
(xN -xg )2 +(yN -yg )2
h2(N) = |xN-xg| + |yN-yg|
xg
xN
(Euclidean distance)
(Manhattan distance)
82
最佳优先搜索存在的局部最小问题:
引导搜索进入错误的方向
局部最小问题
降低了搜索效率
f(N) = h(N) = 到目标的直线距离
“可采纳的”(admissiable)启发式函数

假设h*(N)是节点N到目标节点的实际最优路径耗散

启发式函数h(N)是“可采纳的”,当且仅当
0  h(N)  h*(N)

总是“乐观地”估计路径耗散!!!

Why?
松弛问题:放宽问题的限制(约束),减少行动限制,获得更好的解。
用松弛问题来构造启发式函数是最常用的技术
8数码问题的启发式函数
5
8
1
2
3
6
4
2
1
4
5
7
3
6
7
8
N
Goal node
h1(N) = 错误放置的格子数 = 6 可采纳的
h2(N) = 所有数字到其正确位置的Manhattan距离之和
= 2 + 3 + 0 + 1 + 3 + 0 + 3 + 1 = 13 可采纳的
h3(N) = 逆序数之和
= n5 + n8 + n4 + n2 + n1 + n7 + n3 + n6
=4 +6 +3 +1 +0 +2 +0 +0
= 16 不可采纳的 反证法:找一个违背可采纳定义的状态
路径规划问题
h2(N) = |xN-xg| + |yN-yg|
不允许沿对角线移动,是可采纳的
水平/垂直移动一格,路径耗散为1
对角线移动一格,路径耗散为 2
h1 (N) =
h*(I) = 42
h2(I) = 8
(xN -xg )2 +(yN -yg )2 可采纳的
允许沿对角线移动,
则是不可采纳的
A*算法


f(N) = g(N) + h(N), where:

g(N) =从初始节点到N的路径耗散

h(N):从N到目标节点的路径耗散,可采纳的
启发式函数
AI中最著名的搜索算法
A*算法结论一:是完备的和最优的(树搜索)
(重复访问状态时,不丢弃新节点)

完备性证明:
1.
未扩展节点集合FRINGE中每个节点满足f(N) =
g(N)+h(N)  g(N)  d(N)e, 其中d(N) 是节点 N 的深度
2.
只要A*算法没结束,在FRINGE中至少有一个节点k属于
解代表的路径
3.
节点扩展会使得路径变长,k将最终被扩展,除非在这之
前找到一个到达目标节点的其他路径。
K
简单理解:算法搜索到树的一定深度就会结束,若深度无穷大,则
d(N)e会无穷大!
A*算法结论一:是完备的和最优的(树搜索)
(重复访问状态时,不丢弃新节点)

最优性证明

C*= 最优解的路径耗散

G’: 未扩展节点集合中“非最佳”目标节点(为什么只要考虑
目标节点?)
f(G’) = g(G’) + h(G’) = g(G’)  C*

未扩展节点集合中的节点k位于最优解的路径上:
f(K) = g(K) + h(K)  C*
所以, G’ 不会被选择扩展
 一旦某个目标节点被选择扩展,则一定是最优的!

G’
K
A*算法:树搜索实现的问题

无解时,算法可能永远运行下去(状态允许重复访问)

对于未知问题,不知道有解还是无解,怎么办?

解决办法:
 增加时间约束,超过给定时间就结束搜索;此时无解,也
不能判定问题是无解,还是搜索时间太少
 因此,产生了新问题:如何设置时间约束?(没办法!)
A*算法:图搜索的实现
明显地,启发式函数是可采纳的!
c=1
2
h = 100
1
1
2
4+90
90
100
0
2+1
f = 1+100
?
104
这时候两个候选扩展节点的f值为104和101,选择101
进行扩展,扩展的新节已经被访问过
如果丢掉,那么接下来就直接扩展104,得到非最优解
A*算法:图搜索的实现
c=1
2
h = 100
1
1
2
90
2+1
1+100
2+90
4+90
获得最优解的代价是访问了更多
的节点!
100
0
这时候实际上就是“树搜索”,且
允许状态用不同的节点表示,允
许重复访问状态!
102
104
如果不丢弃重复访问状态的节点,
那么我们可以得到最优解!
不丢弃且允许访问表示同一状态的重复节
点,会造成搜索树节点指数增加!
1
1
1+1
1
1
1
1
2
2+1
1+1
2+1
2+1
2+1
2
4
2n+1 states
4
4
4
4
O(2n) nodes
4
4
4
二难的抉择
丢弃同一已访问状
态的新产生节点
不丢弃同一已访问
状态的新产生节点
丢弃已访问状态的新节点并不总是有害的


当表示某个已访问状态的新节点产生了,同时其路径耗散估计值f大于已
有路径,则可以丢弃该新节点!

此时A*算法仍然是最优的,但是搜索树可能节点变少了(也可能仍是
指数个节点)

同一状态仍然可能会被多次访问/扩展
有没有好的可采纳的启发式函数能更有效地处理状态的重复访问问题?

一致的/单调的启发式函数

保证第一次到达某个状态时,路径是最优的,以后达到该状态,路径
耗散总是更大
N
一致的/单调的启发式函数

一致的启发式函数h:
1.
可采纳的h
2.
满足三角不等式

h(N)  C*(N)  c(N,N’) + h*(N’)
h(N) - c(N,N’)  h*(N’)
h(N) - c(N,N’)  h(N’)  h*(N’)
任何节点N和它的后继节点N’,满足h(N)  c(N,N’) + h(N’)
可采纳的
一致的
理解:随着搜索的深
度越来越深,估计的
启发式函数值越来越
准确!!!
c(N,N’)
N’
h(N)
h(N’)
(三角不等式)
违背一致性的启发式函数

不满足三角不等式
N
c(N,N’)
=10
N’
h(N’)
=10
h(N)
=100
三角不等式
8数码问题的启发式函数
5
8
1
2
3
6
4
2
1
4
5
7
3
6
7
8
N
Goal node
h1(N) = 错误放置的格子数 = 6 可采纳的,一致的
h2(N) = 所有数字到其正确位置的Manhattan距离之和
= 2 + 3 + 0 + 1 + 3 + 0 + 3 + 1 = 13 可采纳的,一致的
N
c(N,N’)
N’
h(N)
h(N’)
h(N)  c(N,N’) + h(N’)
证明?
N
c(N,N’)
路径规划问题
N’
h(N)
h(N’)
h(N)  c(N,N’) + h(N’)
h2(N) = |xN-xg| + |yN-yg|
不允许沿对角线移动,是可采纳的,一致的
水平/垂直移动一格,路径耗散为1
对角线移动一格,路径耗散为 2
h1 (N) =
h*(I) = 42
h2(I) = 8
(xN -xg )2 +(yN -yg )2 可采纳的,一致的
允许沿对角线移动,则是
不可采纳的,不一致的
A*算法结论二:若h是一致的,那么得到
当前节点的路径都是此时最优的

该结论及其证明隐含:从第二次开始
重复扩展的状态总是不如第一次扩展
证明

一致性意味着单调性: (考虑N 及其后继 N’ )
f(N) = g(N)+h(N)


g(N)+c(N,N’)+h(N’) = f(N’)
如右图,K被选择进行扩展,我们要证明此时路径到K是最优的, 即
g(K) 最小。考虑在未扩展节点集合中存在一个其他节点N,经N到K,
K此时用节点N’表示,存在一条路径,那么有:(N’和K是同一个状态
不同的节点表示)
f(N’)  f(N)  f(K)
以及
h(N’) = h(K)
K
N
所以,g(N’)  g(K)
G
N’
一致的启发式函数:作用于状态的重复访问

节点被扩展,则状态进入CLOSED表

当一个新节点N产生了
 若N表示的状态在CLOSED表中,则丢弃节点N
 若N表示的状态不在CLOSED
表中,但是在未扩
展节点集合FRINGE中(不妨设为N’),则去掉
f(N),f(N’)中较大的节点,等价于去掉g(N)和g(N’)
中较大的节点
特殊的一致的启发式函数:h≡0
一致的,当然也是可采纳的
等价于单步路径耗散相同
A*退化为宽度优先搜索,代价一致
搜索
评价/比较不同的启发式函数

若对任何节点N,都有h1(N)  h2(N),则称h2比h1更精确
5
8
1
2
3
6
4
2
1
4
5
7
3
6
7
8
STATE(N)
Goal state
 h1(N) = 错误放置的格子数目
 h2(N) = 每个数字到对应目标位置
的Manhattan距离
 h2 is more accurate than h1
A*算法结论三:当解存在时,较精确启发式函数导致的被扩展
节点集合包括在“不精确”启发式函数导致的被扩展节点集合中,除了f值相
同且等于最优解的路径耗散的那些节点。

证明

任何f(N)<C*的节点都将会被扩展(在获得最优解之前)。可用绘制
等g(N)值线的方式来逐步扩展初始状态为核心的等值线系统,在最优
解路径耗散C*围成的等值线包括了所有f(N)<C*的节点。(完备性容
易由此被证明)

所以由h1(N)  h2(N)可知,在找到最优解之前,h2扩展的节点,h1
都会进行扩展

除了最后达到最优解时,可能获得的是不同的最优目标节点!
不精确的启发式函数
会访问更多的节点!
有效分支因子b*
 b*可以度量启发式函数的有效性
 通过隐函数来定义:
n = b* + (b*)2 +...+ (b*)d
其中n是被扩展的节点数目,d是解的深度
有效分支因子和搜索效率实验结果

8数码问题,考虑无信息的迭代深入搜索、h1和h2,随机产生1200个instances

n = b* + (b*)2 +...+ (b*)d

被扩展节点数目n

d = 12, h1227, h273

d = 24,h139135, h21641
设计好的启发式函数

基本思路:求解原问题的松弛问题,获得灵感

例如8数码问题


h1的设计:假设错了数字,可以一次就放到正确位置,忽略其它所有因素

h2的设计:假设数字可以水平和垂直任意移动,忽略移动目标位置是否被占据

更复杂有效的启发式函数设计:假设数字可以水平和垂直移动,使得1,2,3,4移动
到目标位置,忽略5,6,7,8的阻挡,计算移动次数d1;使得5,6,7,8移动到目标
位置,忽略1,2,3,4的阻挡,计算移动次数d2;d1+d2就是h。(产生大约3024个状
态节点)
其他方法:从经验中学习,归纳学习,不同启发式函数的集成等
A*算法的目标:精确的、一致的启发式函数
 保证了完备性、最优性,不需要重复访问同
一个状态
 实际上,问题并没有解决。问题规模大时,
因为时空要求都是解长度的指数函数
 算法时间限制及其设置
 其它实用的,不可采纳的启发式函数,不能
保证最优性和完备性,但是能快速获得最优
解或近似最优解
迭代深入A*算法:IDA*

思想:设置f的阈值,超过f的阈值,节点不再扩展;迭代执行A*,降低A*
算法对内存的需求

要求:一致的启发式函数

算法描述:
1.
初始化f的阈值t为f(N0)
2.
重复执行
I.
执行深度优先搜索,扩展f(N)<=t的节点N
II.
重新设置t为未扩展节点中f的最小值
8数码问题的IDA*运行过程
6
5
4
5
6
6
4
Cutoff=4
f(N) = g(N) + h(N), h(N) = 错误放置的格子数目
8数码问题的IDA*运行过程
4
Cutoff=5
5
4
5
7
6
6
f(N) = g(N) + h(N), h(N) = 错误放置的格子数目
5
5
IDA*的评价
优点
不足
• 完备的、最优的
• 比A*要求的内存少
• 避免了未扩展节点集合的排序开销
• 无法充分利用内存,用的内存太少,
两次迭代之间只保留阈值t
• 无法避免重复访问不在路径上的节点
IDA*的改进:把内存
用光,不能保存节点
了,丢掉保存的一个
高耗散,最旧的节
点,再插入新的节
点,这个算法称为:
SMA*
优化问题的搜索算法
优化问题和Landscape(地貌图)
•
•
•
•
状态空间S
目标函数f
邻居算子N
定义了一个landscape:
L = (S,f,N)
想象:首先给定一个所有状态构成的
集合S,S是集合,包含元素之间是无
序的;设计一个邻居算子/后继函数,
在状态之间建立关系,形成状态图,如
左图的横坐标系统,是一个“状态图”;
在状态图形成的空间基础上,增加一维
对每个状态赋予一个目标函数值f,这样
就得到了Landscape!
什么时候用局部搜索

最优化问题:根据目标函数,找到最佳状态

不关心具体到达目标状态的路径,仅仅关心目标状态

没有目标测试!

没有路径耗散!但是有搜索过程的“轨迹”

局部搜索的轨迹、时间代价和搜索耗散相似

局部搜索是非系统化的算法(不完备的,不能确定搜索了整个状态空间),在合
理的时间内找到一个“可用的”好解

只保留当前解,内存需求极低
N-皇后问题

只关心最终状态,N个皇后之间互相不吃这个条件满足即可。

搜索过程不关心

用局部搜索求解(爬山法求解)

设定目标函数:h=互吃的皇后对数目

如右图,h=17

h=0时,获得一个解
局部搜索算法

爬山法

模拟退火

演化计算,并行的局部搜索算法

遗传算法

蚁群算法

粒子群算法

差分算法

EDA,估计分布算法

Memetic算法
梯度下降法

假设目标函数f(X)=f(x1,x2),定义在连续变量x1,x2上,最小化f

梯度下降法是一个最优化算法,通常也称为最速下降法。梯度下降法框架:
𝜕𝑓(𝑥1,𝑥2) 𝜕𝑓(𝑥1,𝑥2) t
,
] ,(梯度:变化最快的方向)
𝜕𝑥1
𝜕𝑥2
1.
计算梯度[
2.
沿着梯度方向“下山”,得到新点: 𝑋𝑛 = 𝑋 − 𝛾[
3.
If f(X) < f(Xn) then 𝑋 ← 𝑋𝑛
4.
重复步骤1-3
𝜕𝑓(𝑥1,𝑥2) 𝜕𝑓(𝑥1,𝑥2) t
,
]
𝜕𝑥1
𝜕𝑥2
𝛾是移动步长,如何设置?
直线搜索

梯度下降法的变型:

𝑋𝑛 = 𝑋 − 𝛾[

𝛾 = arg min 𝑓(𝑋 − 𝛾𝑣),𝛾的取值域为(±𝑐, ±2𝑐, ±3𝑐, …)
∗
𝜕𝑓(𝑥1,𝑥2) 𝜕𝑓(𝑥1,𝑥2) t
,
]
𝜕𝑥1
𝜕𝑥2
圆搜索?
≝ 𝑋 − 𝛾𝑣 ,𝑣可以是梯度方向或给定的其它方向
牛顿法

找函数f(x)的根x*, f(x*)=0

找f(x)在xn处的切线,以切线和x轴的交点为新点xn+1
f (x n ) - 0
f (x n )
f (x n ) 
 x n +1  x n x n +1 - x n
f (x n )

速度快!

问题:离散问题?

爬山法(最大化问题)

Function hill-climbing(problem)
1. 随机生成初始解current
2. Repeat:
2.1) 找到current的后继neighbor,满足h(neighbor)在所有后继中最小
2.2) if h(neighbor)>=h(current)
then
current  neighbor
注意条件判断中的等号!
会出现问题吗?
3. return current


上述2.1中所采用的策略称为:“best-found”,还有”first-found”策略,也就是将
current的所有邻居随机排列,然后一个一个neighbor判断其和current的h值大小,
若碰到了较大的h值,就令用neighbor替换current
另一种策略就是“随机”选择一个邻居移动,称为Random walk算法,也许不能称为算
法。就是在地图(landscape)上漫步,有点象随机采样,用来分析landscape特征
梯度信息?
爬山法评估

优点:简单、快速!内存要求低;

不足:严重依赖初值,容易陷入局部最优,不完备

简单而高效的改进:

用不同的随机初始值重启算法,对于300万个皇后问题,不到一分钟,随机初值重启的
爬山法能求解出

局部最优的存在是和邻域结构的定义相关,故就有“变”邻域结构结构的局部搜索算法。
比如迭代爬山法,到达局部最优解后,调整邻居算子,实现“扰动”,然后再回到局部搜
索。

模拟退火(=爬山法+随机行走)
模拟退火(最小化问题)

爬山法:容易陷入局部最优

模拟退火思想:小概率允许“坏”的移动,而不是像爬山法一样,每次都选最好的
移动,算法框架:
概率p的设计思想来自冶金学:
1. 随机生成初始解current
开始时刻,温度较高,有较大
2. Repeat:
概率移动到“坏”解,随着搜
2.1) 找到current的一个后继neighbor,
索的进行,温度降低,移动到
“坏”解得概率指数下降,公
2.2) if h(neighbor)<=h(current) then current  neighbor
−∆𝑓/𝑇 ,其中T是温度,
式:p
=
𝑒
2.3)else 以概率p: current  neighbor
∆𝑓 = h(neighbor)−h(current)
3. return current
是解的目标函数之差
温度T的下降过程,称为schedule, 可以证明,T下降得足够慢,算法找到最优解的概率逼近1
禁忌搜索:Tabu搜索

简单、带记忆的局部搜索算法

不能算法算法,是一种策略,可以添加到各种局部搜素算法中

算法思想:


一个长度有限的(不妨设为k)最近历史解列表Tabu-list(用队列实现)

在搜索过程中,发现的新解如果出现在Tabu-list,直接放弃

Tabu-list能一定程度上防止在局部最优动不了
Tabu-list的长度k多少最好?
从爬山法到:1+1-EA (最小化问题)

Function 1+1-Evolutionary-algorithm(problem)
1. 随机生成初始解current
2. Repeat:
2.1) 随机产生一个current的一个后继neighbor
2.2) if h(neighbor)<=h(current)
then
current  neighbor
3. return current

其中2.1)中的邻居算子能够有概率一步访问到其它任何一个解,这是一
个特殊的邻居算子(全局算子),可能不同解之间的跳转概率不一样,
一般1+1-EA会“系统地”设置这样一个概率分布
局部剪枝搜索 Local Beam Search

初始时刻,开始k个随机种子,准备执行爬山法

接下来的步骤,是循环迭代过程,可以有不同的策略:

策略一:假设每个解有N个后继,每一步会在所有Nk个后继中选择最优的k作为当前的
k个解
代价?

策略二:所有Nk个后继对应一个被选择的概率分布(比如:来自自然选择,根据适应
性来选择),选择k个出来
一种演化算法!
局部剪枝搜索典型的演化算法

采用策略二的局部剪枝搜索,在迭代循环过程中添加一个步骤:在当前k个解
中,随机选择2个,执行“交叉”算子,产生“后继/孩子”,生物学上称为“有性繁殖”

演化算法对有性繁殖的“后继/孩子”的Nk个后继(变异算子),再执行按一定概
率分布选择(选择算子)下一代“解”集合

演化算法对于“交叉”算子,“变异”算子,“选择”算子可以用各种不同的方法来定
义,产生各种演化算法的各种“变型”。
遗传算法:演化算法的典型代表
树型编码?EP

解的表示:二进制串表示一个解,遗传算法一般包括一个解集合

交叉算子:两个二进制串的混杂/分解

变异算子:二进制串的某些位置的概率“翻转”(01, 10)

选择算子:在“后继”或者“后继+当前解集”中用某种方式选择出“新的”当前解集。
演化计算的发展

算子(后继函数)的变化1:单性繁殖两性繁殖4个体杂交?


算子(后继函数)的变化2:单性繁殖两性繁殖多个个体杂交?


差分演化:x和其它三个不同a,b,c个体产生的中间个体y=a+F(b-c)进行传统的“交叉”,产生后继z
EDA:估计群体的分布,依据估计得到的分布进行采样
算子(后继函数)的变化3:存在“Queen”的某些昆虫社会系统

粒子群算法:个体和Queen交配,产生后代。模拟鸟类飞行的“从众”现象。假设群体中最佳解是
“queen”,所谓“交配”,定义为非最佳个体“面向”群体的“queen”方向,以一定的速度“靠拢”

蚁群算法:利用社会性昆虫通信的方式“信息素”来对“好解”的“分量”进行加权,利用得到的权值实
现“优胜劣汰”,这是一个“正反馈”过程。来自蚂蚁寻路的启发。

Memetic算法:EA+Local search, 演化计算的每一代迭代中,对每个个体进行local search,找
到局部最优,也就是说下一代个体是些局部最优解构成的;传统的EA交叉/变异算子来对这些局
部最优解进行“扰动”,扰动结束,重新启动局部搜索。
联机搜索/在线搜索
离线搜索和联机搜索


从制定方案的角度看:

离线搜索要给出完整的,每个将来要发生状况的应对策略;或者在给出了目标状态
后,要制定出应对策略,保证以后不管出现什么状态,都回朝着目标状态转移;如下
棋,每次落子,理想状况下都要考虑最终胜利的状态如何到达;

在线/联机搜索,仅仅依据目前的“知识”/感知和判断,来确定下一步该如何进行

理解:离线搜索问题,可认为每个节点都拥有现成每个后继及其路单步径耗散信息,
有一个“上帝”能跳脱棋局(状态图),从整体上设计和把握整个路线的规划;而在线搜
索,想象个“彷徨”“瞎转悠”的“凡人”在山中迷路了,只能够获取视野内的信息,每跨出
一步都要付出代价(路径耗散),如何规划/设计出一条最佳前进的路线?
局部搜索是离线搜索还是联机搜索?
用搜索求解问题:内容框架图
问题求解:搜索
无信息搜索
/盲搜索
有信息搜索/启发式搜索
宽度优先搜索/深度
节点评价函数f,最佳优先搜索
优先搜索/迭代深入
搜索/深度受限搜索/
代价一致搜索/双向
搜索
在线搜索/
A*
贪婪算法
A*变种
联机搜索
优化搜索
启发式函数
可采纳的
一致的
精确的
……