• 浅谈搜索


    对于常规的Dfs/Bfs就不说了,博弈搜索都是后话,这里主要整理高效率的搜索(也没高哪去)

    搜索的时间复杂度一般是xn指数级别的所以在这里为了提高搜索效率,最好的方法是降指,以下的方法都是基于这种想法的。

    1.双向Bfs、Dfs

    适用于操作可逆的搜索,采用meet in the middle 的想法,将前一半搜出,后一半查询,或者直接两边一起搜,将时间复杂度降至2*xn/2

    poj1198

    大概我是第一个用Dfs的人。

      1 #include<map>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 struct cio{
      6     int i,j;
      7     void move(int direction);
      8     bool Insert(void);
      9     bool friend operator < (cio x,cio y)
     10     {
     11         if(x.i!=y.i)
     12             return x.i<y.i;
     13         return x.j<y.j;
     14     }
     15     bool friend operator == (cio x,cio y)
     16     {
     17         return (x.i==y.i)&&(x.j==y.j);
     18     }
     19     bool friend operator <=(cio x,cio y)
     20     {
     21         return (x<y)||(x==y);
     22     }
     23     bool friend operator >=(cio x,cio y)
     24     {
     25         return !(x<y);
     26     }
     27     bool friend operator !=(cio x,cio y)
     28     {
     29         return !(x==y);
     30     }
     31     bool friend operator >(cio x,cio y)
     32     {
     33         return !(x<=y);
     34     }
     35 };
     36 struct sit{
     37     cio c[5];
     38     bool friend operator < (sit x,sit y)
     39     {
     40         for(int i=1;i<=4;i++)
     41             if(x.c[i]!=y.c[i])
     42                 return x.c[i]<y.c[i];
     43         return false;
     44     }
     45     bool friend operator == (sit x,sit y)
     46     {
     47         for(int i=1;i<=4;i++)
     48             if(x.c[i]!=y.c[i])
     49                 return false;
     50         return true;
     51     }
     52     bool friend operator <=(sit x,sit y)
     53     {
     54         return (x<y)||(x==y);
     55     }
     56     bool friend operator >=(sit x,sit y)
     57     {
     58         return !(x<y);
     59     }
     60     bool friend operator !=(sit x,sit y)
     61     {
     62         return !(x==y);
     63     }
     64     bool friend operator >(sit x,sit y)
     65     {
     66         return !(x<=y);
     67     }
     68     bool Insert(void);
     69     void sort(void);
     70 }sta,fin,anc;
     71 int di[10]={0,0,0,1,-1};
     72 int dj[10]={0,1,-1,0,0};
     73 std::map<sit,int>Map;
     74 bool ans_found;
     75 bool cmp(cio x,cio y);
     76 bool check_and_ban(cio one);
     77 void Dfs_from_sta(int step,sit S);
     78 void Dfs_from_end(int step,sit S);
     79 sit Move(int which,int where,sit S);
     80 int main()
     81 {
     82     while(scanf("%d",&sta.c[1].i)!=EOF)
     83     {
     84         scanf("%d",&sta.c[1].j);
     85         for(int i=2;i<=4;i++)
     86             scanf("%d%d",&sta.c[i].i,&sta.c[i].j);
     87         for(int i=1;i<=4;i++)
     88             scanf("%d%d",&fin.c[i].i,&fin.c[i].j);
     89         Map.clear();
     90         Map[anc]=998244353;
     91         ans_found=false;
     92         Dfs_from_sta(1,sta);
     93         Dfs_from_end(1,fin);
     94         if(ans_found)
     95             puts("YES");
     96         else
     97             puts("NO");
     98     }
     99     return 0;
    100 }
    101 void Dfs_from_sta(int step,sit S)
    102 {
    103     S.sort();
    104     if(S==anc)
    105         return ;
    106     Map[S]=20010728;
    107     if(step==5)
    108         return ;
    109     step++;
    110     for(int chess=1;chess<=4;chess++)
    111         for(int direction=1;direction<=4;direction++)
    112             Dfs_from_sta(step,Move(chess,direction,S));
    113     return ;
    114 }
    115 void Dfs_from_end(int step,sit S)
    116 {
    117     if(ans_found)
    118         return ;
    119     S.sort();
    120     if(Map.find(S)!=Map.end()&&S!=anc)
    121     {
    122         ans_found=true;
    123         return ;
    124     }
    125     if(step==5)
    126         return ;
    127     step++;
    128     for(int chess=1;chess<=4;chess++)
    129         for(int direction=1;direction<=4;direction++)
    130             Dfs_from_end(step,Move(chess,direction,S));
    131     return ;
    132 }
    133 sit Move(int which,int where,sit S)
    134 {
    135     sit ans;
    136     ans=S;
    137     cio tmp=ans.c[which];
    138     tmp.move(where);
    139     for(int others=1;others<=4;others++)
    140     {
    141         if(others==which)
    142             continue;
    143         if(tmp==ans.c[others])
    144         {
    145             tmp.move(where);
    146             break;
    147         }
    148     }
    149     for(int others=1;others<=4;others++)
    150     {
    151         if(others==which)
    152             continue;
    153         if(tmp==ans.c[others])
    154             return anc;
    155     }
    156     if(check_and_ban(tmp))
    157         return anc;
    158     ans.c[which]=tmp;
    159     return ans;
    160 }
    161 bool check_and_ban(cio one)
    162 {
    163     int i=one.i;
    164     int j=one.j;
    165     if(i<=0||i>8)
    166         return true;
    167     if(j<=0||j>8)
    168         return true;
    169     return false;
    170 }
    171 bool cmp(cio x,cio y)
    172 {
    173     if(x.i!=y.i)
    174         return x.i<y.i;
    175     return x.j<y.j;
    176 }
    177 void sit::sort(void)
    178 {
    179     std::sort(c+1,c+4+1,cmp);
    180     return ;
    181 }
    182 void cio::move(int direction)
    183 {
    184     i+=di[direction];
    185     j+=dj[direction];
    186     return ;
    187 }
    View Code

    2.IDDFS

    限定层数,本质上是在空间条件下不允许的情况下提高了Dfs的实际效率。

    蒟蒻代码不可读   

    3.A*

    类似一种Bfs,对于问题求解时不要求最优时使用,其中有估价函数使算法在接近答案时有较强兴奋性,使得搜索到可行解的概率大大提高。

    时间复杂度比较玄学,一般在输出任意解时有用。

    蒟蒻代码不可读                         

    4.IDA*

    本人最喜欢的搜索,其估价函数用于估计步数,提前结束搜索,减少了很多层,在指数级别优化了算法。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              

  • 相关阅读:
    浅尝《Windows核心编程》之 等待函数
    linux 下 解压rar的过程
    一些多线程编程的例子(转)
    js数组操作《转》
    缩略图片处理<收藏>
    .net 框架
    详解NeatUpload上传控件的使用
    NHibernate工具
    xml xpath语法《转》
    C#事务技术
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10013932.html
Copyright © 2020-2023  润新知