爆搜是noip中最容易拿分的算法(我认为)。2014年的noip中我就用爆搜拿了360,当然爆搜还是要剪枝的!可惜的是初赛没考好,只能在B组,即使拿B组第一但还是二等奖。
一、搜索剪枝
什么是剪枝:剪枝是技巧,而不是方法,也就是说,可能一点实用的小技巧,让程序可以少判断一点,这就是剪枝,要知道剪枝无处不在。
搜索的进程可以看作是从树根出发,遍历一棵倒置的树—-搜索树的过程。而所谓的剪枝,顾名思义,就是通过某种判断,避免一些不必要的遍历过程,形象的说,就是减去了搜索树中的某些“枝条”,故称剪枝。(杭电课件)
剪枝的必要性:
既然采用了搜索,剪枝就显得十分的必要,即使就简简单单的设一个槛值,或多加一两条判断,就可对搜索的效率产生惊人的影响。
<span style="font-size:18px;">例题1 计算机网络连接要将台计算机连成网络,连接方法:去除首尾两台计算机与一台计算机相连以外,其他计算机只与两台计算机相连。连接的长度则为计算机连接的电缆的长度。求:一种连接方式,使需要电缆的长度最短。分析这个题目用回溯搜索来解决。但是,由于回溯搜索的搜索量比较大,达到了,是不可能搜索完的情况的,所以,我们考虑对它进行优化:假如目前搜索到了一组解,电缆总长度为,那么,如果说以后搜索到的连接方法(不一定是最终连接方法)的连接长度,那么这个方案的总长度一定不小于,那么,就不必要搜索下去了,直接换下一个结点继续搜索。路径与路径这两条路径是一个“正反”的关系,本质上是相同的,于是我们可以规定起点始的下标总是小于终点的下标假如路径的的长度的长度,那么包含路径的路径的长度一定不是最短。有了上述的优化,题目就可以得到很快的解决了。在深度优先搜索的过程当中,往往有很多走不通的“死路”。假如我们把这些“死路”排除在外,不是可以节省很多的时间吗?打一个比方,前面有一个路径,别人已经提示:“这是死路,肯定不通”,而你的程序仍然很“执着”地要继续朝这个方向走,走到头来才发现,别人的提示是正确的。这样,浪费了很多的时间。针对这种情况,我们可以把“死路”给标记一下不走,就可以得到的搜索效率。</span>
<span style="font-size:18px;">例题2 皇后问题分析 取为例采用一般的回溯,就是每一行的每个格子放与不放都搜索一下:然后回溯一次,换下一个点继续搜索。这个算法的效率,是实际上,在放置了这个皇后,再把皇后放置在就是毫无意义的:前面一个皇后一定能攻击到它。为了避免这种情况,我们这样做:走了一个棋子以后,把它的“势力范围”给圈出来,并且告诉以后的皇后:这里不能放置。举简单的例子:放置皇后,由于打“的格子在放了这颗子之后,被标注为了“不能走”,所以这些点我们就不去理会了。这样就节省了很多时间,大大提高了搜索的效率。而对于很多回溯的题目,我们都可以采用分枝定界法,把搜索树中不必要的枝剪去,大大提高了搜索的效率。剪枝的原则:</span>
1.正确性:必须保证不丢失正确的结果。
2.准确性:能够尽可能多的减去不能通向正解的枝条
3.高效性:在很多时候,为了加强优化的效果,我们会增加一些判断,这样对程序效率也带来了副作用,所以要考虑剪枝的高效性,否则得不偿失。