1. 程式人生 > >淺談搜尋

淺談搜尋

對於常規的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*

本人最喜歡的搜尋,其估價函式用於估計步數,提前結束搜尋,減少了很多層,在指數級別優化了演算法。