AI八数码问题 Stack Overflow

问题描述

AI课本八数码问题,我是用广度优先搜索,用Ismatch来记录状态是否已经遍历,个人感觉算法基本没错吧!可是编译程序的时候只要步数长一点(5步可以输出)就没有输出,用Debug调试显示是:Stack Overflow。我看了很久的代码,也没有搞懂需要在哪里做优化。希望大家看下给点意见。谢谢#include <stdio.h>#include <string.h>#define M 362881bool IsAnswer = false;bool Ismatch[M];//标记是否已经遍历过int tos,len;//队列指针tos,长度lenint tt[9]={1,1,2,6,24,120,720,5040,40320};char dest[10];//目标状态char tmap[10];enum dir{up,down,left,right,none};struct {int dir;int t;}path[M];//记录路径struct eightnum{char map[10];int x,y;int father;dir myDir;//父节点移动的方向}num[M];eightnum temp;void back_push(eightnum _num)//push{strcpy(num[len].map, _num.map);num[len].x = _num.x;num[len].y = _num.y;num[len].father = _num.father;num[len].myDir = _num.myDir;++len;}eightnum front_pop()//pop{tos++;if(tos<len)return num[tos];elseprintf("Wrong about the queue!n");}int getHash(char _map[])//获取hash{int hash;int k,l;hash = 0;int count = 0; for(k=0;k<9;++k){count = 0;for(l = 0 ; l < k ;++ l){if(_map[k]<_map[l])count++;}hash += count*tt[k];}return hash;}int ReverseNum(char _map[])//逆序数{int k,l;int count = 0;for(k=0;k<9;++k){for(l = 0 ; l < k ;++ l){if(_map[k] == '0')continue;else if(_map[k]<_map[l])count++;}}return count;}void DFS(eightnum _tmp)//dfs{getHash(_tmp.map);if(strcmp(_tmp.map,dest)==0){//find the answerIsAnswer = true;printf("Find the path!n");return;}else if(len>=M){//flowprintf("Above Flow!");return ;}else{//downif( _tmp.x != 2){strcpy(tmap,_tmp.map);char m_tmp;m_tmp = tmap[_tmp.x*3+_tmp.y];tmap[_tmp.x*3+_tmp.y] = tmap[(_tmp.x+1)*3+_tmp.y];tmap[(_tmp.x+1)*3+_tmp.y] = m_tmp;int m_hash = getHash(tmap);if(Ismatch[m_hash]==false){Ismatch[m_hash] = true;strcpy(temp.map,tmap);temp.x = _tmp.x + 1;temp.y = _tmp.y;temp.father = tos;temp.myDir = down;back_push(temp);}}//rightif( _tmp.y != 2 ){strcpy(tmap,_tmp.map);char m_tmp;m_tmp = tmap[(_tmp.x)*3+_tmp.y];tmap[(_tmp.x)*3+_tmp.y]= tmap[(_tmp.x)*3+_tmp.y+1];tmap[(_tmp.x)*3+_tmp.y+1] = m_tmp;int m_hash = getHash(tmap);if(Ismatch[m_hash]==false){Ismatch[m_hash] = true;strcpy(temp.map,tmap);temp.x = _tmp.x;temp.y = _tmp.y+1;temp.father = tos;temp.myDir = right;back_push(temp);}}//upif(_tmp.x != 0){strcpy(tmap,_tmp.map);char m_tmp;m_tmp = tmap[_tmp.x*3+_tmp.y];tmap[_tmp.x*3+_tmp.y] = tmap[(_tmp.x-1)*3+_tmp.y];tmap[(_tmp.x-1)*3+_tmp.y] = m_tmp;int m_hash = getHash(tmap);if(Ismatch[m_hash]==false){Ismatch[m_hash] = true;strcpy(temp.map,tmap);temp.x = _tmp.x - 1;temp.y = _tmp.y;temp.father = tos;temp.myDir = up;back_push(temp);}}//leftif( _tmp.y != 0 ){strcpy(tmap,_tmp.map);char m_tmp;m_tmp = tmap[_tmp.x*3+_tmp.y];tmap[_tmp.x*3+_tmp.y]= tmap[(_tmp.x)*3+_tmp.y-1];tmap[(_tmp.x)*3+_tmp.y-1] = m_tmp;int m_hash = getHash(tmap);if(Ismatch[m_hash]==false){Ismatch[m_hash] = true;strcpy(temp.map,tmap);temp.x = _tmp.x;temp.y = _tmp.y-1;temp.father = tos;temp.myDir = left;back_push(temp);}}}eightnum m_tmp = front_pop();DFS(m_tmp);}void myDisplay(char _map[]){//displayint ii;for(ii=0;ii<9;++ii){if(0==ii%3)printf("n");if(_map[ii] == '0')printf(" ");elseprintf("%c ",_map[ii]);}printf("n-----------------------------n");}int main(){char input[10] ;//输入strcpy(input,"283164705");strcpy(dest,"123804765");int i;tos = -1;len = 0;strcpy(temp.map,input);printf("原始状态:n");myDisplay(input);for(i=0;i<M;++i)Ismatch[i] = false;if( ReverseNum(input)%2 != ReverseNum(dest)%2){printf("Not exist the answer!n");return 1;}for(i=0;i<10;++i){if(temp.map[i] == '0'){Ismatch[getHash(temp.map)] = true;temp.x = i/3;temp.y = i%3;temp.father=-1;temp.myDir = none;back_push(temp);break;}}eightnum _tmp = front_pop();DFS(_tmp);int kk = 0;if (IsAnswer){int ff = tos ;while( num[ff].father != -1){path[kk].dir = num[ff].myDir;path[kk].t = ff;kk++;//printf("%d",num[ff].myDir);ff = num[ff].father;}}for(i=kk-1;i>=0;--i){if(path[i].dir==0){printf("down-->");myDisplay(num[path[i].t].map);}else if(path[i].dir==1){printf("up-->");myDisplay(num[path[i].t].map);}else if(path[i].dir==2){printf("right-->");myDisplay(num[path[i].t].map);}else if(path[i].dir==3){printf("left-->");myDisplay(num[path[i].t].map);}}return 0;}ps:用“在link option中增加/stack”这种方法可以实现步长到27,我是想知道是否有更好的方法可以优化代码

