浅谈搜索

对于常规的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*

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

原文地址:https://www.cnblogs.com/blog-Dr-J/p/10013932.html