码迷,mamicode.com
首页 > 编程语言 > 详细

A*算法实现 八数码问题

时间:2016-08-21 12:30:24      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:

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

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 };
 38 class cmp_s{
 39 public:
 40     int operator()(const Node &a, const Node &b){
 41         return a.s < b.s;
 42     }
 43 };
 44 class cmp_f{
 45 public:
 46     int operator()(const Node &a, const Node &b){
 47         // 最小堆按大于比较
 48         return a.f > b.f || (a.f==b.f && a.s > b.s);
 49     }
 50 };
 51 set<Node, cmp_s> closed, open;
 52 set<Node, cmp_s>::iterator ito, itc;
 53 priority_queue<Node, vector<Node>, cmp_f> que;
 54 
 55 void print(Node nd){
 56     int d = nd.d;
 57     string ope;
 58     while(d!=-1){
 59         ope.push_back(dir[d]);
 60         nd.s = nd.ps;
 61         itc = closed.find(nd);
 62         nd = *itc;
 63         d = nd.d;
 64     }
 65     reverse(ope.begin(), ope.end());
 66     cout<< ope<< "\n";
 67 }
 68 int hn(LL s){
 69     decode(s);
 70     int cnt=0;
 71     for(int i=0; i<9; ++i){
 72         if(eight[i/3][i%3] != (i+1)%9) cnt++;
 73     }
 74     return cnt;
 75 }
 76 void astar(){
 77     init = encode();
 78     int inith = hn(init);
 79     Node start = Node(init, 0, -1, inith, 0, inith);
 80     open.insert(start); que.push(start);
 81     while(!open.empty()){
 82         Node tn = que.top(); que.pop(); open.erase(tn);
 83         LL ts = tn.s, s2;
 84         int tf = tn.f, tg = tn.g, th = tn.h;
 85         for(int i=0; i<4; ++i){
 86             decode(ts);
 87             int r = xx+dx[i], c=xy+dy[i];
 88             if(r<0 || c<0 || r==3 || c==3) continue;
 89             swap(eight[r][c], eight[xx][xy]);
 90             s2 = encode();
 91             int g = tg+1, h = hn(s2), f = g+h;
 92             Node nd = Node(s2, ts, i, f, g, h);
 93             if(s2 == tar){
 94                 closed.insert(tn);
 95                 print(nd);
 96                 return;
 97             }
 98             ito = open.find(nd), itc = closed.find(nd);
 99             if(ito == open.end() && itc == closed.end()){
100                 open.insert(nd); que.push(nd);
101             }
102             else if(ito == open.end() && f < itc->f){
103                 closed.erase(itc); open.insert(nd); que.push(nd);
104             }
105             else if(itc == closed.end() && f < ito->f){
106                 // que 里有相同s不同f的node
107                 open.erase(ito), open.insert(nd), que.push(nd);
108             }
109         }
110         closed.insert(tn);
111     }
112 }
113 int main(){
114     std::ios::sync_with_stdio(false);
115     char c;
116     for(int i=0; i<3; ++i){
117         for(int j=0; j<3; ++j){
118             cin>>c;
119             if(c==x)
120                 eight[i][j]=0, xx = i, xy = j;
121             else 
122                 eight[i][j]= c-0;
123         }
124     }
125     tar=8;
126     for(int i=7; i>0; --i)
127         tar<<=4, tar |= i;
128     int cnt=0; 
129     for(int i=0; i<9; ++i){
130         for(int pi=0; pi<i; ++pi)
131             if(eight[pi/3][pi%3] && eight[pi/3][pi%3]<eight[i/3][i%3])
132                 cnt++;
133     }
134     if(cnt%2)
135         printf("unsolvable\n");
136     else 
137         astar();
138     return 0;
139 }
View Code

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

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

A*算法实现 八数码问题

标签:

原文地址:http://www.cnblogs.com/yyf2016/p/5792360.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!