热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

八数码问题(A*&&双向BFS)

题目地址:http:acm.zju.edu.cnonlinejudgeshowProblem.do?problemId217首先说一下八数码问题的可解性。

题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=217

      首先说一下八数码问题的可解性。

       1.互换2个非零位置,状态的逆序奇偶性将保持不变。

       2.互换0和另一个非零位置,状态的逆序奇偶性将发生颠倒。

       3.因此,如果目标状态和起始状态的逆序奇偶性相同,问题可解,否则不可解。所以对于八数码问题的一个目标状态有9!/2种可解状态

       逆序奇偶性可以这样来求,将状态转化了数列,然后去掉X位,然后对于每一位,计算在它之前小于它的个数,每一位对应的值之和就是逆序奇偶数。

      A*算法具体不多说了,它的精髓在于f(n)=g(n)+h(n),中估值函数h(n)的设计。值的注意的是:

      如果估价值h(n)<= n(到目标节点的实际步长),这种情况下,搜索的点数多,搜索范围大,效率低。但能得到最优解。

  如果 估价值>实际值, 搜索的点数少,搜索范围小,效率高,但不能保证得到最优解。

     因此在实际使用的时候应该更具需要来设计h(n)

     在zoj_1217中,为了不TLE,选择h(n)=20*dis(欧几里德距离),但是得不到最优解

zoj_1217:

