zoukankan      html  css  js  c++  java
  • 搜索算法总结

    一、最基本的搜索算法:回溯算法
    回溯算法是所有搜索算法中最为基本的一种算法,其采用了一种“走不通就掉头”思想作为其控制结构。

    二、搜索算法分类:bfs与dfs
    dfs:栈的思想(先进后出)优先兄弟节点。容易超时,多用于求可行解。
    bfs:队列的思想(先进先出)优先儿子节点。容易消耗大量内存,多用于求最优解。

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

    第二部分 搜索算法的优化
    一、双向广度搜索
    广度搜索虽然可以得到最优解,但是其空间消耗增长太快。但如果从正反两个方向进行广度搜索,理想情况下可以减少二分之一的搜索量,从而提高搜索速度。

    二、分支定界(俗称剪枝)
    分支定界实际上是A*算法的一种雏形,为了有效地选择下一扩展结点,以加速搜索的进程,在每一活结点处,计算一个函数值(限界),
    并根据这些已计算出的函数值,从当前活结点表中选择一个最有利的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解。

    三、A*算法
    A*算法中更一般的引入了一个估价函数f,其定义为f=g+h (f必须单调递增,切越小越好)。其中g为到达当前节点的成本,而h表示对从当前节点到达目标节点的耗费的估计。

    A*算法的控制结构与广度搜索的十分类似,只是每次扩展的都是当前待扩展节点中f值最小的一个,如果扩展出来的节点与已扩展的节点重复,则删去这个节点。
    如果与待扩展节点重复,如果这个节点的估价函数值较小,则用其代替原待扩展节点。

    四、A*+小顶堆
    如果每次排序找扩展节点中f最小的元素,那么排序的工作量可以说是很大的,即使是快排,程序也不够快!
    这里,可以想到,由于需要动态的添加元素,动态的得到程序的最小值,我们可以维护一个小顶堆,这样的效果就是。
    每次取最小元素的时候,不是用一个n*Log(n)的排序,而是用log(n)的查找和调整堆。

    五、IDA*
    IDA*算法就是基于迭代加深的A*算法。迭代加深分两步走:
    1、枚举深度(H值逐渐递增枚举,有解情况必是最有值)。
    2、根据限定的深度进行DFS,并且利用估价函数进行剪枝。
    由于改成了深度优先的方式,与A*比起来,IDA*更实用:1.不需要判重,2.不需要排序,3.空间需求减少。

    六、记忆化搜索(深搜+动态规划)
    搜索到的一些解用动态规划的那种思想和模式作一些保存。
    eg:给定一个8 * 8的国际象棋棋盘。给出棋盘上任意两个位置的坐标,问马最少几步可以从一个位置跳到另外一个位置.
    if dp[x2][y2] > dp[x1][y1] + 1 then dp[x2][y2] = dp[x1][y1] + 1 继续搜下去
    else 没有必要搜下去了 return

    八数码问题的八重境界:
    境界一、 暴力广搜+STL
    境界二、广搜+哈希
    境界三、广搜+哈希+打表
    境界四、双向广搜+哈希
    境界五、A*+哈希+简单估价函数
    境界六、A*+哈希+曼哈顿距离
    境界七、A*+哈希+曼哈顿距离+小顶堆
    境界八、IDA*+曼哈顿距离

  • 相关阅读:
    rsyslog服务日志收集配置
    Python urllib2 发送HTTP Request
    Jenkins版本回滚
    C++算法的40个高频面试问题集锦
    Linux添加自启动daemon service
    python爬虫随机设备信息生成模板
    selenium配置有账号密码验证的代理
    app脱壳后多个dex合并成一个
    webpack优化系列-多进程打包thread-loader
    AtCoder abc158_f
  • 原文地址:https://www.cnblogs.com/kane0526/p/8330852.html
Copyright © 2011-2022 走看看