zoukankan      html  css  js  c++  java
  • 算法笔记——搜索初步

            把这几天学的搜索做一个初步总结。
           一、 深度优先搜索(DFS):从起点出发,走过的点要做标记,发现有没走过的点,就随意挑一个往前走,走不动了就回退。不能走已经走过的点(需要判重)。
           举几个栗子:
           1.判断从V出发是否能走到终点:

    bool Dfs(V) {
    if( V 为终点)
    return true;
    if( V 为旧点)
    return false;
    将V标记为旧点;
    对和V相邻的每个节点U {
    if( Dfs(U) == true)
    return true;
    }
    return false;
    }

    判断从v出发是否能走到终点时,返回值有意义。

    因为有回溯的过程,所以会把k出发能走到的点都走一遍。

    2.判断从v出发是否能走到终点,如果能,要记录路径。

    bool Dfs(V) {
    if( V为终点) {
    path[depth] = V;
    return true;
    }
    if( V 为旧点)
    return false;
    将V标记为旧点;
    path[depth]=V;
    ++depth;
    对和V相邻的每个节点U {
    if( Dfs(U) == true)
    return true;
    }
    --depth;
    return false;
    }

    --depth的过程就是回溯的过程。

    3.在图中寻找最优(步数最少路径)

    void Dfs(V) {
    if( V为终点) {
    path[depth] = V;
    if( depth < minSteps ) {
    minSteps = depth;
    拷贝path到bestPath;
    }
    return;
    }
    if( V 为旧点) return;
    if( depth >= minSteps ) return ; //最优性剪枝
    将V标记为旧点;
    path[depth]=V;
    ++depth;
    对和V相邻的每个节点U {
    Dfs(U);
    }
    --depth;
    将V恢复为新点
    }

    求最优路时,要把走过的不同的路保留下来。

    为什么将v恢复为新点:为了之后的兄弟可能会绕回v。

    找最优路时返回值无意义。

    图的存储方式对遍历v的相邻节点u过程的影响:

    邻接矩阵遍历:O(n²)

    邻接表遍历:O(n+e)

    稀疏图用邻接表存储效率更高。

    剪枝:最优性剪枝,可行性剪枝。(待更新)

     二、 广度优先搜索(BFS):依层次顺序,从小到大扩展节点。把层次低的点全部扩展出来后,才会扩展层次高的点。扩展时,不能扩展已经走过的节点(要判重)。

    广搜最优解一般是求操作步骤最少,注意判重(可以用set来判重)。

    三、双向广搜(DBFS):待更新。

    四、A*算法在BFS算法中,若对每个状态n都设定估价函数f(n)=g(n)+h(n),并且每次从Open表中选节点进行扩展时,都选取f值最小的节点,则该搜索算法为启发式搜索算法,又称A算法。

    g(n) : 从起始状态到当前状态n的代价
    h(n) : 从当前状态n到目标状态的估计代价
    广搜可以看作:f(n)=g(n)(无h(n)这项),A*的关键是如何设计估计函数h(n),如何对估计函数做限制,确保能找到最优解。

    由于是有根据地去估计,因此不可能估计出比真实值还小的数,即真实代价≥估计代价。

    估计函数实际上是一种乐观的估计,在这种乐观估计的前提下,越悲观越靠近真实值。即估计值在满足≤真实值的前提下,估计函数的值越大越好。

    五、迭代加深搜索算法:总体上按照深度优先算法方法进行。多次从起点出发做深搜,每次规定一个深度限制dm。劣势:会有重复搜索,从时间效率上不如广搜,好处是因为有步数的限制所以不用判重。

    广搜有可能比深搜号,但广搜扩展出来的情况可能更多。

    六、Alpha-Beta剪枝

    极大极小搜索法(待更新)

  • 相关阅读:
    C++ 模板实现败者树,进行多路归并
    CentOS 7 使用 Realtek 8188eu 上网 (解决 Required key not available)
    C++ Concurrency in Action 读书笔记
    Linux操作系统是如何工作的
    大型项目使用Automake/Autoconf完成编译配置
    Socket 用于进程间通信 --- UNIX Domain Socket
    在Linux中实现类似windows中获取配置文 件的函数GetProfileString
    Linux Shell 1
    YAML
    ubuntu虚拟机如何连接到windows上安装的Navicat
  • 原文地址:https://www.cnblogs.com/knmxx/p/9375311.html
Copyright © 2011-2022 走看看