Cpp代码   收藏代码
  1. #include  
  2. #include  
  3. #include  
  4. #include  
  5. #include  
  6. #include  
  7. #include  
  8. using namespace std;  
  9. int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};  
  10. string path[4]={"d","r","u","l"};  
  11. int dp[10]={1,1,2,6,24,120,720,5040,40320,362880};  
  12. int final[9]={1,2,3,4,5,6,7,8,0};  
  13. bool hashtable[362885];  
  14. class state  
  15. {  
  16. public:  
  17.     int a[9],exp,zero,dept;  
  18.     string path;  
  19.     state(){};  
  20.     state(int num[9])  
  21.     {  
  22.         for(int i=0;i<9;++i)  
  23.             a[i]=num[i];  
  24.     }  
  25.     void swapn(int c)  
  26.     {     
  27.         swap(a[zero],a[c]);  
  28.     }  
  29. };  
  30. struct cmp     
  31. {     
  32.     bool operator()(const state x,const state y)     
  33.     {     
  34.         return x.exp>y.exp;     
  35.     }     
  36. };  
  37. int getHash(int code[9])  
  38. {  
  39.     int sum=0;  
  40.     bool flag[9];  
  41.     int k;  
  42.     memset(flag,false,sizeof(flag));  
  43.     for(int i=0;i<9;++i)  
  44.     {  
  45.         k=0;  
  46.         for(int j=code[i]+1;j<9;++j)  
  47.         {  
  48.             if(!flag[j])  
  49.                 ++k;  
  50.         }  
  51.         sum+=k*dp[8-i];  
  52.         flag[code[i]]=true;  
  53.     }  
  54.     return 362879-sum;  
  55. }  
  56. int Eudis(int a[9])  
  57. {  
  58.     int dis=0;  
  59.     for(int i=0;i<9;++i)  
  60.     {  
  61.         for(int j=0;j<9;++j)  
  62.         {  
  63.             if(a[i]==final[j])  
  64.             {  
  65.                 dis+=fabs(1.0*(i/3-j/3))+fabs(1.0*(i%3-j%3));  
  66.                 break;  
  67.             }     
  68.         }  
  69.     }  
  70.     return dis/2;     
  71. }  
  72. state ans;  
  73. bool bfs(state ori)  
  74. {  
  75.     priority_queue,cmp >open;  
  76.     //queueopen;  
  77.     open.push(ori);  
  78.     while(!open.empty())  
  79.     {  
  80.         state t=open.top();  
  81.         open.pop();  
  82.         if(Eudis(t.a)==0)  
  83.         {  
  84.             ans=t;  
  85.             return true;  
  86.         }  
  87.         for(int i=0;i<4;++i)  
  88.         {  
  89.             int row=t.zero/3;  
  90.             int col=t.zero%3;  
  91.             int arow=row+next[i][1];  
  92.             int acol=col+next[i][0];  
  93.             if(arow<3&&arow>=0&&acol<3&&acol>=0)  
  94.             {  
  95.                 int sw=arow*3+acol;  
  96.                 state tmp=t;  
  97.                 tmp.swapn(sw);  
  98.                 tmp.zero=sw;  
  99.                 int hcode=getHash(tmp.a);  
  100.                 if(hashtable[hcode])  
  101.                     continue;  
  102.                 hashtable[hcode]=true;  
  103.                 int dis=50*Eudis(tmp.a);  
  104.                 ++tmp.dept;  
  105.                 tmp.exp=dis+tmp.dept;  
  106.                 tmp.path+=path[i];  
  107.                 open.push(tmp);       
  108.             }             
  109.         }  
  110.     }     
  111.     return false;  
  112. }  
  113. void test(bool flag[9],int b,int num[9])  
  114. {  
  115.     if(b>8)  
  116.     {  
  117.         printf("%d\n",getHash(num));  
  118.         return;  
  119.     }  
  120.     for(int i=0;i<9;++i)  
  121.     {  
  122.         if(!flag[i])  
  123.         {  
  124.             flag[i]=true;  
  125.             num[b]=i;  
  126.             test(flag,b+1,num);  
  127.             flag[i]=false;  
  128.         }  
  129.     }  
  130. }  
  131. bool isSolveable (int statue[9])    
  132. {    
  133.     int num=0;  
  134.     for (int i=1;i<=8;++i)    
  135.         {    
  136.             if(statue[i]==0)  
  137.             continue;  
  138.         for(int j=0;j
  139.             {    
  140.                     if(statue[j]==0)  
  141.                 continue;  
  142.             if(statue[i]>statue[j])   
  143.                 ++num;    
  144.             }    
  145.         }    
  146.         if (num%2==1) return false;    
  147.         return true;    
  148. }    
  149.   
  150. int main()  
  151. {  
  152.     //bool ff[9];  
  153.     //int nn[9];  
  154.     //memset(ff,false,sizeof(ff));  
  155.     //memset(nn,false,sizeof(nn));  
  156.     //test(ff,0,nn);  
  157.     //int a[9]={0,1,2,3,4,5,6,7,8};  
  158.     //int b[9]={8,7,6,5,4,3,2,1,0};  
  159.     //printf("%d\n",getHash(b));  
  160.     freopen("e:\\zoj\\zoj_1217.txt","r",stdin);  
  161.     while(1)  
  162.     {  
  163.         memset(hashtable,0,sizeof(hashtable));  
  164.         int flag=0;  
  165.         int num[9];  
  166.         int zero;  
  167.         char c;  
  168.         for(int i=0;i<9;++i)  
  169.         {  
  170.             if(scanf(" %c",&c)==EOF)  
  171.                 return 0;  
  172.             if(c=='x')  
  173.             {     
  174.                 zero=flag;  
  175.                 num[flag++]=0;  
  176.             }  
  177.             if(c<='9'&&c>='1')  
  178.                 num[flag++]=c-48;  
  179.             if(flag>=9)  
  180.                 break;    
  181.         }  
  182.         state ori(num);  
  183.         ori.exp=20*Eudis(num);  
  184.         ori.zero=zero;  
  185.         ori.dept=0;  
  186.         int hcode=getHash(num);  
  187.         hashtable[hcode]=true;  
  188.         if(!isSolveable(num))  
  189.             printf("unsolvable\n");  
  190.         else  
  191.         {         
  192.         bool f=bfs(ori);  
  193.         int l=ans.path.length();  
  194.         for(int i=0;i
  195.             printf("%c",ans.path[i]);  
  196.         puts("");  
  197.         }  
  198.     }  
  199. }  

 双向BFS:

 

Cpp代码   收藏代码
  1. #include  
  2. #include  
  3. #include  
  4. #include  
  5. #include  
  6. #include  
  7. using namespace std;  
  8. int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};  
  9. string path[4]={"d","r","u","l"};  
  10. string path2[4]={"u","l","d","r"};  
  11. int dp[10]={1,1,2,6,24,120,720,5040,40320,362880};  
  12. int final[9]={1,2,3,4,5,6,7,8,0};  
  13. int hashtable[362885];  
  14. class state  
  15. {  
  16. public:  
  17.     int a[9],zero;  
  18.     string path;  
  19.     state(){};  
  20.     state(int num[9])  
  21.     {  
  22.         for(int i=0;i<9;++i)  
  23.             a[i]=num[i];  
  24.     }  
  25.     void swapn(int c)  
  26.     {     
  27.         swap(a[zero],a[c]);  
  28.     }  
  29. };  
  30. state x,y;  
  31. state sl[362885];  
  32. int getHash(int code[9])  
  33. {  
  34.     int sum=0;  
  35.     bool flag[9];  
  36.     int k;  
  37.     memset(flag,false,sizeof(flag));  
  38.     for(int i=0;i<9;++i)  
  39.     {  
  40.         k=0;  
  41.         for(int j=code[i]+1;j<9;++j)  
  42.         {  
  43.             if(!flag[j])  
  44.                 ++k;  
  45.         }  
  46.         sum+=k*dp[8-i];  
  47.         flag[code[i]]=true;  
  48.     }  
  49.     return 362879-sum;  
  50. }  
  51. bool check(state a,state b)  
  52. {  
  53.     bool flag=true;  
  54.     for(int i=0;i<9;++i)  
  55.     {  
  56.         if(a.a[i]!=b.a[i])  
  57.         {  
  58.             flag=false;  
  59.             break;  
  60.         }  
  61.     }  
  62.     return flag;  
  63. }  
  64. bool bfs(state ori,state fin)  
  65. {  
  66.     queueopen,open2;  
  67.     open.push(ori);  
  68.     open2.push(fin);  
  69.     int hcode,fcode;  
  70.     state tmp,tmp2,t1,t2;  
  71.     while(1)  
  72.     {  
  73.         if(!open.empty())  
  74.         {  
  75.             t1=open.front();  
  76.             open.pop();  
  77.             for(int i=0;i<4;++i)  
  78.             {  
  79.                 int row=t1.zero/3;  
  80.                 int col=t1.zero%3;  
  81.                 int arow=row+next[i][1];  
  82.                 int acol=col+next[i][0];  
  83.                 if(arow<3&&arow>=0&&acol<3&&acol>=0)  
  84.                 {  
  85.                     int sw=arow*3+acol;  
  86.                     tmp=t1;  
  87.                     tmp.swapn(sw);  
  88.                     tmp.zero=sw;  
  89.                     tmp.path+=path[i];  
  90.                     hcode=getHash(tmp.a);  
  91.                     if(hashtable[hcode]==1)  
  92.                         continue;  
  93.                     if(hashtable[hcode]==2)  
  94.                     {  
  95.                         x=tmp;  
  96.                         y=sl[hcode];  
  97.                         return true;  
  98.                     }  
  99.                     hashtable[hcode]=1;  
  100.                     sl[hcode]=tmp;  
  101.                     open.push(tmp);       
  102.                 }             
  103.             }  
  104.         }  
  105.         if(!open2.empty())  
  106.         {  
  107.             t2=open2.front();  
  108.             open2.pop();  
  109.             for(int i=0;i<4;++i)  
  110.             {  
  111.                 int row=t2.zero/3;  
  112.                 int col=t2.zero%3;  
  113.                 int arow=row+next[i][1];  
  114.                 int acol=col+next[i][0];  
  115.                 if(arow<3&&arow>=0&&acol<3&&acol>=0)  
  116.                 {  
  117.                     int sw=arow*3+acol;  
  118.                     tmp2=t2;  
  119.                     tmp2.swapn(sw);  
  120.                     tmp2.zero=sw;  
  121.                     tmp2.path+=path2[i];  
  122.                     fcode=getHash(tmp2.a);  
  123.                     if(hashtable[fcode]==2)  
  124.                         continue;  
  125.                     if(hashtable[fcode]==1)  
  126.                     {  
  127.                         y=tmp2;  
  128.                         x=sl[fcode];  
  129.                         return true;  
  130.                     }  
  131.                     hashtable[fcode]=2;  
  132.                     sl[fcode]=tmp2;  
  133.                     open2.push(tmp2);         
  134.                 }             
  135.             }     
  136.         }  
  137.     }     
  138.     return false;  
  139. }  
  140. bool isSolveable (int statue[9])    
  141. {    
  142.     int num=0;  
  143.     for (int i=1;i<=8;++i)    
  144.         {    
  145.             if(statue[i]==0)  
  146.             continue;  
  147.         for(int j=0;j
  148.             {    
  149.                     if(statue[j]==0)  
  150.                 continue;  
  151.             if(statue[i]>statue[j])   
  152.                 ++num;    
  153.             }    
  154.         }    
  155.         if (num%2==1) return false;    
  156.         return true;    
  157. }    
  158.   
  159. int main()  
  160. {  
  161.     freopen("e:\\zoj\\zoj_1217.txt","r",stdin);  
  162.     while(1)  
  163.     {  
  164.         memset(hashtable,0,sizeof(hashtable));  
  165.         int flag=0;  
  166.         int num[9];  
  167.         int zero;  
  168.         char c;  
  169.         for(int i=0;i<9;++i)  
  170.         {  
  171.             if(scanf(" %c",&c)==EOF)  
  172.                 return 0;  
  173.             if(c=='x')  
  174.             {     
  175.                 zero=flag;  
  176.                 num[flag++]=0;  
  177.             }  
  178.             if(c<='9'&&c>='1')  
  179.                 num[flag++]=c-48;  
  180.             if(flag>=9)  
  181.                 break;    
  182.         }  
  183.         state ori(num);  
  184.         ori.zero=zero;  
  185.         state fin(final);  
  186.         fin.zero=8;  
  187.         int ocode=getHash(num);  
  188.         int fcode=getHash(final);  
  189.         hashtable[ocode]=1;  
  190.         hashtable[fcode]=2;  
  191.         sl[ocode]=ori;  
  192.         sl[fcode]=fin;  
  193.         if(!isSolveable(num))  
  194.             printf("unsolvable\n");  
  195.         else  
  196.         {         
  197.             if(check(ori,fin))  
  198.                 puts("");  
  199.             bool f=bfs(ori,fin);  
  200.             int l=x.path.length();  
  201.             for(int i=0;i
  202.                 printf("%c",x.path[i]);  
  203.             l=y.path.length();  
  204.             for(int i=l-1;i>=0;--i)  
  205.                 printf("%c",y.path[i]);  
  206.             puts("");  
  207.         }  
  208.     }  
  209. }  


推荐阅读
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 近年来,大数据成为互联网世界的新宠儿,被列入阿里巴巴、谷歌等公司的战略规划中,也在政府报告中频繁提及。据《大数据人才报告》显示,目前全国大数据人才仅46万,未来3-5年将出现高达150万的人才缺口。根据领英报告,数据剖析人才供应指数最低,且跳槽速度最快。中国商业结合会数据剖析专业委员会统计显示,未来中国基础性数据剖析人才缺口将高达1400万。目前BAT企业中,60%以上的招聘职位都是针对大数据人才的。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • 关键词:塞尔达旷传说野之息、switch、cemu设置、Wii U、租赁、游戏机 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
author-avatar
浪子一品香_938
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有