网上找的一些算法搜索lunwen_第1页
网上找的一些算法搜索lunwen_第2页
网上找的一些算法搜索lunwen_第3页
网上找的一些算法搜索lunwen_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、论程序设计中搜索的优化苏展(金陵中学初一 6 班)【关键字】程序设计、搜索、时间与空间【摘要】本文作者利用搜索的一般知识结合自身经验,介绍了程序设计中搜索及其优化的一般方法。开始介绍 搜索的方法及其存在的问题,然后重点介绍了作者归纳的一些解决方法,通过时间和空间两部分加以分类。同时,在附录里介绍了 PASCAL 对内存空间的分配。一、 引言在一时找不出解决问题的更好途径(指从数学上找到求解公式或规则)时,可以对问题的状态进行逐一的查找,直到找到目标状态或到达目标状态的过程。这种方法叫做“搜索”或“穷举”。一般情况下,“搜索”是对于问题的状态进行基于队列的广度优先的搜寻。由于它是对问题的所有状态

2、进行搜寻,所以它不易做错,但这也带来了一个问题:对运算的空间与时间带来了很大的压力。由于搜索要对问题的大部分甚至所有状态进行搜寻,要它们,必然需要极多的内存空间。就拿“魔板问题”来说吧,它一共有 40320 种状态,下,要全部搜索完,恐怕小小的 64K 数据段空间是远远不够的。情况再则,搜索每一种状态都需要时间,还说“魔板问题”,在情况下,即便一毫秒搜索两种状态,也要三分钟多。这种等待往往让人难以忍受,在大部分竞赛中,这是拿不到分的。由于上述考虑,的问题。在程序中需要对搜索进行优化,以解决时间与空间不足二、 利用队列进行搜索的一般方法利用队列进行搜索一般是解决求一种状态通过几种规定的操作以最少

3、次数变换到另一种状态的方法,本文也是以索用队列的数据结构如下:利用队列进行的搜索的优化为主。搜队列头指针队列尾指针由于找到目标值后,还需根据 PRE 值回溯得到由初始状态到达目标值的最短序列,所以还要准备一个辅助栈,其元素类型与 DATA 或 OP 一样。下面是利用队列搜索的一般步骤(设共有 N 种变换操作):DATA(状态)初始状态初始状态经 A操作的结果初始状态经 B操作的结果初始状态经两次A 操作的结果OP(由何种操作变换而来)-ABAPRE(由何种状态变换而来)0112初始状态入队。I:=1。对队列首部的状态进行第 I 种操作,结果。检查结果是否出现过,若未出现过,则此结果进队,DAT

4、A 记下此结果,OP 记下 I 的值,PRE 记下变换至此结果的元素(即当前队列首部元素)的位置(下标)。若结果即为所求,至步骤若 I=N,队列第一个元素出队,至步骤;否则,I:=I+1,至步骤。 J:=当前元素下标队列中第 J 个元素的 OP 或 DATA 进辅助栈若 J1,J:=队列中第 J 个元素的 PRE,至步骤。全部弹栈,按出栈顺序输出。不过,在搜索过程中,“出队”的元素必须一直保留,不能删除(最后回溯时要用到)。三、 空间的解决方案判重“判重”即指判断一个新搜索到的状态以前是否出现过,如出现过就去掉它。判重一般用于用队列进行搜索,而且用队列进行搜索的程序几乎全都用到这种方法。虽然判

5、重需要增加时间,而且一次最多只能去掉一种状态,但这种状态所产生的众多无用状态所浪费的时间与空间将远远大于判重本身所需要的时间。利用“免费”资源这里的“免费”资源指的是那些不占用空间却可以表示信息的。数组下标就是一种完全不占空间的。往往可以用数组下标来表示所有的状态,这一状态的信息就直接在下标所对应的数组元素里,方可空间。另外,内存地址也是一种免费资源。不过,使用时须可能会产生意想不到的严重情况。重复利用,万一动了系统的内存,举一个不恰当的例子:在没有通自来水的时候,大家用水桶从井里打水;通上了自来水,水桶不要了,可改成桶(尽管不太合适)。同理,有时候,变量重复利用,可节省不少空间。比如利用队列

