• 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<< "
    ";
     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
    ");
    128     else 
    129         astar();
    130     return 0;
    131 }
    View Code

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

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

  • 相关阅读:
    Java阶段测试题一
    HttpClient配置及运用(一)
    字符串数组及链表的应用:例题
    Java多线程
    String普通方法测试;可变参数
    Java连接mysql数据库
    JS练习
    foreach遍历、包装类、Object类
    Java多态总结
    类的关联,不同类属性的调用
  • 原文地址:https://www.cnblogs.com/yyf2016/p/5792360.html
Copyright © 2020-2023  润新知