zoukankan      html  css  js  c++  java
  • 深搜和广搜的原理及优缺点

    原文来源:https://blog.csdn.net/dark_cy/article/details/88926435

    深搜原理
    深搜,顾名思义,是深入其中、直取结果的一种搜索方法。
      如果深搜是一个人,那么他的性格一定倔得像头牛!他从一点出发去旅游,只朝着一个方向走,除非路断了,他绝不改变方向!除非四个方向全都不通或遇到终点,他绝不后退一步!因此,他的姐姐广搜总是嘲笑他,说他是个一根筋、不撞南墙不回头的家伙。
      深搜很讨厌他姐姐的嘲笑,但又不想跟自己的亲姐姐闹矛盾,于是他决定给姐姐讲述自己旅途中的经历,来改善姐姐对他的看法。他成功了,而且只讲了一次。从那以后他姐姐不仅再没有嘲笑过他,而且连看他的眼神都充满了赞赏。他以为是自己路上的各种英勇征服了姐姐,但他不知道,其实另有原因……
      深搜是这样跟姐姐讲的:关于旅行呢,我并不把目的地的风光放在第一位,而是更注重于沿路的风景,所以我不会去追求最短路,而是把所有能通向终点的路都走一遍。可是我并不知道往哪走能到达目的地,于是我只能每到一个地方,就向当地的人请教各个方向的道路情况。为了避免重复向别人问同一个方向,我就给自己规定1 :先问北,如果有路,那就往北走,到达下一个地方的时候就在执行此规定,如果往北不通,我就再问西,其次是南、东,要是这四个方向都不通或者抵达了终点,那我回到上一个地方,继续探索其他没去过的方向。我还要求自己要记住2 那些帮过他的人,但是那些给我帮倒忙的、让我白费力气的人,要忘记3他们。有了这些规定之后,我就可以大胆的往前走了,既不用担心到不了不目的地,也不用担心重复走以前的路。哈哈哈……

    深搜优缺点

      • 优点
        1、能找出所有解决方案
        2、优先搜索一棵子树,然后是另一棵,所以和广搜对比,有着内存需要相对较少的优点
      • 缺点
        1、要多次遍历,搜索所有可能路径,标识做了之后还要取消。
        2、在深度很大的情况下效率不高

    深搜模板

    void DFS() //N代表目前DFS的深度
    {
        if(找到解) //进行相应的操作
        {
            …
            return;
        }
        for(inti=0;i<4;i++) //枚举四个方向
        {
            DFS(N+1); //进入下层递归
        }
    }
    

    广搜原理
    广搜,顾名思义,是多管齐下、广撒网的一种搜索方法
      如果广搜是一个人,那么她一定很贪心,而且喜新厌旧!她从一点出发去旅游,先把与起点相邻的地方全部游览一遍,然后再把与她刚游览过的景点相邻的景点全都游览一遍……一直这样,直至所有的景点都游览一遍。
      广搜属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。类似树的按层遍历,其过程为:首先访问初始点Vi,并将其标记为已访问过,接着访问Vi的所有未被访问过可到达的邻接点Vi1、Vi2…Vit,并均标记为已访问过,然后再按照Vi1、Vi2…Vit 的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过,依此类推,直到图中所有和初始点Vi有路径相通的顶点都被访问过为止。

    广搜优缺点

      • 优点
        1、对于解决最短或最少问题特别有效,而且寻找深度小
        2、每个结点只访问一遍,结点总是以最短路径被访问,所以第二次路径确定不会比第一次短
      • 缺点
        1、内存耗费量大(需要开大量的数组单元用来存储状态)

    广搜模板

    void BFS() 
    {     … …//初始化起点入队 
        while(!q.empty()) //判断队是否为空
        {    … …//获取队首元素
            if(... …){… …}//判断是否是终点
            for(int i=0;i<4;i++)//四个方向
            { 
                k.x=p.x+dir[i][0];
                k.y=p.y+dir[i][1];
                //向各个方向走一步
                 if(judge())//判断能不能走
                {
                    … …//各种处理 
                    vis[k.x][k.y]=1; //标记     
                    q.push(k); //入队
                }
            }
        }
    }
    

    广搜打印路径:虽然它有多个后继结点,但前驱节点只有一个。所以可以逆向打印路径,即从终点出发找通向起点的路径。


    1. 遍历四个方向
    2. 标记,标识已经走过的结点
    3. 取消标记
  • 相关阅读:
    day7 面向对象 静态方法 类方法 属性方法 类的特殊成员方法 元类 反射 异常处理
    day6 面向对象 封装 继承 多态 类与实例在内存中的关系 经典类和新式类
    day5 time datetime random os sys shutil json pickle shelve xml configparser hashlib subprocess logging re正则 python计算器
    kafka常用操作命令
    linux基础
    django学习1——初识web应用程序
    mysql数据库(三)——pymysql模块
    mysql数据库(二)——表的查询
    mysql数据库(一)
    Python常用模块——re模块
  • 原文地址:https://www.cnblogs.com/RioTian/p/13064420.html
Copyright © 2011-2022 走看看