6、搜索,辅助栈会占去不少空间。如果不用辅助栈,将 PRE 再次利用,使它变化方向,反过来指向所变换成的元素,就等于进行了回溯,也就不需辅助栈,节省了空间。但重复利用变量,往往会降低程序的可读性。使用动态数据类型动态数据类型,其实就是指针类型。因为指针类型占用的是堆空间(有关PASCAL 的内存管理请见附录 PASCAL 的内存分配),堆空间理论上0K之多(一般能用到 289K 左右),是栈或数据段空间的十倍,所以使用指针类型可大大缓解空间紧张问题。另外,指针类型可以根据实际需要分配内存空间,比数组更灵活。但是,使用指针类型需要注意几点:指针本身也占空间 不仅指针所指向的资料占空间,指针本身也是占

7、空间的。一个指针将占去堆空间是以八个字节为一个节的内存空间。与硬盘用簇来作为文件的最小单位类似,Pascal 也将为每一个指针类型在堆中分配八的整倍数字节(例如 15 个字节的数据类型将占用 16 个字节的堆空间),无论指针指向的是字节类型还是数组类型。 利用文件如果其它方法都使用了,空间仍然不够。那么就要考虑使用文件了。硬盘上几十兆的空间任你用,空间问题自然是迎刃而解。但硬盘的速度要比内存慢的多,这又容易造成时间不够,所以不到必要时候,不要使用文件。程序中一般是使用类型文件,这是因为类型文件具有较好的灵活性,可以象数组一样快速定位文件内容,可以任何除文件类型或包含文件类型的构造类型外的任何一

8、种类型。当然,也可使用无类型文件。它的特点是可以从中一次一批资料至所需的任何数据类型,适用于高速输入输出及在文件中多种数据类型的场合。四、 时间的解决方案判重就是前面的那个判重。它减少了所需的状态,自然减少了搜索的时间。判重是一种既节省空间,又节省时间的算法,应此成为了每个搜索程序中都用到的算法。分枝定界在搜索中用一些约束条件将一些不必要的状态去掉,以去掉这个状态可能涎生的许许多多种分枝状态,就象砍树一样,故名“分枝定界”。它在深度优先搜索中效果明显。前面提到的判重实际也是分枝定界。分枝定界也是搜索程序中常用的算法之一。在使用分枝定界的时候, 有时候不但使用题目给出的约束条件,还要从问题中找出

9、隐含的约束条件。例如跳马问题,表面上并未给出任何约束条件,实际上也有不少约束条件,比如棋盘上不能有一个完全封闭(跳不进去)的点、不能同时出现两个只有一个点可跳入的点等等。当然,剪枝的过程也会增加一定时间,所以一个好的约束条件可以火上浇油。设计估价函数空间与时间,不好的也可能使空间紧张问题在搜索中,每一步都有很多状态需要搜索,往往状态选得好,就能减少搜索次数,也就减少搜索时间,这一点在深度优先搜索中体现较明显。究竟怎样才能使程序自动选择状态呢?需要设计一个估价函数,用它来对每一步搜索作评价,选出应先搜索哪些状态,后搜索哪些状态。怎样设计估价函数是一个很值得探讨的问题,它将广泛涉及相关学科的知识,

10、特别是数学的基础知识。深度优先搜索中最常用的估价方法就是检查分支数量,分支较少的就较优。这是因为分支少,一般来说搜索的时间就较少。如果搜索不到,浪费的时间也比较少。它也适用于广度优先搜索,但效果不明显。牺牲空间,换取时间这个方法一看就明白,不需多讲。它一般通过牺牲空间减少计算量来取得时间。不过,使用这个方法有个小窍门,就是前面曾提到过,指针类型一占就是八个字节,不妨将变量定义成八(或八的倍数)个字节的指针类型,这样既不浪费空间,又减少了时间。 其它的小方面 用递归代替多重循环虽然会增加程序可读性,但会减慢程序运行速度。 如果多重循环用单层循环代替(不增加循环次数),可以提高程序速度。五、 结语

11、优化搜索主要是求得减少时间和空间消耗的方案,本文就列举出了几种方案,它们可以帮助大家在搜索省不少时间和空间。当然,还有许多种本文所没有举出的方案,它们需要读者自己来发掘。我只希望这几个方案能使大家的搜索程序更快一些、更好一些。当然,要想彻底解决搜索所存在的种种问题,就要利用别的、更好的方法(例如动态规划)替代搜索。这需要大家利用自己的知识与经验来寻求。六、 附录 PASCAL 的内存分配PASCAL 采用堆栈结构管理内存。其内存分配映像略图如下:最大 640K堆最大约 64K栈最大约 64K最大约 64K数据段代码段PASCAL 内存分配映像略图如图,PASCAL 将指针变量安排在堆中,箭头表示堆向

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论