zoukankan      html  css  js  c++  java
  • 暴搜的美学

    暴搜的美学

      引言:在noip,csp的比赛中一般情况下都会有大量的部分分可拿,某些题可以通过暴搜AC,甚至于还可以吊打标称。。。在某些弱省,拿满暴力分就有省一的说。。。。

       然而,不管怎样,本文所述的就好比教你如何让你的弓箭射得更准,长矛投得更远,即使你掌握的再好,也比不过好比电磁炮,激光枪的其他优秀算法。 本文的意图就在于分享一些比较使用的搜索小技巧,展示搜索的精妙之处,在考场上遇到不会的题时可以写写暴力骗骗分。电磁炮,激光枪偶尔也会有出故障的时候。

      真正的oier的思维是不会局限于暴搜的,所以当你因为用了一些本文中所提到的搜索技巧而AC了某些题目时,请放下你的暴搜,去领悟题目的美。学习暴搜,运用暴搜,并且脱离暴搜。


    Part.1 暴搜的定义

      本文所讲的暴搜是指在可承受的数据规模内,利用计算机的高速运算能力,对题目所求的答案进行寻找。一般来说,有两种风格不同的搜索。DFS和BFS。DFS即为深度优先搜索,一般是递归调用自己,利用函数的参数进行状态转移。BFS主要是横向地讨论每一个可能的状态,一般利用队列维护其状态。

    DFS 和 BFS 该如何决策呢?

    总的来说 DFS 的上镜率远高于BFS,所以一般首选DFS

    一般情况下,求最优解的情况可以考虑BFS,因为BFS的搜素顺序是横向发展的,所以第一个搜到的值一定是最优值,但BFS正因为是横向搜索所以不方便进行剪枝的优化

    同时,DFS也可以通过像迭代加深等操作来模拟横向搜索,所以,推荐尽量使用DFS;本文也同样会花大篇幅讲DFS的各类优化。


     Part.2 DFS的剪枝优化

    在DFS的搜索树上存在着许多无用的子树,这些子树要么不是最优解,要么甚至不合法,为了缩小搜索的范围,达到骗分的目的,在这里给出几种常用的剪枝优化

    一,记忆化剪枝

      顾名思义,记忆化剪枝就是将已经搜索计算过的状态先存下来,如过需要再次使用的时候就可以拿出来用了,这样做会大大地提高搜索的效率,可以感性理解为搜索一次后就可以一劳永逸,当下一次搜索到该状态时直接拿出来用就行了。该剪枝是所有剪枝中优化最明显的,当然记忆化剪枝其实和DP之间有着密切的联系,这会等到后文在详细的讲述。

    二,可行性剪枝

      如果搜索到目前状态发现该状态已经不合法了,就完全不用继续花时间搜索下去了,直接就可以return掉搜索其余的状态,比如说你妈要求你每天最多玩1min的电脑,然后你发现开机都用了一分钟,你就可也return掉滚回去学习了。。

    三,最优化剪枝

    这个可以利用放缩法,如果假设当前的搜索状态继续下去,且每次都按照一个最优值都不能达到目的的话,也可以return掉,举个例子,假设你估计了下剩下的作业和天数,发现你每天就算做24h也无法完成剩下的作业,你就可以大胆return掉了(这不是你不写作业的理由)

    四,拉斯维加斯剪枝

    众所周知,拉斯维加斯是一个赌城。。该剪枝的意义就是当你发现程序要超时了,就把当前搜索到的最优值当做全局最优值输出。。。这是迫不得已的赌徒行为。

    但能不能骗分其实真的不好说。。。。 看情况使用即可。代码实现很简单,记录一个Cnt,每递归一次就Cnt++;Cnt大于某个值时就return

    五,概率剪枝

      这是一种玄学算法,能否AC取决于你的脸。。。。 模拟退火算法就是一种概率剪枝,大概的意思是说每次搜索都有一定的概率继续往下搜索,随着搜索的深入,往下搜索的概率就会变小,类似于物理上的退火过程,当然继续搜索的概率是由自己来设定,也可以搞一个什么估价函数来计算当前继续搜索下去的概率。。。。。都是玄学,有机会以后再细谈。

    其他还有一些剪枝的技巧,如启发式搜索啦之类的,将在分类讲主流优化搜索时详细讲述。


     Part 3.一些优秀的搜索技巧

    一,Meet in the middle 折半搜索/双向DFS

     1.为什么要进行折半搜索?

    一般情况,在搜索树上,搜索的规模是随着数据规模呈指数型增长的,所以如果能将数据规模减半,那搜索的规模将大幅度减小 。

    <----普通搜索的搜索树规模

    <----折半搜索的搜索树规模

    2.什么题可以用折半搜索

      折半搜索适用于数据较小的题(要保证折半后的数据规模仍可以接受),同时搜索的答案可以被由被分开搜索的两部分合并求解。

    3.折半搜索 Vs 分段状压

      一般题目的n值在40以内,就有两种可选择的解法,分段状压和折半搜索。 时间复杂度上一般是折半搜索更胜一筹,如果再加上一些其它的剪枝就能跑得更快。

  • 相关阅读:
    Linux系统信息查看
    批处理Dos命令
    python语法31[函数]
    python基础31[数据结构list+tuple+set+dictionary]
    nmake使用
    linux间文件拷贝
    linux文件同步工具Unison的使用
    python语法31[基本数据类型和流程控制]
    远程桌面管理工具比较
    WindowsBatch与LinuxShell比较[batchfile之for命令详解]
  • 原文地址:https://www.cnblogs.com/pveds/p/11802257.html
Copyright © 2011-2022 走看看