1、姚金宇,搜索专题,Outline,基本搜索策略 / DFS BFS 启发式搜索 / A* 迭代加深搜索 / IDA* 剪枝 博弈问题,最简单or最困难的算法,最简单 入门算法 所需基本知识不多,算法描述简单,思考直白 最困难 搜索不难,时间不够 如何选择搜索方法,如何选择顺序,如何剪枝 难以举一反三,搜索问题,搜索问题:在一个空间中寻找目标 搜索什么(目标) 在哪里搜索(状态空间) 在搜索中,如何扩展状态空间是关键性问题 搜索可以根据是否使用启发式信息分成 盲目搜索:只能区分当前状态是否为目标状态 启发式搜索:在搜索过程中加入与问题相关的启发信息,指导搜索的方向,盲目搜索策略,宽度优先搜索(B
2、readth-first search) 深度优先搜索(Depth-first search),宽度优先搜索,优点 目标节点如果存在,用宽度优先搜索算法总可以找到该目标节点,而且是最小(即最短路径)的节点 缺点 当目标节点距离初始节点较远时,会产生许多无用的节点,搜索效率低,双向宽度优先搜索,从初始结点和目标结点分别做广度优先搜索,每次检查两边是否重合。 Bonus: 每次扩展结点总是选择结点比较少的那边进行下次搜索,并不是机械的两边交替。,深度优先搜索,深度优先搜索也称为回溯搜索 回溯:能进则进,进不了则换,换不成则退 优点 空间需求少,深度优先搜索的存储器要求是深度约束的线性函数 问题 可
3、能搜索到错误的路径上,在无限空间中可能陷入无限的搜索 最初搜索到的结果不一定是最优的,迭代加深搜索,算法思路 总体上按照深度优先算法方法进行 对搜索深度需要给出一个深度限制dm,当深度达到了dm的时候,如果还没有找到解答,就停止对该分支的搜索,换到另外一个分支继续进行搜索。 dm从小到大依次增大(因此称为迭代加深) 迭代加深搜索是最优的,也是完备的 重复搜索深度较小的节点,是否浪费?,例 聪明的打字员,阿兰是某机密部门的打字员,她现在接到一个任务:需要在一天之内输入几百个长度固定为6的密码。当然,她希望输入的过程中敲击键盘的总次数越少越好。 不幸的是,出于保密的需要,该部门用于输入密码的键盘是
4、特殊设计的,键盘上没有数字键,而只有以下六个键:Swap0, Swap1, Up, Down, Left, Right,为了说明这6个键的作用,我们先定义录入区的6个位置的编号,从左至右依次为1,2,3,4,5,6。,例 聪明的打字员,Swap0:按Swap0,光标位置不变,将光标所在位置的数字与录入区的1号位置的数字(左起第一个数字)交换。如果光标已经处在录入区的1号位置,则按Swap0键之后,录入区的数字不变 Swap1:按Swap1,光标位置不变,将光标所在位置的数字与录入区的6号位置的数字(左起第六个数字)交换。如果光标已经处在录入区的6号位置,则按Swap1键之后,录入区的数字不变
5、Up:按Up,光标位置不变,将光标所在位置的数字加1(除非该数字是9)。例如,如果光标所在位置的数字为2,按Up之后,该处的数字变为3;如果该处数字为9,则按Up之后,数字不变 Down:按Down,光标位置不变,将光标所在位置的数字减1(除非该数字是0),如果该处数字为0,则按Down之后,数字不变,光标位置也不变 Left:按Left,光标左移一个位置,如果光标已经在录入区的1号位置(左起第一个位置)上,则光标不动 Right:按Right,光标右移一个位置,如果光标已经在录入区的6号位置(左起第六个位置)上,则光标不动。,例 聪明的打字员,当然,为了使这样的键盘发挥作用,每次录入密码之前
6、,录入区总会随机出现一个长度为6的初始密码,而且光标固定出现在1号位置上。当巧妙地使用上述六个特殊键之后,可以得到目标密码,这时光标允许停在任何一个位置。 现在,阿兰需要你的帮助,编写一个程序,求出录入一个密码需要的最少的击键次数。,例 聪明的打字员,采用广度优先搜索。 考虑到密码总数有106个,再加上光标位置,总的状态数目有6*106个。如此庞大的状态数是解题的瓶颈。把移动光标的操作Left ,Right,Swap0,Swap1和改变数值的操作Up,Down分离开 先只进行移动光标的操作,记录得到的数的排列以及光标曾经到过的位置,状态数目6!*26=46080 对上一步得到的每一个状态判断通
7、过改变光标经过的位置上的数字能否得到目标状态。,例 聪明的打字员,例: 如果通过k次可达到排列356124(其中红色表示光标达到过的位置) 最后的密码如果是371194,则通过这种方案需要一共操作k+(7-5)+(6-1)+(9-2)=14+k步最后通过所有排列方案求得的步数中取一个最小值,即为答案。,启发式搜索,所谓启发式搜索,就在于当前搜索结点往下选择下一步结点时,可以通过一个启发函数来进行选择,选择代价最少的结点作为下一步搜索结点而跳转其上(遇到有一个以上代价最少的结点,不妨选距离当前搜索点最近一次展开的搜索点进行下一步搜索)。一个经过仔细设计的启发函数,往往在很快的时间内就可得到一个搜
8、索问题的最优解,对于NP问题,亦可在多项式时间内得到一个较优解。,启发式估价函数,f(n) = g(n) + h(n) 其中f(n) 是节点n的估价函数,g(n)实在状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。在这里主要是h(n)体现了搜索的启发信息,因为g(n)是已知的。,若干启发式搜索算法,局部择优搜索法 在搜索的过程中选取“最佳节点”后舍弃其他的兄弟节点、父亲节点,继而继续搜索 最好优先搜索法 在每一步的估价中都把当前的节点和以前的节点的估价值比较得到一个“最佳的节点”,继而进行搜索 A*算法 如果一个估价函数可以找出最短的路径,我们称之为可采纳性
9、 。A*算法是一个可采纳的最好优先算法。,A*算法,f(n) = g(n) + h(n) f(n)是估价函数,g(n)表示从起始搜索点到当前点的代价(通常用某结点在搜索树中的深度来表示)。 h(n)是n到目标的最短路经的启发值。由于这个f(n)其实是无法预先知道的,所以我们用前面的估价函数f(n)做近似。g(n)代替g(n),但 g(n)=g(n)才可;h(n)代替h(n),但h(n)=h(n)才可。,A*算法的条件,一种具有f(n)=g(n)+h(n)策略的启发式算法能成为A*算法的充分条件是: 1)搜索树上存在着从起始点到终了点的最优路径。 2)问题域是有限的。 3)所有结点的子结点的搜索
10、代价值0。 4)h(n)=h*(n) (h*(n)为实际问题的代价值)。 当此四个条件都满足时,一个具有f(n)=g(n)+h(n)策略的启发式算法能成为A*算法,并一定能找到最优解。,A*算法实现框架,初始化起始点,将其加入未搜索过点的优先队列 当队列非空且未达到终了点时获取队列头结点,并寻找其所有孩子结点;若孩子结点未在已搜索和待搜索队列中,计算其F值,并将其有序插入队列中;若在待搜索队列中且F值较小,则替换之。 输出搜索结果从已搜索队列中可逆推搜索过程,IDA*: 迭代加深的A*算法,IDA*与A*,IDA*与A*算法相比,主要的优点是对于内存的需求 A*算法需要指数级数量的存储空间,因
11、为没有深度方面的限制 而IDA*算法只有当节点n的所有子节点n的f(n)小于限制值c时才扩展它,这样就可以节省大量的内存。,搜索的剪枝,通常情况下,搜索的剪枝考虑下面几个方面: 判重:避免枚举重复的节点 最优化剪枝:如果当前部分搜索方案比目前求得的最优方案还要差,则剪枝。 可行性剪枝:如果可以判断继续按当前方向搜索下去,必定无解或者达不到最优解,则剪枝。,例 木棍问题,John有一组等长的木棍,他将它们随机地截断,使得每一节木棒都不超过50个单位长度。然后他又想要把这些木棒拼接恢复到裁切之前的长度,但他却忘了木棒的初始长度。现在给你裁切之后的所有木棒的长度,请求出初始木棒的最小可能长度。裁切后
12、木棒根数64,例 木棍问题,我们考虑从小到大枚举初始木棒的长度,然后判断这个长度可不可以由当前的木棒拼接而成。(枚举的边界?) 深度优先搜索(下面函数头仅供参考) bool check(int k, int now, int largest, int len, int tot) k:当前在拼第几根 now:当前这根拼了多长 largest: 当前未被用上的最长的木棍编号 len:初始木棒的长度 /可定义为全程变量 tot:初始木棒一共需要多少根 /可定义为全程变量 搜索的时候把木棒按长度排序,每次选木棒都选尽量长的。,例 木棍问题,剪枝1:每次开始拼新棍子的时候,必定选择剩下的木棒里面最长的一
13、根,作为组成该棍子的第一根木棒。如果此路不通,则可以直接回溯。剪枝2:由于长度相同的木棒是没有差别的,可以它们合并起来,每次只需枚举该长度用多少根即可。剪枝3:,例 植物大战僵尸,你有一些钱,可以用来购买僵尸。你的任务是在尽量过更多的关的前提下,得到的金钱越多越好。每一关你的任务就是购买僵尸来摧毁植物。植物生长在一块5*5的草坪上(如图)。你可以将购买到的僵尸立刻放在某一行上(也可以一次放多个),然后该僵尸会自动去摧毁该行的植物(蜘蛛除外)。每当你完全摧毁一行的植物后,你会得到p1元钱的奖金。你能成功地摧毁一行的条件是,你在该行放置的僵尸的总攻击力(攻击力之和)大于该行植物的总防御力(防御力之
14、和),否则,你在该行放置的僵尸会全部死掉且不会摧毁该行任意一颗植物。 初始时有p3元钱,例 植物大战僵尸,例 植物大战僵尸,例 植物大战僵尸,可行性剪枝蕴涵于搜索过程中最优化剪枝:当前所剩余钱数+最多还能得到钱数=当前最优解,例 三国志XI,Its Facers turn. Now Facer can control his troops in any order and he wants to eliminate as many enemies as possible in his round. The battlefield is a matrix of N*M grids (1=N,M=
15、10) and each grid can be either grass field (represented as O) or mountain (represented as X). Grass fields might be occupied by Facers troops or enemies, but each grid can be occupied by ONLY ONE troops. Each of Facers troops can take an action of “MOVE once and ATTACK once“-which means first move
16、the troops to a target area and then attack an adjacent enemy. Note that the action of “attack first and then move” is not allowed, but “No move but attack“ and “ move and no attack“ are both legal. There are three kinds of troops-Lancers, Halberdiers and Cavaliers. Each kind of troops has an Abilit
17、y of Movement (AM) and an Ability of Attacking (AA). AM decides how far the troops can go and AA decides the damage of one soldier in the troops.,例 三国志XI,In the process of MOVE, Facers troops can move up to AM times to adjacent grids in up/left/right/down directions. Troops can go through other Face
18、rs army (considered as non-occupied-grass field) but enemies will block the way (considered as mountains). For example, if Troops A has an AM of 3 then move to any of the RED field is legal. (Where F regard as enemy troops and B is one of Facers army).X O F O X X X O A X O O B O X X O X X X,例 三国志XI,
19、In the process of ATTACK, Facers troops can deal some damage to adjacent enemy troops (adjacent in four directions in up/left/right/down). The basic damage equals to number of soldiers in the troops multiply AA of that kind of troops. When use Lancers to attack Cavaliers (represented as Lancers-Cava
20、liers), the damage will be doubled. This will also happen when Cavaliers-Halberdiers and Halberdiers-Lancers. Enemy troops will lost the same number of soldiers as the final damage point. Note that if the damage point is higher then the rest number of soldiers, the exceeded damage will be wasted.,例
21、三国志XI,可行性剪枝 维护当前所剩敌人数目 判断环的情况 最优化剪枝 当前杀敌数+接下来最优杀敌数=当前最优杀敌数,博弈问题,博弈是一类非常有意思的问题。 我们这里说的博弈是二人博弈,二人零和、全信息、非偶然的博弈。博弈双方的利益是完全对立的。 如井字棋、象棋、围棋等。,取石子游戏,取石子问题有N堆石子,其中第i堆有Pi颗石子,每次从某一堆里选出若干石子去掉(但不能不去石子),两人轮流取石,谁不能继续取谁就输了。 什么情况下先手必胜,什么情况下后手必胜?,博弈树,Alfa-beta剪枝,练习题,1184 1024 1084 1138 1168,Thank you for your attention!,THE END,A*的证明,