- 浏览: 174261 次
- 性别:
- 来自: 吉林
文章分类
最新评论
-
zaocha321:
图片全部挂掉了。。
eclipse中新建maven项目 -
springdata_spring:
可以参考最新的文档:如何在eclipse jee中检出项目并转 ...
eclipse中新建maven项目
题目地址: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:
- #include<cstdio>
- #include<algorithm>
- #include<queue>
- #include<string.h>
- #include<string>
- #include<math.h>
- #include<iostream>
- using namespace std;
- int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
- string path[4]={"d","r","u","l"};
- int dp[10]={1,1,2,6,24,120,720,5040,40320,362880};
- int final[9]={1,2,3,4,5,6,7,8,0};
- bool hashtable[362885];
- class state
- {
- public:
- int a[9],exp,zero,dept;
- string path;
- state(){};
- state(int num[9])
- {
- for(int i=0;i<9;++i)
- a[i]=num[i];
- }
- void swapn(int c)
- {
- swap(a[zero],a[c]);
- }
- };
- struct cmp
- {
- bool operator()(const state x,const state y)
- {
- return x.exp>y.exp;
- }
- };
- int getHash(int code[9])
- {
- int sum=0;
- bool flag[9];
- int k;
- memset(flag,false,sizeof(flag));
- for(int i=0;i<9;++i)
- {
- k=0;
- for(int j=code[i]+1;j<9;++j)
- {
- if(!flag[j])
- ++k;
- }
- sum+=k*dp[8-i];
- flag[code[i]]=true;
- }
- return 362879-sum;
- }
- int Eudis(int a[9])
- {
- int dis=0;
- for(int i=0;i<9;++i)
- {
- for(int j=0;j<9;++j)
- {
- if(a[i]==final[j])
- {
- dis+=fabs(1.0*(i/3-j/3))+fabs(1.0*(i%3-j%3));
- break;
- }
- }
- }
- return dis/2;
- }
- state ans;
- bool bfs(state ori)
- {
- priority_queue<state,vector<state>,cmp >open;
- //queue<state>open;
- open.push(ori);
- while(!open.empty())
- {
- state t=open.top();
- open.pop();
- if(Eudis(t.a)==0)
- {
- ans=t;
- return true;
- }
- for(int i=0;i<4;++i)
- {
- int row=t.zero/3;
- int col=t.zero%3;
- int arow=row+next[i][1];
- int acol=col+next[i][0];
- if(arow<3&&arow>=0&&acol<3&&acol>=0)
- {
- int sw=arow*3+acol;
- state tmp=t;
- tmp.swapn(sw);
- tmp.zero=sw;
- int hcode=getHash(tmp.a);
- if(hashtable[hcode])
- continue;
- hashtable[hcode]=true;
- int dis=50*Eudis(tmp.a);
- ++tmp.dept;
- tmp.exp=dis+tmp.dept;
- tmp.path+=path[i];
- open.push(tmp);
- }
- }
- }
- return false;
- }
- void test(bool flag[9],int b,int num[9])
- {
- if(b>8)
- {
- printf("%d\n",getHash(num));
- return;
- }
- for(int i=0;i<9;++i)
- {
- if(!flag[i])
- {
- flag[i]=true;
- num[b]=i;
- test(flag,b+1,num);
- flag[i]=false;
- }
- }
- }
- bool isSolveable (int statue[9])
- {
- int num=0;
- for (int i=1;i<=8;++i)
- {
- if(statue[i]==0)
- continue;
- for(int j=0;j<i;++j)
- {
- if(statue[j]==0)
- continue;
- if(statue[i]>statue[j])
- ++num;
- }
- }
- if (num%2==1) return false;
- return true;
- }
- int main()
- {
- //bool ff[9];
- //int nn[9];
- //memset(ff,false,sizeof(ff));
- //memset(nn,false,sizeof(nn));
- //test(ff,0,nn);
- //int a[9]={0,1,2,3,4,5,6,7,8};
- //int b[9]={8,7,6,5,4,3,2,1,0};
- //printf("%d\n",getHash(b));
- freopen("e:\\zoj\\zoj_1217.txt","r",stdin);
- while(1)
- {
- memset(hashtable,0,sizeof(hashtable));
- int flag=0;
- int num[9];
- int zero;
- char c;
- for(int i=0;i<9;++i)
- {
- if(scanf(" %c",&c)==EOF)
- return 0;
- if(c=='x')
- {
- zero=flag;
- num[flag++]=0;
- }
- if(c<='9'&&c>='1')
- num[flag++]=c-48;
- if(flag>=9)
- break;
- }
- state ori(num);
- ori.exp=20*Eudis(num);
- ori.zero=zero;
- ori.dept=0;
- int hcode=getHash(num);
- hashtable[hcode]=true;
- if(!isSolveable(num))
- printf("unsolvable\n");
- else
- {
- bool f=bfs(ori);
- int l=ans.path.length();
- for(int i=0;i<l;++i)
- printf("%c",ans.path[i]);
- puts("");
- }
- }
- }
双向BFS:
- #include<cstdio>
- #include<algorithm>
- #include<queue>
- #include<string.h>
- #include<string>
- #include<iostream>
- using namespace std;
- int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
- string path[4]={"d","r","u","l"};
- string path2[4]={"u","l","d","r"};
- int dp[10]={1,1,2,6,24,120,720,5040,40320,362880};
- int final[9]={1,2,3,4,5,6,7,8,0};
- int hashtable[362885];
- class state
- {
- public:
- int a[9],zero;
- string path;
- state(){};
- state(int num[9])
- {
- for(int i=0;i<9;++i)
- a[i]=num[i];
- }
- void swapn(int c)
- {
- swap(a[zero],a[c]);
- }
- };
- state x,y;
- state sl[362885];
- int getHash(int code[9])
- {
- int sum=0;
- bool flag[9];
- int k;
- memset(flag,false,sizeof(flag));
- for(int i=0;i<9;++i)
- {
- k=0;
- for(int j=code[i]+1;j<9;++j)
- {
- if(!flag[j])
- ++k;
- }
- sum+=k*dp[8-i];
- flag[code[i]]=true;
- }
- return 362879-sum;
- }
- bool check(state a,state b)
- {
- bool flag=true;
- for(int i=0;i<9;++i)
- {
- if(a.a[i]!=b.a[i])
- {
- flag=false;
- break;
- }
- }
- return flag;
- }
- bool bfs(state ori,state fin)
- {
- queue<state>open,open2;
- open.push(ori);
- open2.push(fin);
- int hcode,fcode;
- state tmp,tmp2,t1,t2;
- while(1)
- {
- if(!open.empty())
- {
- t1=open.front();
- open.pop();
- for(int i=0;i<4;++i)
- {
- int row=t1.zero/3;
- int col=t1.zero%3;
- int arow=row+next[i][1];
- int acol=col+next[i][0];
- if(arow<3&&arow>=0&&acol<3&&acol>=0)
- {
- int sw=arow*3+acol;
- tmp=t1;
- tmp.swapn(sw);
- tmp.zero=sw;
- tmp.path+=path[i];
- hcode=getHash(tmp.a);
- if(hashtable[hcode]==1)
- continue;
- if(hashtable[hcode]==2)
- {
- x=tmp;
- y=sl[hcode];
- return true;
- }
- hashtable[hcode]=1;
- sl[hcode]=tmp;
- open.push(tmp);
- }
- }
- }
- if(!open2.empty())
- {
- t2=open2.front();
- open2.pop();
- for(int i=0;i<4;++i)
- {
- int row=t2.zero/3;
- int col=t2.zero%3;
- int arow=row+next[i][1];
- int acol=col+next[i][0];
- if(arow<3&&arow>=0&&acol<3&&acol>=0)
- {
- int sw=arow*3+acol;
- tmp2=t2;
- tmp2.swapn(sw);
- tmp2.zero=sw;
- tmp2.path+=path2[i];
- fcode=getHash(tmp2.a);
- if(hashtable[fcode]==2)
- continue;
- if(hashtable[fcode]==1)
- {
- y=tmp2;
- x=sl[fcode];
- return true;
- }
- hashtable[fcode]=2;
- sl[fcode]=tmp2;
- open2.push(tmp2);
- }
- }
- }
- }
- return false;
- }
- bool isSolveable (int statue[9])
- {
- int num=0;
- for (int i=1;i<=8;++i)
- {
- if(statue[i]==0)
- continue;
- for(int j=0;j<i;++j)
- {
- if(statue[j]==0)
- continue;
- if(statue[i]>statue[j])
- ++num;
- }
- }
- if (num%2==1) return false;
- return true;
- }
- int main()
- {
- freopen("e:\\zoj\\zoj_1217.txt","r",stdin);
- while(1)
- {
- memset(hashtable,0,sizeof(hashtable));
- int flag=0;
- int num[9];
- int zero;
- char c;
- for(int i=0;i<9;++i)
- {
- if(scanf(" %c",&c)==EOF)
- return 0;
- if(c=='x')
- {
- zero=flag;
- num[flag++]=0;
- }
- if(c<='9'&&c>='1')
- num[flag++]=c-48;
- if(flag>=9)
- break;
- }
- state ori(num);
- ori.zero=zero;
- state fin(final);
- fin.zero=8;
- int ocode=getHash(num);
- int fcode=getHash(final);
- hashtable[ocode]=1;
- hashtable[fcode]=2;
- sl[ocode]=ori;
- sl[fcode]=fin;
- if(!isSolveable(num))
- printf("unsolvable\n");
- else
- {
- if(check(ori,fin))
- puts("");
- bool f=bfs(ori,fin);
- int l=x.path.length();
- for(int i=0;i<l;++i)
- printf("%c",x.path[i]);
- l=y.path.length();
- for(int i=l-1;i>=0;--i)
- printf("%c",y.path[i]);
- puts("");
- }
- }
- }
发表评论
-
源代码:基于A*算法的八数码问题的实现(用OpenGL实现动态演示)
2012-04-15 21:25 1587转载请注明出处:http://hi.baidu.com/ ... -
源代码:基于A*算法的八数码问题的实现(类的定义与实现)
2012-04-15 21:25 1320转载请注明出处:http://hi.baidu.com/lvc ... -
八数码问题使用HashTable优化查找后的版本
2012-04-07 11:17 1358在《双向广度优先搜索算法框架及八数码问题例程》一文中,给 ... -
双向广度优先搜索算法框架及八数码问题例程
2012-04-07 11:16 4624双向广度优先搜索算 ... -
用 A* 解决八数码问题
2012-04-07 11:13 1346Description The 15-puzzle has ... -
八数码问题源代码
2012-04-07 11:05 2213题目描述: 八方块移动游戏要求从一个含8个数字(用1- ...
相关推荐
标题中的“八数码”是指经典的八数码问题,也被称为滑动拼图游戏。在这个游戏中,一个3x3的...通过比较BFS、DFS、BBFS和A*在解决八数码问题上的性能,我们可以深入理解它们的优缺点,并为实际问题选择合适的搜索策略。
# pyqt5 八数码拼图游戏 广度优先搜索(bfs)、双向广搜(dbfs)、A*搜索求解 1. pyqt5制作可视化窗口,qss美观ui; 2. 自定义导入图片,生成3、4、5阶八数码拼图; 3. 可以点击移动小方块进行游戏; 4. 可以选择使用...
解决八数码的问题可以使用多种算法,包括深度优先搜索(DFS)、宽度优先搜索(BFS)、迭代加深搜索、爬山法、双向搜索、A*算法和DIA算法等。 1. 深度优先搜索(DFS) 深度优先搜索是一种常用的搜索算法,它从起点...
### 八数码(九宫格)问题解析 #### 一、问题简介 八数码问题,又称九宫格问题,是一种经典的益智游戏,也是人工智能领域内的一个著名问题。该问题在一个3×3的棋盘上放置了八个数字牌(1至8),剩下的一个空格...
描述中提到的“双向BFS解立体八数码问题”表明这个项目使用了广度优先搜索(BFS)算法来解决立体版的八数码问题。立体八数码是在二维八数码的基础上扩展的,增加了更多的维度,使得问题的复杂性增加,解决起来更具...
在C#编程语言中,8数码问题(也称为8-puzzle)是一个经典的计算机科学问题,它基于滑动拼图游戏。这个题目涉及到算法设计、搜索策略以及状态空间的表示。在这个压缩包中,可能包含了一个或多个C#程序,用于解决8数码...
课程中讨论了如何使用不同的搜索策略(如BFS vs DFS)来优化解决方案,同时提出了节省存储空间和加速搜索的方法,例如使用A*算法、双向BFS、HASH映射和并行算法等。 - **木棒问题**:涉及到分割给定长度的木棒,以...
递归和排列 BFS BFS和队列 状态图搜索:八数码问题 BFS与A*算法 双向广搜 DFS DFS和递归 回溯与剪枝:八皇后 迭代加深搜索 IDA
**题目:** 一片容量为8GB的SD卡能储存大约( )张大小为2MB的数码照片。 **选项:** A. 1600 B. 2000 C. 4000 D. 16000 **解析:** 首先将SD卡的容量统一为MB单位进行计算。8GB = 8 * 1024 MB = 8192MB。一张2MB的...
1. BFS的剪枝通常基于状态的重复性,如八数码问题中,通过记录和比较已经访问过的状态,避免重复搜索相同的棋盘配置,从而降低复杂度。 2. DFS剪枝则更加多样化,包括: - 可行性剪枝:在遇到非法状态时立即终止...
##### 九数码问题(ZJOI2005) - **题目描述**:给定一个初始状态的九宫格,目标是通过合法移动将九宫格变为目标状态。 - **解题思路**: - 从初始状态和目标状态同时开始广度优先搜索。 - 当两个搜索方向遇到...
- 八数码问题(又称滑动拼图游戏)可以用这些搜索算法来求解。 3. **逻辑与推理** - 谓词逻辑法用于表达复杂的事实和关系,并能进行定理证明。 - 语义网络是一种知识表示方法,适用于表达和推理。 - 子句集求解...
第7章 DFS与BFS以及剪枝问题……………………………………………………119 7.1 深度优先遍历……………………………………………………………………119 〖案例l〗15数码难题…………………………………………...