zoukankan      html  css  js  c++  java
  • 搜索模板

    深度优先搜索,就是将可能的答案从头到尾进行递归枚举,在确定前一部分的情况下,根据规则往下扩展答案树,直到得到可行的答案

    广搜,借助队列实现,扩展节点入队

    双向广搜,双向扩展结点,在两个方向的扩展顺序上,可以轮流交替进行,但由于大部分的解答树并不是棵完全树 ,在扩展完一层后,下一层则选择结点个数较少的那个方向先扩展,可以克服两个方向结点生成速度不平衡的状态,明显提高搜索效率

    剪枝

    1.如果当前节点已经到达过,就可以直接剪掉,这个可以用哈希表来实现,也可以根据情况直接开一个Judge数组

    2.使用估价函数判定,如果在最乐观的情况下,所需要的步数仍然不如已经找到的最优解,就直接剪掉

    注意事项

    1.在传递参数的过程中,如果把当前状态也传了过来,就一定要开一个备份,直接对备份进行操作,然后把备份作为参数传下去,这之后再把备份改回原来的状态

    2.在搜索方案的过程中,如果在往下走之前把judge数组设了一,递归完一定要再改成零

    3.在循环搜索填下一个空的时候,如果开了变量,要对状态进行一定处理,并有他进行judge数组记录,在需要回溯的时候一定要看好,这个变量还是不是从一开始穿上来的那个状态引出来的

    4.一定要设置边界

    5.在判重的时候,在队首元素入队前设标记,在扩展节点前判定标记,在入队新状态前设标记

    框架:

    1.深搜

    void dfs(当前状态);
    {
               if  当前状态为边界   {
                  if 当前状态为最佳目标状态 
                         { 记下最优结果;exit;}
                   }
               for i←算符最小值 to 算符最大值 do {//状态循环变量为局部变量
                   算符i作用于当前状态,扩展出一个子状态;
                   标记子状态路径;
                   if (子状态满足约束条件) and (子状态满足最优性要求)
                      dfs(子状态);
                       恢复子状态路径;  //回溯
               }
    }
    View Code

    2.广搜

     1 void bfs(v);
     2 {
     3 Int queue(q); 
     4 Visite(v); visted[v]=true; Insert_queue(q,w);
     5 While not empty(q) do {
     6 取出队首元素 v
     7 For 对所有v扩展出来的元素w
     8 if (not visited[w] )
     9     { visite(w);visited[w]=true; Insert_queue(q,w)}
    10  delete_queue(q,v);
    11 }
    12 }
    View Code

    3.双向广搜

     1 //DOUBFS初始化,初始结点,和目标结点分别进入OPEN[1]和OPEN[2]表;
     2     head[1]=1; tail[1]=1; head[2]=1; tail[2]=1 3     do{
     4              if (tail[1]-head[1]<=tail[2]-head[2]) t=1;else t=2//优先扩展待讨论节点比较少那个方向
     5              for(i=head[t];i<=tail[t];i++)expand(t);//讨论队列中的结点
     6         }while(head[t]<=tail[t]);
     7    //函数expand(t)的结构如下:
     8   void expand(int t)
     9  {
    10       int j;
    11       for(j=1;j<=n;j++ ) //n为最多后继状态数
    12       {
    13           产生i点的第j个后继状态,将它加入到队尾(tail[t]+1);
    14           if(新结点未与其上一层以上的所有点重复)
    15           {
    16                 if isans(t) {输出结果;return;}
    17           }
    18          else{将新点从队列中去掉(tail[t]-1);}
    19       }
    20   }
    21   // 判断两个方向是否是相交点的函数isans(t)如下:
    22   bool isans(int t)
    23   {
    24         int j,k;
    25         if(t==1)k=2; else k=126         for(j=head[k] ;j<=tail[k];j++) 
    27            if(tail[t]==j)return true;//新结点tail[t]是相交点
    28         return false;
    29  }
    View Code

    4.康托展开式编码判重

     X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!

     1 int gethash(status a)
     2 {
     3     int res = 0;
     4     int k = 1;
     5     int i, j;
     6     //此处的4为每个位能达到的最大数+1 
     7     for (i = 1; i <= 4; i++)
     8         for (j = 1; j <= 4; j++)
     9         {
    10             res += a.map[i][j] * k;
    11             k *= 3;
    12         }
    13     return res;
    14 } 
    View Code

    5.位运算加速

      ·x&-x 返回最低一位1

      ·x ^ 1 等价于!x

      

  • 相关阅读:
    8/30 sql脚本
    navicat批量添加uuid去重
    循环向JsonArray添加对象
    java String字符串去除()里的内容
    工厂模式
    Thymeleaf学习
    SSH开发常用常见的src下建的包名
    04jQuery操作03
    04jQuery筛选jquery对象02
    04jQuery筛选jquery对象01
  • 原文地址:https://www.cnblogs.com/hyfer/p/4822586.html
Copyright © 2011-2022 走看看