A*算法实现 八数码问题

有关八数码问题及其参考:

http://wenku.baidu.com/view/87c92ef1ba0d4a7302763a29.html

http://blog.csdn.net/damotiansheng/article/details/40017107

http://blog.csdn.net/wsywl/article/details/5726617

下面的代码实现可以在poj上验证其正确性,估价函数可以进行修改.

poj 原题网址:http://bailian.openjudge.cn/practice/1077

  1 #include <iostream>
  2 #include <map>
  3 #include <algorithm>
  4 #include <string>
  5 #include <queue>
  6 #include <set>
  7 using namespace std;
  8 typedef long long LL;
  9 
 10 int eight[3][3], xx, xy, dx[]={0,-1,1,0}, dy[]={1,0,0,-1};
 11 char dir[] = "rudl";
 12 LL init, tar;
 13 
 14 LL encode(){
 15     LL s=eight[2][2];
 16     for(int i=7; i>=0; --i){
 17         s <<=4;
 18         s |= eight[i/3][i%3];
 19     }
 20     return s;
 21 }
 22 void decode(LL s){
 23     for(int i=0; i<9; ++i){
 24         eight[i/3][i%3] = s%16;
 25         if(s%16 == 0) 
 26             xx = i/3, xy = i%3;
 27         s >>=4;
 28     }
 29 }
 30 class Node {
 31 public:
 32     LL s, ps;
 33     int f,g,h,d;
 34     Node (LL _s=0, LL _ps=0, int _d=-1, int _f=0, int _g=0, int _h=0){
 35         s = _s, ps = _ps, f = _f, g = _g, h = _h, d = _d;
 36     }
 37     int operator<(const Node & b) const {
 38         return this->f < b.f || (this->f==b.f && this->s<b.s);
 39     }
 40 };
 41 
 42 multiset<Node> closed, open;
 43 map<LL, multiset<Node>::iterator> inOpen, inClosed;
 44 
 45 void print(Node nd){
 46     int d = nd.d;
 47     LL ts = nd.s;
 48     string ope;
 49     while(d!=-1){
 50         ope.push_back(dir[d]);
 51         auto itc = inClosed[nd.ps];
 52         nd = *itc;
 53         d = nd.d;
 54     }
 55     reverse(ope.begin(), ope.end());
 56     cout<< ope<< "\n";
 57 }
 58 int hn(LL s){
 59     decode(s);
 60     int cnt=0;
 61     for(int i=0; i<9; ++i){
 62         if(eight[i/3][i%3] != (i+1)%9) cnt++;
 63     }
 64     return cnt;
 65 }
 66 void astar(){
 67     init = encode();
 68     int inith = hn(init);
 69     Node start = Node(init, 0, -1, inith, 0, inith);
 70     open.insert(start);
 71     while(!open.empty()){
 72         Node tn = *open.begin(); inOpen.erase(tn.s); open.erase(tn);
 73         LL ts = tn.s, s2;
 74         int tf = tn.f, tg = tn.g, th = tn.h;
 75         for(int i=0; i<4; ++i){
 76             decode(ts);
 77             int r = xx+dx[i], c=xy+dy[i];
 78             if(r<0 || c<0 || r==3 || c==3) continue;
 79             swap(eight[r][c], eight[xx][xy]);
 80             s2 = encode();
 81             int g = tg+1, h = hn(s2), f = g+h;
 82             Node nd = Node(s2, ts, i, f, g, h);
 83             if(s2 == tar){
 84                 inClosed[tn.s]= closed.insert(tn);
 85                 inClosed[nd.s]= closed.insert(nd);
 86                 print(nd);
 87                 return;
 88             }
 89             auto ito = inOpen.find(s2), itc = inClosed.find(s2);
 90             if(ito == inOpen.end() && itc == inClosed.end()){
 91                 inOpen[nd.s]=open.insert(nd);
 92             }
 93             else if(ito == inOpen.end() && f < itc->second->f){
 94                 closed.erase(itc->second); inClosed.erase(itc); 
 95                 inOpen[nd.s]=open.insert(nd);
 96             }
 97             else if(itc == inClosed.end() && f < ito->second->f){
 98                 // que 里有相同s不同f的node
 99                 open.erase(ito->second), inOpen[nd.s]=open.insert(nd);
100             }
101         }
102         inClosed[tn.s] = closed.insert(tn);
103     }
104 }
105 int main(){
106     std::ios::sync_with_stdio(false);
107     char c;
108     for(int i=0; i<3; ++i){
109         for(int j=0; j<3; ++j){
110             cin>>c;
111             if(c=='x')
112                 eight[i][j]=0, xx = i, xy = j;
113             else 
114                 eight[i][j]= c-'0';
115         }
116     }
117     tar=8;
118     for(int i=7; i>0; --i)
119         tar<<=4, tar |= i;
120     int cnt=0; 
121     for(int i=0; i<9; ++i){
122         for(int pi=0; pi<i; ++pi)
123             if(eight[pi/3][pi%3] && eight[pi/3][pi%3]<eight[i/3][i%3])
124                 cnt++;
125     }
126     if(cnt%2)
127         printf("unsolvable\n");
128     else 
129         astar();
130     return 0;
131 }
View Code

 

 另外八数码问题的三种实现(bfs,dbfs,a*):

 http://www.cnblogs.com/yyf2016/p/5790127.html

posted @ 2016-08-21 11:23  Keep_Going  阅读(3308)  评论(0编辑  收藏  举报