`
Kingson_Wu
  • 浏览: 123560 次
文章分类
社区版块
存档分类
最新评论

八数码问题

 
阅读更多

使用了A*算法


#include <stdio.h>

#include <stdlib.h>
#define TIME 50 //限定只搜索前50步,50步以后如果仍然没有搜索到结果,认为无解。
#define MAXSIZE 200
int n=1;
int* level=new int[10];//用来标志扫描的树的扩展次数
int* path=new int[10];//用来记录最佳路径
int pathLength=0;//用来记录最佳路径大小
int current,p=0;//回溯时用到的辅助变量


int k=0;
int result[9]={1,2,3,8,0,4,7,6,5};//所要达到的最终状态,0代表空格。
typedef struct{
int num[9];
char expension; //记录是否可以扩展,Y代表可以扩展,N代表不可以。
char banOperate; //表示不可以执行的操作,'L'代表不能左移,'R'代表不能右移,
//'U'代表不能上移,'D'代表不能下移,'C'代表可以任意移动。
int father; //记录父节点的下标。
}Node;
Node store[MAXSIZE]; //将搜索过的状态存储于该数组中。


int same(int temp) //判断是否达到了目标状态。
{
for(int j=0;j<9;j++)
if(store[temp].num[j]!=result[j])
return 0;
return 1;
}




//---------------------------------------------------------A*算法------------------------------------------------------------------------

int index(int now ,int des){//两个位置相差的步数


int dif=abs(now-des);

if(dif==3){

return 1;

}
else if(dif==6||dif==2){
return 2;
}else if(dif==4){

if(now==3||now==7)
{


return 4;
}
else {return 2;}

}else if(dif==1){

if(now+des==5||now+des==11)

return 3;

else {
return 1;
}
}else if(dif==5)
{
return 3;
}else if(dif==7){
return 3;
}else if(dif==8)
{
return 4;
}



return 0;




}






int guess(int temp)//计算该状态的估价函数
{
int now;
int des;
int value=0;
for(int j=0;j<9;j++)
if(store[temp].num[j]!=result[j])
{
if(store[temp].num[j]==0)
continue;
now=j;
for(int i=0;i<9;i++){

if(store[temp].num[j]==result[i])
{des=i;
break;

}



}

value+=index(now,des);

}
return value;






}



//----------------------------------------------------------------------------




void cut(int m,int count){//根据估价函数剪枝
int min;
m-=count;
int temp;



int* gue=new int[count];


gue[0]=min=temp=guess(m);




for(int j=1;j<count;j++)
{
gue[j]=temp=guess(++m);

if(min>temp)
min=temp;
}
m-=count;
m++;

for(int j=0;j<count;j++)

{
if(gue[j]!=min)
{

store[m+j].expension='N';
//printf("dsfs");
}
}


}


















































void printResult() //输出搜索结果。
{
int count=1;
int r=0;

printf("从顶点开始第1次扩展---------------------------\n");
for(int j=1;j<=n;j++)
{


printf("第%d步搜索后:\n",j);
printf("\t%d\t%d\t%d\n",store[j].num[0],store[j].num[1],store[j].num[2]);
printf("\t%d\t%d\t%d\n",store[j].num[3],store[j].num[4],store[j].num[5]);
printf("\t%d\t%d\t%d\n",store[j].num[6],store[j].num[7],store[j].num[8]);
printf("\n\n");
if(j+1==level[r])
{
r++;
count++;
printf("第%d次扩展---------------------------------\n",count);
printf("\n");
}

}


printf("以下输出最佳路径及其大小---------------------------\n");




current= n;
path[0]=current;

p=1;
while(1){
if(store[current].father==-1)
break;


path[p]=store[current].father;
current=path[p];
p++;

}
pathLength=p-1;


for(int j=p-1;j>=0;j--){
printf("第%d步-------------------------------\n",p-j-1);
printf("\t%d\t%d\t%d\n",store[path[j]].num[0],store[path[j]].num[1],store[path[j]].num[2]);
printf("\t%d\t%d\t%d\n",store[path[j]].num[3],store[path[j]].num[4],store[path[j]].num[5]);
printf("\t%d\t%d\t%d\n",store[path[j]].num[6],store[path[j]].num[7],store[path[j]].num[8]);
printf("\n\n");


}
printf("最佳路径长度为:%d\n",pathLength);


}




int left(int temp) //将空格进行左移操作。
{
int j;
for(j=0;j<9;j++) //判断空格的位置。
if(store[temp].num[j]==0)
break;
if(j==0||j==3||j==6)
return 0;
for(int k=0;k<9;k++)
store[n].num[k]=store[temp].num[k];
int tempNum=store[n].num[j-1]; //将移动后的状态赋给store[n]
store[n].num[j-1]=0;
store[n].num[j]=tempNum;
store[temp].expension='N';
store[n].banOperate='R';
store[n].expension='Y';
store[n].father=temp;
if(same(n)) //判断store[n]是否为最终想得到的状态。
{
printResult();
exit(1);
}
n++;
return 1;
}


int right(int temp) //将空格进行右移操作。
{int j;
for(j=0;j<9;j++)
if(store[temp].num[j]==0)
break;
if(j==2||j==5||j==8)
return 0;
for(int k=0;k<9;k++)
store[n].num[k]=store[temp].num[k];
int tempNum=store[n].num[j+1];
store[n].num[j+1]=0;
store[n].num[j]=tempNum;
store[temp].expension='N';
store[n].banOperate='L';
store[n].expension='Y';
store[n].father=temp;
if(same(n))
{
printResult();
exit(1);
}
n++;
return 1;
}


int up(int temp) //将空格进行上移操作。
{int j;
for(j=0;j<9;j++)
if(store[temp].num[j]==0)
break;
if(j==0||j==1||j==2)
return 0;
for(int k=0;k<9;k++)
store[n].num[k]=store[temp].num[k];
int tempNum=store[n].num[j-3];
store[n].num[j-3]=0;
store[n].num[j]=tempNum;
store[temp].expension='N';
store[n].banOperate='D';
store[n].expension='Y';
store[n].father=temp;
if(same(n))
{
printResult();
exit(1);
}
n++;
return 1;
}


int down(int temp) //将空格进行下移操作。
{
int j;
for(j=0;j<9;j++)
if(store[temp].num[j]==0)
break;
if(j==6||j==7||j==8)
return 0;
for(int k=0;k<9;k++)
store[n].num[k]=store[temp].num[k];
int tempNum=store[n].num[j+3];
store[n].num[j+3]=0;
store[n].num[j]=tempNum;
store[temp].expension='N';
store[n].banOperate='U';
store[n].expension='Y';
store[n].father=temp;
if(same(n))
{
printResult();
exit(1);
}
n++;
return 1;
}


void init()
{
Node start;
printf("请输入初始状态,用空格分开,0代表空格:\n");//输入初始的状态。
for(int i=0;i<9;i++)
scanf("%d",&start.num[i]);
for(int k=0;k<9;k++)
if(start.num[k]==0)
break;
start.banOperate='C';
start.expension='Y';
start.father=-1;
store[0]=start; //将初始状态赋于store[0]。
}
int main(){
init();


if(same(0))
{
printf("没有必要进行搜索,初始状态即为最终状态!");
exit(1);
}


for(int i=0;i<TIME;i++) //开始进行宽度搜索,限定搜索上限为50步。
{
if(store[i].expension=='Y')
{
if(store[i].banOperate=='L')
{
up(i);
right(i);
down(i);


cut(n,3);
level[k++]=n;



}
if(store[i].banOperate=='R')
{
left(i);
up(i);
down(i);


cut(n,3);
level[k++]=n;
}
if(store[i].banOperate=='U')
{
left(i);
right(i);
down(i);


cut(n,3);
level[k++]=n;
}
if(store[i].banOperate=='D')
{
left(i);
up(i);
right(i);


cut(n,3);
level[k++]=n;
}
if(store[i].banOperate=='C')
{
left(i);
up(i);
right(i);
down(i);



cut(n,4);
level[k++]=n;
}
}
if(n>=TIME) //50步以后仍然没有达到所要求的状态,认为无解。
{
n--;
printResult();
printf("Sorry,在所在搜索范围内没有搜索到结果!");
exit(1);
}
}



return 0;
}
分享到:
评论

相关推荐

    C语言解决八数码问题

    **八数码问题** 八数码问题(也称滑动拼图或15拼图)是一个经典的逻辑谜题,玩家需要通过移动空格处的方块,将初始排列的数字方块按照特定顺序排列好。在这个问题中,我们通常有一个2x3的网格,上面有1到15的数字和...

    八数码问题C语言代码

    "八数码问题C语言代码" 该代码是使用 C 语言实现的八数码问题解决方案。八数码问题是一种经典的人工智能问题,目的是将一组初始状态的棋盘通过有限步骤变换为目标状态的棋盘。该代码使用了广度优先搜索算法来解决八...

    MATLAB八数码问题

    《MATLAB实现A*算法解决八数码问题》 在人工智能领域,解决复杂问题的方法多种多样,其中搜索算法占据着重要地位。八数码问题(又称滑动拼图游戏)就是一个经典的搜索问题实例,它考验了算法的效率和智能程度。本文...

    宽度优先算法解决八数码问题实验报告.zip

    在这个实验报告中,它被应用于解决著名的八数码问题,也称为滑动拼图游戏。 八数码问题是一个典型的状态空间搜索问题,玩家需要通过移动一个空格与其他数字进行交换,将初始布局调整到目标布局。游戏的目标通常是将...

    通过广度优先遍历解决八数码问题

    通过广度优先遍历解决八数码问题 在计算机科学和人工智能领域中,对于搜索问题的解决方法有很多,广度优先遍历(Breadth-First Search,BFS)是一种常用的方法。八数码问题(Eight Puzzle)是一种经典的搜索问题,...

    八数码问题_C八数码问题_

    数码问题也称为九宫问题。在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。...解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态。

    八数码问题解决C语言源代码

    八数码问题,又称滑动拼图游戏,是一个经典的计算机科学问题,主要研究如何通过最少的移动次数将一个打乱的拼图恢复到预设的目标状态。在这个问题中,通常使用一个3x3的网格,包含8个数字方块和一个空格。目标是通过...

    启发式函数解决八数码问题

    启发式函数解决八数码问题 启发式函数解决八数码问题是人工智能领域中的一个经典问题,八数码问题是指在 3*3 九宫格棋盘上,摆有 8 个将牌,每一个将牌都刻有 1-8 数码中的某一个数码。棋盘中留有一个空格,允许其...

    C语言实现:八数码问题的深度优先搜索、广度优先搜索、过程表示(全)

    ①使用深度优先搜索来解决八数码问题 ②使用广度优先搜索来解决八数码问题 ③使用过程式表示和实现八数码问题 以及相关代码详细注释 过程式知识表示是将有关某一问题领域的知识, 连同如何使用这些知识的方法,均...

    人工智能--八数码问题

    **八数码问题(Eight Puzzle Problem)** 八数码问题是一个经典的逻辑谜题,源自19世纪的智力游戏“十五拼图”。在这个游戏中,我们有一个3x3的网格,其中8个格子内填充了数字1到8,还有一个空格。目标是通过在相邻...

    湘潭大学人工智能实验 状态空间法求解八数码问题

    湘潭大学人工智能实验状态空间法求解八数码问题 本文档包含湘潭大学人工智能课程实验之实验一:采用状态空间法求解八数码问题的详细内容。实验的主要目的是熟悉人工智能系统中的问题求解过程、状态空间的盲目搜索...

    八数码问题A*算法代码

    《八数码问题与A*算法实现详解》 八数码问题,又称滑动拼图或15拼图,是一个经典的计算机科学问题,属于图灵完全问题的范畴。它涉及到在一个3x3的网格上,通过空格与其他数字进行交换,使得初始布局最终转变为预设...

    八数码问题程序实现 java实现

    ### 八数码问题Java程序实现解析 #### 一、八数码问题概述 八数码问题(也称为8拼图问题)是一种经典的搜索问题,在人工智能领域中常用来作为算法研究的例子。该问题在一个3×3的棋盘上进行,棋盘上有8个数字块(1...

    A*算法解决八数码问题(C++)

    A*算法是路径搜索领域中一种非常高效的启发式搜索算法,它在解决八数码问题时表现出色。八数码问题,又称滑动拼图游戏,是一个经典的计算机科学问题,玩家需要通过移动空格来重新排列一组数字,使得它们最终形成一个...

    八数码问题解的存在性证明

    《八数码问题解的存在性证明》 八数码问题,又称滑动拼图,是一个经典的计算机科学和数学问题,涉及到在3x3的网格中通过移动数字来达成预设的目标状态。然而,并非所有初始配置都能转化为目标状态。本文将探讨八...

    A* (A STAR)算法解决八数码问题

    A* 算法解决八数码问题 A* 算法是一种启发式搜索算法,常用于解决复杂的问题。八数码问题是经典的搜索问题,目的是从初始状态到达目标状态,通过交换空格和数字达到目标状态。A* 算法可以高效地解决八数码问题。 A...

    八数码问题数据结构实现

    【八数码问题】,又称滑动拼图游戏,是一个经典的逻辑谜题,通过移动数字方块至目标布局来解决。本问题的实现涉及到三种搜索策略:回溯、图搜索和启发式算法。 **回溯策略**是基于深度优先搜索的算法,它采用递归的...

    八数码问题实验报告1

    【八数码问题实验报告1】 本实验主要涉及的是在人工智能领域中的一种经典问题——八数码问题,使用C++编程语言实现A*算法进行求解。A*算法是一种启发式搜索算法,它结合了实际走过的代价(g(n))和预估到目标的代价...

    人工智能 八数码问题 A*算法 C语言

    八数码问题,又称滑动拼图游戏,是人工智能中经典的搜索问题之一,用于教授和理解状态空间搜索算法。本实验重点探讨了如何用C语言实现A*算法来解决八数码问题。 A*算法是一种启发式搜索算法,由人工智能先驱Peter ...

Global site tag (gtag.js) - Google Analytics