浅谈搜索
Posted blog-dr-j
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈搜索相关的知识,希望对你有一定的参考价值。
对于常规的Dfs/Bfs就不说了,博弈搜索都是后话,这里主要整理高效率的搜索(也没高哪去)
搜索的时间复杂度一般是xn指数级别的所以在这里为了提高搜索效率,最好的方法是降指,以下的方法都是基于这种想法的。
1.双向Bfs、Dfs
适用于操作可逆的搜索,采用meet in the middle 的想法,将前一半搜出,后一半查询,或者直接两边一起搜,将时间复杂度降至2*xn/2
大概我是第一个用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 }
2.IDDFS
限定层数,本质上是在空间条件下不允许的情况下提高了Dfs的实际效率。
蒟蒻代码不可读
3.A*
类似一种Bfs,对于问题求解时不要求最优时使用,其中有估价函数使算法在接近答案时有较强兴奋性,使得搜索到可行解的概率大大提高。
时间复杂度比较玄学,一般在输出任意解时有用。
蒟蒻代码不可读
4.IDA*
本人最喜欢的搜索,其估价函数用于估计步数,提前结束搜索,减少了很多层,在指数级别优化了算法。
以上是关于浅谈搜索的主要内容,如果未能解决你的问题,请参考以下文章