搜索及应用

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

搜索及应用

【学习与辅导方式】

自学为主,所有提到的例题和算法都要编写完整的程序,有疑问的地方可以在QQ群中提问。

内部资料,请勿外传。

【学习要点】

(1)掌握搜索算法的基本概念和求解过程

(2)掌握搜索算法的几种常用策略

(3)能够应用搜索算法解决问题,并分析各种搜索策略的空间、时间复杂性

(4)探索搜索算法的优化思路以降低该算法的时间、空间复杂度

搜索算法是利用计算机的高性能来有目的的穷举一个问题解空间的部分或所有的可能情况,从而求出问题的解的一种方法。

一、搜索过程

搜索算法实际上是

根据初始条件和扩展规

则构造一颗“解答树”

并寻找符合目标状态的

节点的过程。所有的搜

索算法从最终的算法实现上来看,都可以划分成两个部分——控制结构(扩展节点的方式)和产生系统(扩展节点),而所有的算法优化和改进主要都是通过修改其控制结构来完成的。其实,在这样的思考过程中,我们已经不知不觉地将一个具体的问题抽象成了一个图论的模型——树,即搜索算法的使用第一步在于搜索树的建立。

由图一可以知道,这样形成的一棵树叫搜索树。初始状态对应着根结点,目标状态对应着目标结点。排在前的结点叫父结点,其后的结点叫子结点,同一层中的结点是兄弟结点,由父结点产生子结点叫扩展。完成搜

索的过程就是找到一条从根结点到目标结点的路径,找出符合条件的解。

二、搜索策略

1、枚举法

枚举法的基本思想:根据实际问题设计多重循环,一一枚举所有可能的状态,并用问题给定的约束条件检验哪些状态是需要的,哪些状态是不需要的。能使命题成立的状态,即为其解。虽然枚举法本质上属于搜索策略,但是适用枚举法求解的问题必须满足两个条件:

(1)可预先确定每个状态的元素个数n;

(2)可预先确定每个状态元素a1,a2,...,an的值域。

设ai1为状态元素ai的最小值;aik为状态元素ai的最大值(1≤i≤n),即状态元素a1,a2,...,an的值域分别为a11≤a1≤a1k, a21≤a2≤a2k, ai1≤ai≤aik,..., an1≤an≤ank。

for a1:=a11 to a1k do

for a2:=a21 to a2k do

......

for ai:=ai1 to aik do

......

for an:=an1 to ank do

if 状态(a1,a2,...,ai,...,an) 满足检验条件 then 输出问题的解;

枚举法的优点:由于枚举算法一般是现实问题的“直译”,且是建立在考察大量状态、甚至是穷举所有状态的基础之上的,因此比较直观,易于理解,其算法的正确性也比较容易证明。

枚举法的缺点:枚举算法的效率取决于枚举状态的数量以及单个状态枚举

的代价,因此效率比较低。

由于枚举法属于一种“直译”的解题方法,因此需要编程者注意认真审题,不要疏漏任何信息,根据题意以及蕴涵的规律准确地设定枚举对象、范围和约束条件。

【例2-1】猫老大数(TOJ1081,猫老大与彩虹的竞赛)

猫老大很喜欢研究数字,特别是喜欢质数。一天,猫老大发现有一些数字可以表示成两个质数相乘的形式。比如,10=2×5. 2,5都是质数,所以 10 是一个“猫老大数”。所以猫老大决定考考彩虹,他告诉彩虹一个数 n ,判断 n 是不是“猫老大数”?(1<=n<=231-1)

由于题目中含有条件1<=n<=231-1= maxlongint(LONG_MAX),所以我们可以先计算出1到的所有质数,共有4792个。我们把这些质数存在数组中,完成了第一步的预处理工作。

有这样一个定理:如果一个数是合数,那么它一定会有一个小于等于这个数的开方的不是1的因数。根据这个理和题意,则如果这个数是合数,我们只须要枚举2到就可以找到一个质数。

然后根据唯一分解定理,我们可以得出猫老大数必定只能质数分拆为两个质数。所以我们只须判断被一个质数除下后是不是质数即可。由于两个质数是成反比例的(n一定),根据函数曲线,得出一种好的方法——先从小到大找到一个较小的,然后继续判断,直到找到第二个,判断剩下的是不是1。

【例2-2】仓库扩张(USACO Contest DEC05)

在FJ的农场里有N(1<=N<=25000)个长方形仓库,这些仓库的四条边都分别与x轴、y轴平行,且四角坐标均为正数,范围为0..1000000。这些仓库都不互相重叠,但是可能有一些点或者一段边是它们共有的。

一次,FJ得到了更多的奶牛去挤奶,因此他想扩张自己的仓库。一个仓库有能够扩张的条件是它不与别的仓库存在任何一个公共角或者任意一段公共边。请你计算有多少个仓库可以扩张。

这道题目枚举的方法有些特殊,需要一些枚举技巧。

首先在读入时,我们的处理方法是“拆边”,按横、纵两种拆。拆开以后,我们应该把所有的横边排序,所有的纵边也排序。

横边排序规则:1.按行排序。2.行相等时按这一行的头坐标(线段左边端点纵坐标)排序。3.如果再相等就按线段右边端点纵坐标排序。这样就能够保证边的有序性,为下面做好铺垫。竖边类同。

然后就是把所有的横边、纵边进行重叠处理。我们可以把它们分开处理。如果重叠(或临接),则两个仓库都不能扩张。经过上述处理,我们可以发现我们需要比较的边数已经大大减少。因此我们可以加上一些细节处理来加快速度。

2、深度优先搜索与回溯法

深度优先搜索所遵循的搜索策略是尽可能“深”地搜索树。它的基本思想是:为了求得问题的解,先选择某一种可能情况向前(子结点)探索,在探索过程中,一旦发现原来的选择不符合要求,就回溯至父亲结点重新选择另一结点,继续向前探索,如此反复进行,直至求得最优解。一般地,从纵深搜索的策略讲,深度优先搜索与回溯法的本质是一致的,只不过是深度优先搜索一般用于现成的显式图,而回溯法一般用于隐式图的拓展、转化与搜索。

深度优先搜索的实现方式可以采用递归或者栈来实现。

Program 递归深度优先搜索程序;

Const …;

相关文档
最新文档