1.8k likes | 1.94k Views
状态空间搜索. 状态空间搜索策略 数据驱动和目标驱动的搜索 图搜索的实现 深度和广度优先搜索 有界深度优先搜索 谓词演算推理的状态空间表示法 逻辑的状态空间描述 与/或图 讨论. 基于递归的搜索 递归 递归搜索 模式驱动搜索 产生式系统 定义与历史 产生式系统示例 产生式系统搜索的控制 产生式系统的优点.
E N D
状态空间搜索 状态空间搜索策略 数据驱动和目标驱动的搜索 图搜索的实现 深度和广度优先搜索 有界深度优先搜索 谓词演算推理的状态空间表示法 逻辑的状态空间描述 与/或图 讨论
基于递归的搜索 • 递归 • 递归搜索 • 模式驱动搜索 • 产生式系统 • 定义与历史 • 产生式系统示例 • 产生式系统搜索的控制 • 产生式系统的优点
状态空间搜索策略 • 数据驱动和目标驱动的搜索 • 状态空间可以从两个方向进行搜索:从实际问题的给定数据向目标搜索或者从目标到数据进行搜索。 • 数据驱动搜索,也称为正向推理。搜索的过程是应用规则从给定的条件产生新的条件,再用规则从新的条件产生更多的新条件。这个过程持续到有一条满足目标要求的路径产生为止。
另一种求解方法是:先从欲想达到的目标开始,看哪些规则或合法移动能产生该目标以及应用这些规则产生目标时需要哪些条件。这些条件就成为我们要达到的新目标,即子目标。搜索就通过反向的、连续的子目标不断地进行,一直到找到问题给定的条件为止。这样就找到了一条从数据到目标的移动或规则组成的链,尽管搜索方向和它正好相反。这种方法称为目标驱动的推理或反向推理。另一种求解方法是:先从欲想达到的目标开始,看哪些规则或合法移动能产生该目标以及应用这些规则产生目标时需要哪些条件。这些条件就成为我们要达到的新目标,即子目标。搜索就通过反向的、连续的子目标不断地进行,一直到找到问题给定的条件为止。这样就找到了一条从数据到目标的移动或规则组成的链,尽管搜索方向和它正好相反。这种方法称为目标驱动的推理或反向推理。 • 在实际的搜索系统中可能两种方法同时使用,即一方面从数据驱动向目标进行,可能搜索到某一个子目标;另一方面又从目标向数据方面进行搜索,刚好也搜索到该子目标,这时推理也结束,即假设的目标正确。
图搜索的实现 • 无论是目标还是数据驱动的搜索,其求解问题都是要在状态空间图中找到从初态到目标状态的路径。而路径上弧的序列就对应解题的先后步骤。若在选择解题路径时能给出绝对可靠的预言或绝对正确的机制,那就不需要搜索了,求解时会一次成功地穿过空间到达目标,构造出一条求解路径来。但实际问题中没有绝对可靠的预言,求解时必须尝试多条路径直到找到目标为止。回溯是一种经常使用的技术。
图搜索的实现(续) • 带回溯的搜索从初始状态出发,不停地寻找路径一直到它到达目标或“不可解端点”。若找到目标,就退出搜索,返回解题路径,若遇到不可解结点,就回溯到路径中最近的父结点上,查看是否有当前结点的兄弟结点未扩展,并沿这些分支继续搜索。算法在每个结点上的检查过程遵循下面的递归方式:
图搜索的实现(续) • 若当前状态S未到达目标的要求,就对它的第一子状态Schild1递归调用回溯过程。如果在以Schild1为根的子图中没有找到目标,就对它的兄弟Schild2调用此过程。此过程重复进行到某个结点的后裔是目标或者所有子结点都搜索完为止。
图搜索的实现(续) • 算法就是以这种方式执行直到找到目标或遍历了状态空间为止。下图给出的是一个假设的状态空间的深度优先回溯搜索。 • 1 A • 2 B 8 C 10 D • E 3 6 F 9 G • H I J • 4 5 7 • 一个假设状态空间的深度优先回溯搜索
图搜索的实现(续) • 下面定义一个回溯搜索的算法:算法使用3张表保存状态空间中的结点。 • SL状态表列出了当前路径上的状态。如果找到了目标,SL就是解题路径上状态的有序集。 • NSL新状态表,包含了等待评估的结点,其后裔结点还未被扩展。DE不可解端点集,列出了找不到解题路径的状态。如果在搜索中再遇到它们,就会检测到它们是DE中的成分而立即将其排除。 • 为了在最普遍的情况下(是图而不是树)定义回溯算法,有必要检测并删除多次出现的某些状态,以避免造成路径循环。检测可以通过对每一个新生成的状态判断它是否在上述3张表中来实现,如果它属于某一张表,就说明它已被搜索过不必再考虑。
图搜索的实现(续) • 当前正在搜索的结点叫CS,即当前状态。CS总是等于最近加入SL中的状态,是当前正在探寻的解题路径的“前锋”。博弈中走步用的推理规则或者其他合适的问题求解操作都可应用于CS,得到一些新状态,即CS的子状态的有序集,重新视该集合中第一个状态为当前状态,其余的按次序放入NSL中,用于以后的搜索。新的CS加入SL中,搜索就这样继续进行。若CS没有子状态,就要从SL,NSL中删除它,将其加入DE,然后回溯查找NSL中的下一个状态。
图搜索的实现(续) • Function backtrack (回溯算法) • begin • SL:=[Start]; NSL:= [Start]; DE := [ ]; CS :=Start; /*初始化*/ • while NSL [ ] /*还有未检查的状态*/ • do begin • if CS = 目标(或符合目标的要求) • then return (SL); /*成功,返回路径状态的表*/ • if CS没有子状态(不包括DE,SL和NSL中已有的状态) • then begin • while((SL非空)and(CS = SL中第一个元素))
图搜索的实现(续) • do begin • 将CS加入DE;/*标明此状态不可解*/ • 从SL中删除第一个元素;/*回溯*/ • 从NSL中删去第一个元素; • CS:=NSL中第一个元素; • end; • 将CS加入SL; • end • else begin • 将CS子状态(不包括DE、SL、NSL中有的)加入NSL;
图搜索的实现(续) • CS:=NSL中第一个元素; • 将CS加入SL; • end • end; • return FAIL • end. • 假设状态空间的深度优先回溯搜索中的回溯轨迹如下: • 初值:SL = [A];NSL= [A];DE=[ ];CS=A;
图搜索的实现(续) • 重复 CS SL NSL DE • 0 A [A] [A] [ ] • 1 B [BA] [BCDA] [ ] • 2 E [EBA] [EFBCDA] [ ] • 3 H [HEBA] [HIEFBCDA] [ ] • 4 I [IEBA] [IEFBCDA] [H] • 5 F [FBA] [FBCDA] [EIH] • 6 J [JFBA] [JFBCDA] [EIH] • 7 C [CA] [CDA] [BFJEIH] • 8 G [GCA] [GCDA] [BFJEIH]
1 A • 2 B 8 C 10 D • 3 E 6 F 9 G • 4 H 5 I 7 J • 一个假想的状态空间的深度优先回溯搜索
状态空间的一般搜索过程 • 一个问题的状态空间是一个三元组,即 • <S,F,G>,其中S是问题所有可能的状态的集合,F是操作的集合,G是目标状态的集合.一般,如果问题的状态空间不太大的话,可以用显式的方式画出其状态空间图,否则用隐式的方法画出其状态空间图.对状态空间的搜索就是从图中某个初始状态出发,寻求一条到达目标状态的路径.
状态空间的一般搜索过程 • 对状态空间的搜索过程用到两张表:OPEN表和CLOSED表,它们的结构如下: • Open 表 • 状态节点 父节点 • ┆ • Closed表 • 编号 状态节点 父节点 • ┆
状态空间的一般搜索过程 • 其中open表存放刚生成的节点,对于不同的搜索策略,节点在open表中的排列顺序是不同的.例如对宽度优先搜索是先生成的节点排在前面,而对深度优先搜索则是后生成的节点排在前面. • Closed表用于存放将要扩展或者已经扩展的节点.搜索的一般过程如下:
状态空间的一般搜索过程 • (1)把初始节点S0放进open表,并建立只包含S0的图,记为G. • (2)检查open表是否为空,若为空则问题无解,退出. • (3)把open表的第一个节点取出放入closed表,并记该节点为n. • (4)考察节点n是否为目标节点,若是,则求得了问题的解,退出. • (5)扩展节点n,生成一组子节点.把其中不是
状态空间的一般搜索过程 • 节点n的先辈的那些子节点记作集合M,并把这些子节点作为节点n的子节点加入G中. • (6)针对M中子节点的不同情况,分别进行如下处理: • A)对那些未曾在G中出现过的M成员设置一个指向父节点(即节点n)的指针,并把它们放入open表. • B)对于那些先前已在G中出现的M成员,确定是否需要修改它指向父节点的指针. • C)对于那些先前已在G中出现并且已经扩展
状态空间的一般搜索过程 • 了的M成员,确定是否是需要修改其后继节点指向父节点的指针. • (7)按某种搜索策略对open表中的节点进行排序. • (8)转第2步 • 说明:上面对状态空间的搜索过程具有通用性,后面讨论的各种搜索策略都可看作是它的一个特例.各种搜索策略的主要区别仅在于open表中节点的排序准则不同.例如在宽度优先搜索中是先生成的节点排在前,在深度优先搜索中是后生成的节点排在前等.
状态空间的一般搜索过程 • 一个节点经一个算符操作后一般只生成一个子节点,但适用于一个节点的算符可能有多个,此时就会生成一组子节点.在这些子节点中可能有些是当前扩展节点(即节点n)的父节点,祖父节点等,此时不能把这些先辈节点作为当前扩展节点的子节点.余下的子节点记作集合M,并加入图G中. • 一个新生成的节点,它可能是第一次被生成的节点,也可能是先前已作为其它节点的后继节点被生成过,当前又作为另一个节点的后继节
状态空间的一般搜索过程 • 点被再次生成.此时,它应该作为哪一个节点的后继呢?一般由原始节点到该节点上所付出的代价来决定,哪条路径付出的代价小,相应的节点就作为它的父节点.
深度和广度优先搜索 • 深度优先搜索、广度优先搜索、有界深度优先搜索及最好优先搜索都与backtrack方法类似,所不同的是,它们实现了另外一些搜索策略,为求解提供了更灵活的手段。 • 广度优先搜索采取的是先横后纵的搜索策略,而深度优先搜索采取的是先纵后横的搜索策略。 • A • B C D • E F G H I J • K L M N O P Q R • S T U • 用于深度和广度优先搜索的例图
深度和广度优先搜索 • 例如在上面的深度和广度优先搜索图中,深度优先搜索的顺序是: • A,B,E,K,S,L,T,F,M,C,G,N,H,O,P,U,I,Q,J,R • 而在广度优先搜索中结点的顺序是: • A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U • 算法中设有两个表:OPEN表和CLOSED表。 OPEN表中放的是未扩展的结点, CLOSED表中放的是已扩展的结点。
深度和广度优先搜索 • 可以看出这里的open表与回溯算法中的NSL相似,而closed表则是回溯算法中SL和DE的合并. • 当对解的先验信息有所了解时(比如知道解可能落在最右分枝或最左分枝上时)深度优先搜索的速度还是很快的,如果弄错了方向可能会使搜索落入陷阱中,补救的措施是采用定界的方法—有界深度优先搜索。其思想是定一个界d,这个界d可以是深度 ,也可以是一个代价。 • 以上几种搜索方法都是盲目搜索的典型代表。
宽度优先搜索 • 宽度优先搜索的过程如下: • 1、把初始节点放入open表 • 2、如果open表为空,则问题无解,退出. • 3、把open表的第一个节点(记为n)取出放入closed表. • 4、考察节点n是否为目标节点,若是则求得了问题的解,退出。 • 5、若节点n不可扩展,则转第2步. • 6、扩展节点n将其子节点放入open表的尾部
宽度优先搜索 • 并为每一个子节点配置指向父节点指针,然后转2.其图示如p265的图6-11所示. • 例:重排九宫问题在一个33的方格棋盘上放置分别标有数字1,2,3,4,5,6,7,8的8张牌,初始状态为S0目标状态为Sg即: • S0为:2 8 3 Sg为:1 2 3 • 1 4 8 4 • 7 6 5 7 6 5
宽度优先搜索 • 可使用的算符有,空格左移,右移,上移,下移. • 宽度优先搜索的图示如p267页的图6-15.
深度优先搜索 • 深度优先搜索的过程如下: • 1、把初始节点放入open表 • 2、如果open表为空,则问题无解,退出. • 3、把open表的第一个节点(记为n)取出放入closed表. • 4、考察节点n是否为目标节点,若是则求得了问题的解,退出。 • 5、若节点n不可扩展,则转第2步. • 6、扩展节点n将其子节点放入open表的首部
深度优先搜索 • 深度优先搜索和宽度优先搜索的区别仅在于:宽度优先搜索是把节点n的子节点放入到open表的尾部,而深度优先搜索则是将节点n的子节点放入open表的首部.深度优先搜索重排九宫的例子见p268页的图6-16.
有界深度优先搜索 • 为了解决深度优先搜索不完备的问题,避免搜索过程陷入无穷分支的死循环,提出了有界深度优先搜索方法.其过程如下: • 1、把初始节点放入open表,置S0深度d(S0)=0 • 2、如果open表为空,则问题无解,退出. • 3、把open表的第一个节点(记为n)取出放入closed表.
有界深度优先搜索 • 4、考察节点n是否为目标节点,若是则求得了问题的解,退出。 • 5、若节点n的深度d(n)=dm则转2. • 6、若节点n不可扩展,转2 • 7、扩展节点n将其子节点放入open表的首部,并为其配置指向父节点的指针,转2. • 如果问题有解,且其路径长度 dm,则上述搜索过程一定能求得解,若解的路径长度>dm则上述搜索过程就得不到解.即界的选择很重要的.不是越大就越好.
有界深度优先搜索 • 有界深度优先搜索的例子见p269的 • 图6-17.
代价树的宽度优先搜索 • 在上面的搜索中都没有考虑代价的问题,即假设各边上的代价是相同的,如果不是这样,边上是附有不同的数字的即代价(这样的树称为代价树).在代价树中如果用g(x)表示从初始节点S0到节点x的代价,用c(x1,x2)表示从父节点x1到子节点x2的代价,则有: • g(x2)= g(x1)+ c(x1,x2) • 代价宽度优先搜索的基本思想就是每次从open表中选择节点往closed表传送时.总是选择代价最小的节点.也就是说open表中的节点在任一时刻都是按代价从小到大排序的.
代价树的宽度优先搜索 • 其搜索过程如下: • 1、把初始节点放入open表,置S0的代价g(S0)=0 • 2、如果open表为空,则问题无解,退出. • 3、把open表的第一个节点(记为n)取出放入closed表. • 4、考察节点n是否为目标节点,若是则求得了问题的解,退出。 • 5、若节点n不可扩展,转2
代价树的宽度优先搜索 • 6、扩展节点n将其子节点放入open表中,并为其配置指向父节点的指针,计算各子节点的代价,并按代价对open表中的全部节点按从小到大的顺序排序,转2. • 搜索过程见p270页的图6-19 • 书上例6.7给出了求5城市间交通图,现要求从城市A到城市E的最小费用交通路线.求解该问题时首先要把图转换成代价树.
代价树的宽度优先搜索 • A 4 B • 4 4 • C 2 D 5 • 3 E • 交通图
代价树的宽度优先搜索 • 转化成代价树 • A • 3 4 • C1 B1 • 2 4 5 • D1 D2 E1 • 3 4 2 3 • E2 B2 C2 E3 • 5 • E4 • 交通图的代价树
代价树的宽度优先搜索 • 从起始节点A开始,把与它直接相邻的节点作为它的子节点,若一个节点已经作为某个节点的直系先辈,则不能再作为该节点的子节点.为了区别一个节点可能在代价树中的多次出现,用下标1,2,标出.例如,E1,E2等都是图中的节点E.广度优先搜索的结果是:AC D E • 代价树的深度优先搜索类似宽度优先搜索,只是把代价当作深度限制搜索的过程.
对与/或图的搜索 • 对与/或图的搜索与一般图的回溯相比,要求保留更多的记录。对属于或结点的后裔结点的检查与回溯算法中一样;一旦找到一条从初始状态沿或结点通向目标的路径,问题就解决了,除非这条路径被证明是失败的,算法就要回溯,探索另一分支。但检查与结点时,要证明父结点为真,必须证明它所有的子结点为真。 • 如果在代价树中计算与结点的代价时,有两种计算方法:和代价法,最大代价法。具体使用见下图例。
对与/或图的搜索(续) • 和代价法:取与结点逐子结点的代价之和作为该与结点的代价。 • 最大代价法:取逐子结点中代价最大的作为该与结点的代价。 • S 解树B 解树A 4 4 a1 b1 5 4 6 2 a2 a3 b2 2 7 4 a4 5 3 4 a5 b3 t b4 a6 3 t t b5 t
与/或树的搜索(续) • 上图中原始问题S可以分解成解树A或解树B,即只要解决其中一个原始问题S即可解。哪一个花费的代价更少,当然就是我们希望的那个分支。 • 1、按和代价计算的结果:A树为25;B树为23 • 2、按最大代价法计算结果:A树为:14;B树为18 • 所以规定好计算方法取代价花费小的即可。
启发式优先搜索 • 前面我们介绍的搜索均是盲目搜索的情形,即在寻求下一步应扩展结点时,对解的先验信息一点都不知道。 • 启发(heuristic)式优先搜索就是从状态空间中选择最有希望到达问题解的路径。它在选择待扩展结点时利用启发式函数f(x)对OPEN表中的结点进行计算并排序,然后再进行扩展的原则。而不同问题的启发式函数也不同,启发式函数是影响搜索效率的一个关键。 • 启发式函数:f(x)=g(x)+ h(x) • 其中g(x)是从初始结点到结点x已经付出的代价,h(x) • 是从结点x到目标结点将要付出代价的估计值。一般影响f(x)的主要因素是h(x)。
启发式优先搜索算法 • 速度比较快的一种搜索是局部择优(也称瞎子爬山 • (hill climbing)法)搜索. • 它的特点也是其缺点,是省略了一个OPEN表,速度提高了,但由于它没有保留所走过的信息,所以它不能修正错误的路径,可能导致它陷入无穷尽地搜索中。 • 瞎子爬山法在单峰单值的情况,搜索速度较快,可能找到一个最佳解;但在多峰多值的情况下只能找到较好解但不是最好解。
人工智能中Samuel的跳棋程序最早应用的就是该方法。人工智能中Samuel的跳棋程序最早应用的就是该方法。 • 跳棋程序中根据几个不同启发值的总合来估算棋局的状态。
启发式优先搜索算法 • 最好优先搜索法(有序搜索法) • 在最好优先搜索法中也利用两张表OPEN表和CLOSED表来记录已生成而未扩展的结点和已扩展的结点。算法中有一步是根据启发函数,按结点距离目标结点的长度大小重排OPEN表中结点的顺序。扩展时(或循环时)只考虑OPEN表中状态最好的结点,这就是最好优先搜索法。它既不是广度优先中的先进先出,也不是深度中的后进先出而是一个按启发函数计算的大小为序的一个表,有时称为“优先队”。 • 最好优先搜索的算法描述如下:
最好优先搜索法(续) 启动 扩展N并用f(x)估计每个子结点Ni 及配上指向N的返回指针,将{Ni} 并入OPEN表,利用f(x)对OPEN表 重新排序(小的在前) 把S0放入OPEN表 计算f(x) OPEN=NIL 失败 是 否 取OPEN表最前面的结点N放入CLOSED表 并冠以顺序编号n N=Sg? 成功 是 否 否 N可扩展? 是
启发式函数的实现 • 前面我们介绍过启发式优先搜索的关键是启发式函数的制定上,不同的问题有不同的启发式函数。下面介绍的是处理重排九宫问题时制定启发式函数的原则。 • 2 8 3 • 1 6 4 5 6 0 • 7 5 • 2 8 3 1 2 3 • 1 4 3 4 0 8 4 • 7 6 5 7 6 5 • 2 8 3 • 1 6 4 5 6 0 • 7 5 目标 位置不符将牌 二倍将牌逆转数 距离总和
启发式函数的实现 • 2 1 3 1 2 3 • 8 4 8 4 • 7 5 6 7 6 5 目标 九宫问题的目标状态及有两个逆转位置的状态1和2,5和6 下面给出重排九宫问题的两个启发式函数: f1(x)= p(x)+w(x) 其中p(x)是x结点和目标结点相比将牌不相符的数目, w(x)是结点x和目标结点相比每个将牌的距离之和。