最近人工智能基础老师让我们用宽度优先搜索来实现八数码难题,所以就用了自己所学不多的C语言进行了编写。
代码如下:
#include<stdio.h>
#include<string.h>
/*代码说明*/
/*8 puzzle problem*/
/*要输入可行解 否则会出现无解的情况*/
char start[10]={'2','8','3',//起始状态
'1',' ','4',
'7','6','5'};
char end[10]={'1','2','3',//目标状态
'8',' ','4',
'7','6','5'};
char store[500][10];//用于存储状态的数组
int step;//步数
int location;//白框' '在start数组中的位置
int total_num=0;//状态总数
int next_num=0;//下一级的状态个数
int chess_x;//将start数组中白框' '的位置转换为3*3棋盘中的坐标
int chess_y;
int dx[4]={0,1,0,-1};//白框' '移动
int dy[4]={1,0,-1,0};
int compare_state()
{
for(int i=0;i<total_num;i++)
{
if(strcmp(store[i],start)==0) return 0;//与状态库中的状态比较 若有相同的则返回0
}
return 1;//若没有相同的则返回1
}
int main()
{
int mid_vaule;//中间变量
int fake_total_num=1;//用于循环
int fake_next_num=1;//用于循环
strcpy(store[total_num],start);//将初始状态存储到状态库中
total_num++;
if(strcmp(start,end)==0)//比较初始状态和目标状态是否相等
{
printf("最短步数为: %d\r\n",step);
return 0;
}
while(1)
{
for(int j=fake_total_num-fake_next_num;j<fake_total_num;j++)
{
strcpy(start,store[j]);//将下一级的状态从状态库中提取出来存放到start数组中
for(int i=0;i<9;i++)//寻找' '位置
{
if(start[i]==' ')
{
location = i;
break;
}
}
chess_x = location/3;//将白框' '位置装换到3*3棋盘坐标中
chess_y = location%3;
for(int i=0;i<4;i++)//让白框' '移动
{
chess_x+=dx[i];
chess_y+=dy[i];
if(chess_x<0 || chess_x>=3 || chess_y<0 || chess_y>=3)//白框' '超出棋盘则continue
{
chess_x-=dx[i];
chess_y-=dy[i];
continue;
}
mid_vaule = start[chess_x*3+chess_y]; //将变换后的位置中的内容和原位置中的内容互换
start[chess_x*3+chess_y] = start[location];
start[location] = mid_vaule;
if(compare_state())//比较此时状态是否存在与状态库中
{
strcat(store[total_num],start);//如果不存在则将此次状态存储在状态库中
printf("此时状态: %s 总的状态数:%d\r\n",start,total_num);
total_num++;//总状态加一
next_num++;//下一级状态加一
if(total_num>=500)//如果白框' '移动步数太多 则认为无解
{
printf("此问题无解\r\n");
return 0;
}
}
else//如果状态库中存在此时状态 则将内容和坐标都变换回去 然后continue
{
mid_vaule = start[chess_x*3+chess_y];
start[chess_x*3+chess_y] = start[location];
start[location] = mid_vaule;
chess_x-=dx[i];
chess_y-=dy[i];
continue;
}
if(strcmp(start,end)==0)//比较此时状态和目标状态是否相等
{
step++;
printf("最短步数为: %d\r\n",step);
return 0;
}
mid_vaule = start[chess_x*3+chess_y]; //内容变换回去
start[chess_x*3+chess_y] = start[location];
start[location] = mid_vaule;
chess_x-=dx[i];//坐标变换回去
chess_y-=dy[i];
}
}
fake_total_num=total_num;//将总的状态数赋值 用于循环
fake_next_num = next_num;//将下一次状态数赋值 用于循环
next_num = 0;//清零
step++;//步数加一
}
return 0;
}
//作者:Black_Cat
第一次发帖,有什么问题望指正。