状态空间表示法用状态变量和操作符号来表示系统或问题的符号体系。状态空间可以用一个四元组表示:
( S , O , S 0 , G ) (S,\ O,\ S_0\ ,G) (S, O, S0 ,G)
其中 S S S 是状态集合。 O O O 是操作算子的集合。 S 0 S_0 S0 是包含问题的初始状态,是 S S S 的非空子集。 G G G 是包含问题的目的状态若干具体状态或满足某些性质的路径信息描述。
状态
:表示系统状态、事实等叙述型知识的一组变量或数组。
Q = [ q 1 , q 2 , ⋯ , q n ] T Q=[q_1,q_2,\cdots,q_n]^T Q=[q1,q2,⋯,qn]T
操作
:表示引起状态变化的过程型知识的一组关系或函数。
F = { f 1 , f 2 , ⋯ , f n } F=\{f_1,f_2,\cdots,f_n\} F={f1,f2,⋯,fn}
求解路径:从 S 0 S_0 S0节点到 G G G节点的路径。
状态空间的一个解:一个有限的操作算子序列。
S 0 ⟶ O 1 S 1 ⟶ O 2 S 2 ⟶ O 3 ⋯ ⟶ O k G S_0\stackrel{O_1}{\longrightarrow}S_1\stackrel{O_2}{\longrightarrow}S_2\stackrel{O_3}{\longrightarrow}\cdots\stackrel{O_k}{\longrightarrow}G S0⟶O1S1⟶O2S2⟶O3⋯⟶OkG
其中 O 1 ⋅ ⋅ ⋅ O K O_1···O_K O1⋅⋅⋅OK 是状态空间的一个解。
状态空间可用有向图来描述,图的结点表示问题的状态,图的弧表示状态之间的关系,就是求解问题的步骤。初始状态对应于实际问题的已知信息,是图中的根结点。问题的状态空间描述中,寻找从一种状态转换为另一种状态的某个操作算子序列就等价于在一个图中寻找某一路径。
从初始状态出发,不停地、试探性地寻找路径, 直到它到达目的或“不可解结点” ,即“死胡同” 为止。回溯策略
是遇到不可解结点就回溯到路径中最近的 父结点上,查看该结点是否还有其他的子结点未被 扩展。若有,则沿这些子结点继续搜索;如果找到 目标,就成功退出搜索,返回解题路径。
回溯搜索的算法用三张表来保存状态空间中的不同性质节点:
路径状态表/PS表(path states)
:保存当前搜索路径上的状态。如果找到了目的,PS就是解路径上的状态有序集。新的路径状态表/NPS表(new path states)
:新的路径状态表。它包含了等待搜索的状态,其后裔状态还未被搜索到,即未被生成扩展 。不可解状态表/NSS表(no solvable states)
:不可解状态集,列出了找不到解题路径的状态。如果在搜索中扩展出的状态是它的元素,则可立即将之排除,不必沿该状态继续搜索。搜索算法的回溯思想:
在实际宽度优先搜索时,为了保存状态空间搜索的轨迹,用到了两个表:
队列
结构,其中状态的排列次序就是搜索的次序。宽度优先搜索过程:
宽度优先算法的改进:
由原来从OPEN表取出后放入CLOSE表前访问改为扩展其子节点时直接访问其子节点,可以避免访问目标节点的左侧同级节点。
在实际深度优先搜索时,也用到了OPEN表和CLOSED表,不同的是,深度优先搜索算法中OPEN表是堆栈
结构。且一般会对深度优先搜索进行深度上的限制,以免深度过深。
有界深度优先搜索算法过程:
有界深度优先搜索算法的改进:
dm的值很难给出,不能保证找到最优解。可以使用可变的dm
。当达了指定的dm仍未发现目标节点,且CLOSED表中仍有待扩展节点时,就将这些节点送回OPEN表,同时增大深度界限dm继续向下搜索。如此不断地增大dm,只要问题有解,就一定可以找到它。
启发式策略就是利用与问题有关的启发信息进行搜索。在状态空间搜索中,启发式被定义成一系列操作算子,并能从状态空间中选择最有希望到达问题解的 路径。
运用启发式策略的两种基本情况:
在具体求解中,启发式搜索能够利用与该问题有关的信息来简化搜索过程,称此类信息为启发信息
。启发信息按运用的方法不同可分为三种:
为提高搜索效率就需要利用上述三种启发信息作为搜索的辅助性策略。这里主要介绍控制性的启发信息。利用控制性的启发信息有两种极端的情况:
一般情况介于二者之间。在搜索过程中需要根据这些启发信息估计各个结点的重要性。
用估价函数
(Evaluation Function)估计待搜索结点的“有希望”程度,并依次给它们排定次序。一般来说,估计一个结点价值,必须综合考虑已经付出的代价和将要付出的代价两方面的因素,因此,估价函数 f ( n ) f(n) f(n) 定义为从初始结点经过 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 ) h(n) h(n) 是从n结点到目的结点的最佳路径的估计代价、因为实际代价 g ( n ) g(n) g(n) 可以根据已生成的搜索树实际计算出来,而估计代价 h ( n ) h(n) h(n) 是对未生成的搜索路径的作某种经验性的估计。这种估计来源于对问题解的某些特性的认识,希望依靠这些特性来快速找到问题的解,因此主要是 h ( n ) h(n) h(n) 体现了搜索的启发性。
与宽度优先和深度优先搜索算法一样,启发式图搜索法
算法也使用OPEN表和CLOSED表记录状态信息,不同的是,它既不同于宽度优先所使用的队列(先进先出),也不同于深度优先所使用的堆栈(先进后出),而是一个按状态的启发估价函数值的大小排列
的一个表。进入open表的状态不是简单地排在队尾(或队首),而是根据其估值的大小插入
到表中合适的位置,每次从表中优先取出启发估价函数值最小的状态
加以扩展。
A算法是基于估价函数的一种加权启发式图搜索算法,具体步骤如下:
A* 搜索算法又称为最佳图搜索算法,定义 h ∗ ( n ) h^*(n) h∗(n)为状态 n 到目的状态的最优路径的代价,则当A搜索算法的启发函数小于等于 h ∗ ( n ) h^*(n) h∗(n)时被称为 A* 算法。
如果某一问题有解,那么利用 A* 搜索算法对该问题进行搜索则一定能搜索到解,并且一定能搜索到最优的解而结束。 A* 搜索算法有以下几个特征:
可采纳性
:对于可解状态空间图,如果一个搜索算法在优先步内终止,并能得到最优解,就称该搜索算法是可采纳的。可证明所有 A* 搜索算法都是可采纳的,宽度优先搜索是 A* 搜索算法的一个特例,相当于 A* 搜索算法中 h ( n ) = 0 h(n)=0 h(n)=0和 f ( n ) = g ( n ) + 0 f(n)=g(n)+0 f(n)=g(n)+0,它也是可接纳的,只是效率太低。单调性
:对所有状态 n i n_i ni和 n j n_j nj,其中 n j n_j nj是 n i n_i ni的后裔,满足 h ( n i ) − h ( n j ) ≤ c o s t ( n i , n j ) h(n_i)-h(n_j)\le cost(n_i,n_j) h(ni)−h(nj)≤cost(ni,nj),其中 c o s t ( n i , n j ) cost(n_i,n_j) cost(ni,nj)是二者之间的实际代价,且目的状态的启发函数值为0或 h ( G o a l ) = 0 h(Goal)=0 h(Goal)=0,则称该启发函数是单调的。通俗的说就是在整个搜索空间都是局部可采纳的。 一个状态和任一个子状态之间的差由该状态与其子状态之间的实际代价所限定。信息性
:在两个 A* 启发策略的 h 1 h_1 h1和 h 2 h_2 h2中,如果对搜索空间中的任一状态 n 都有 h 1 ( n ) ≤ h 2 ( n ) h_1(n)\le h_2(n) h1(n)≤h2(n),就称策略 h 2 h_2 h2 比 h 1 h_1 h1 具有更多的信息性。