解决方案

你这里面使用了递归没有 ? 看你这种情况,引起堆栈溢出的可能性,有两种。一种是递归,一种就是内存没有往堆上分配,即没有使用malloc等内存分配函数。我认为递归引起的可能性更大。

时间: 2024-11-27 11:25:57

AI八数码问题 Stack Overflow的相关文章

uva 652---Eight Poj 1077 ---Eight zoj 1217---Eight (八数码解法2)

点击打开链接uva 652 点击打开链接hdu 1043 点击打开链接zoj 1217                                                              八数码解法2 解题整体思路 :    预处理+哈希判重+打表+输出路径                               我们知道对于八数码问题而言,每一个状态就是每一个格子的编号(我们把空格看成9),那么最多有9!种,那么现在针对每一种状态都有9个数字,难道我们开一个9维数组,

uva 652---Eight Poj 1077 ---Eight zoj 1217---Eight (八数码解法3)

点击打开链接uva 652 点击打开链接hdu 1043 点击打开链接zoj 1217                                                              八数码解法3 解题整体思路 :    双向广搜+哈希判重+输出路径                      (目前只能AC poj 数据水了不解释,其它的OJ一直TLE,求教)                               我们知道对于八数码问题而言,每一个状态就是每一个格

uva 652---Eight Poj 1077 ---Eight zoj 1217---Eight (八数码解法1)

点击打开链接uva 652 点击打开链接hdu 1043 点击打开链接zoj 1217                                                              八数码解法1 解题整体思路 :    单向广搜+哈希判重+输出路径(这种方法效率不高,目前小弟的程序只能过POJ 其它TLE)                               我们知道对于八数码问题而言,每一个状态就是每一个格子的编号(我们把空格看成9),那么最多有9!种,那么

基于用户投票的排名算法(三)Stack Overflow

上一篇文章,我介绍了Reddit的排名算法. 它的特点是,用户可以投赞成票,也可以投反对票.也就是说,除了时间因素以外,只要考虑两个变量就够了. 但是,还有一些特定用途的网站,必须考虑更多的因素.世界排名第一的程序员问答社区Stack Overflow,就是这样一个网站. 你在上面提出各种关于编程的问题,等待别人回答.访问者可以对你的问题进行投票(赞成票或反对票),表示这个问题是不是有价值. 一旦有人回答了你的问题,其他人也可以对这个回答投票(赞成票或反对票).

POJ 1077 Eight:八数码问题

题目链接: http://poj.org/problem?id=1077 题目类型: 隐式图搜索 原题: The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all pac

PHP has encountered a Stack overflow问题解决方法_php技巧

昨晚将一个disucz论坛进行转移后,发现打开的页面上回多一个PHP has encountered a Stack overflow 这个提示错误,进过翻译为"PHP遇到堆栈溢出".我就感觉奇怪了,新站没人访问的,怎么可能会溢出. 好吧去discuz官方论坛找找解决方法. 找到的第一解决方法,更新后台缓存,结果不行.接下来检查数据库配置文件,也没有错误.检查php权限也没有错误. discuz官网有人说是php版本太低了,个人对于这种人是比较反感的,这种说法比较扯淡.不用去验证了.

八数码问题及A*算法

一.八数码问题 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个空格,与空格相邻的棋子可以移到空格中.要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤. 所谓问题的一个状态就是棋子在棋盘上的一种摆法.棋子移动后,状态就会发生改变.解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态. 八数码问题一般使用搜索法来解. 搜索法有广度优先搜索法

独家 | 一探Stack Overflow工作搜索

大约在两年前,Stack Overflow上发生了一件大事:Stack Overflow发布了一个叫做Providence的新系统.这个系统可以得知访问者对什么样的技术有兴趣,也可以衡量某个访问者和某个工作之间的匹配程度. 更通俗的说,Providence的发布可以被看作是Stack Overflow向"更智能"迈进以及在数据科学领域上持续投资的道路上的里程碑.如果想了解更多关于Providence的信息,可以参考下面这个系列博客(https://kevinmontrose.com/2

在 Stack Overflow 远程办公是一种怎样的体验?

在Stack Overflow,我们经常会探讨为什么信任远程工作这种方式,而且结果显示,我们已经在远程工作方面取得了不错的成果.事实上,2016年我们针对各个公司开展的一项调查显示,有88%的远程工作人员反映自己高度.全面地参与到了公司的运作过程(就总体的员工参与调查率来看,我公司为85%,而行业内其他公司平均为71%).远程工作人员对于"工作与生活相互融合"以及"社会联系"等方面的正面评价,也远高于其他员工对这两方面调查的总体评价.  那么我们又是如何妥善落实远程