人工智能第一次实验\八数码问题、八数码问题(人工智能实验)
迭代深入A*搜索(IDA*)、递归最佳优先搜索RBFS解八数码问题、人工智能实验)
#include
#include
#include
#include
#define IN1 0x7FFFFFFF
/*************************************************************************************************/
enum Actions{u,d,l,r,nop}; //动作:上、下、左、右、无
typedef struct jiegou{ //表示问题的状态
int p[9];
struct jiegou * next;
struct jiegou * prev;
Actions act; //前驱到达本状态的动作
int num_of_step;
int shiying; //适应函数值
}zhuangtai;
/*************************************************************************************************/
/*************************************************************************************************/
int haosan(int p[],int n){ //耗散函数
int k;
k=n;
int goal[9]={1,4,7,2,5,8,3,6,0};
for(int i=0;i<8;i++){
int j;
for(j=0;j<9&&p[j]!=goal[i];j++);
if(j%3>i%3)k=k+(j%3-i%3)*2;
else k=k+(i%3-j%3)*2;
if(j/3>i/3)k=k+(j/3-i/3)*2;
else k=k+(i/3-j/3)*2;
}
return k;
}
/*************************************************************************************************/
/*************************************************************************************************/
zhuangtai * jianztai(int temp[9],int n,Actions a,zhuangtai * n_=NULL,zhuangtai * p_=NULL){//创建新状态结点
zhuangtai *s=new zhuangtai;
s->num_of_step=n;
s->act=a;
s->next=n_;
s->prev=p_;
for(int i=0;i<9;i++)
s->p[i]=temp[i];
s->shiying=haosan(s->p,s->num_of_step);
return s;
}
/*************************************************************************************************/
/*************************************************************************************************/
int * randep(int d){ //随机的初始状态产生器
int *p=new int[9];
int i,j,k,t;
for(i=0;i<3;i++){
for(j=0;j<3;j++)
p[i+j*3]=i*3+j+1;
}
p[8]=0;
j=8;
int *xubo2=new int[d];
srand((unsigned)time(NULL));
for(i=0;i5){i--;continue; } //若遇到边界,则再次产生随机数;
else k=j+3;break;
default:break;
}
t=p[j];p[j]=p[k];p[k]=t;
j=k;
}
return p;
}
/*************************************************************************************************/
/*************************************************************************************************/
int * move_up(int p[]){
int i,t;
int *temp=new int[9];
for(i=0;i<9;i++)
temp[i]=p[i];
for(i=0;temp[i]>0;i++);
if(i%3!=0){
t=temp[i];
temp[i]=temp[i-1];
temp[i-1]=t;
return temp;
}
delete temp;return NULL;
}
/*************************************************************************************************/
/*************************************************************************************************/
int * move_down(int p[]){
int i,t;
int *temp=new int[9];
for(i=0;i<9;i++)
temp[i]=p[i];
for(i=0;temp[i]>0;i++);
if((i-2)%3!=0){
t=temp[i];
temp[i]=temp[i+1];
temp[i+1]=t;
return temp;
}
delete temp;return NULL;
}
/*************************************************************************************************/
/*************************************************************************************************/
int * move_left(int p[]){
int i,t;
int *temp=new int[9];
for(i=0;i<9;i++)
temp[i]=p[i];
for(i=0;temp[i]>0;i++);
if(i>2){
t=temp[i];
temp[i]=temp[i-3];
temp[i-3]=t;
return temp;
}
delete temp;return NULL;
}
/*************************************************************************************************/
/*************************************************************************************************/
int * move_right(int p[]){
int i,t;
int *temp=new int[9];
for(i=0;i<9;i++)
temp[i]=p[i];
for(i=0;temp[i]>0;i++);
if(i<6){
t=temp[i];
temp[i]=temp[i+3];
temp[i+3]=t;
return temp;
}
delete temp;return NULL;
}
/*************************************************************************************************/
/*************************************************************************************************/
void input8(int p[]){ //打印八数码。
//printf("\n");
for(int i=0;i<3;i++){
for( int j=0;j<9;j+=3){
if(p[i+j]>0)
printf("%d ",p[i+j]);
else printf(" "); //当为零时输出空格“ ”。
}
printf("\n");
}
}
/*************************************************************************************************/
/*************************************************************************************************/
char * idas(int init[],int &g){
zhuangtai *xubo=jianztai(init,0,nop);
int i,k;
int num1,num2;
zhuangtai * l1,*s,*t;
num1=xubo->shiying;
while(num1p,0,u);
while(l1!=NULL)
{
s=l1;
if(s->num_of_step>30)
return NULL;
k=s->shiying;
l1=l1->next;
if( k>num1){
if(knum_of_step)
{
char *jiejue=new char[s->num_of_step];
jiejue[0]=0;
g=k;
t=s;
for(i=g-1;i>=0;i--)
{
switch(t->act)
{
case u:jiejue[i]='u';break;
case d:jiejue[i]='d';break;
case l:jiejue[i]='l';break;
case r:jiejue[i]='r';break;
default:break;
}
t=t->prev;
}
return jiejue;
}
else{
int * t;
if( s->act!=d && (t=move_up(s->p))!=NULL)
l1=jianztai(t,s->num_of_step+1 ,u,l1,s);
if( s->act!=u && (t=move_down(s->p))!=NULL)
l1=jianztai(t,s->num_of_step+1 ,d,l1,s);
;
if( s->act!=r && (t=move_left(s->p))!=NULL)
l1=jianztai(t,s->num_of_step+1 ,l,l1,s);
;
if( s->act!=l && (t=move_right(s->p))!=NULL)
l1=jianztai(t,s->num_of_step+1 ,r,l1,s);
}
}
}
num1=num2;
}
return NULL;
}
/*************************************************************************************************/
/*************************************************************************************************/
zhuangtai * rbfs_r(zhuangtai * st,int f_limit,int &fbest){
if(haosan(st->p,st->num_of_step)==st->num_of_step)return st;
zhuangtai * successor=NULL,*s,*best,*result;
int alter;
//expand successors
int * t;
if( st->act!=d && (t=move_up(st->p))!=NULL)
successor=jianztai(t,st->num_of_step+1 ,u,successor,st);
if( st->act!=u && (t=move_down(st->p))!=NULL)
successor=jianztai(t,st->num_of_step+1 ,d,successor,st);
if( st->act!=r && (t=move_left(st->p))!=NULL)
successor=jianztai(t,st->num_of_step+1 ,l,successor,st);
if( st->act!=l && (t=move_right(st->p))!=NULL)
successor=jianztai(t,st->num_of_step+1 ,r,successor,st);
for(s=successor;s!=NULL;s=s->next){
if(s->shiyingshiying)
s->shiying=st->shiying;
}
while(1){
best=successor;
for(s=successor;s!=NULL;s=s->next){
if(s->shiyingshiying)
best=s;
}
if(best->shiying>f_limit){fbest=best->shiying;return NULL;}
alter=IN1;
for(s=successor;s!=NULL;s=s->next){
if(s==best)continue;
else if(s->shiying < alter)
alter=s->shiying;
}
result=rbfs_r(best, (f_limitshiying);
if(result!=NULL)return result;
}
}
/*************************************************************************************************/
/*************************************************************************************************/
char * rbfs(int init[],int &g){ //递归RBFS算法
zhuangtai *xubo=xubo=jianztai(init,0,nop);
zhuangtai *final=rbfs_r(jianztai(xubo->p,0,nop),IN1,xubo->shiying);
zhuangtai *t;
char *jiejue=new char[final->num_of_step];
jiejue[0]=0;
t=final;g=final->num_of_step;
for(int i=g-1;i>=0;i--)
{
switch(t->act)
{
case u:jiejue[i]='u';break;
case d:jiejue[i]='d';break;
case l:jiejue[i]='l';break;
case r:jiejue[i]='r';break;
default:break;
}
t=t->prev;
}
return jiejue;
}
/*************************************************************************************************/
/*************************************************************************************************/
int main(int argc, _TCHAR* argv[])
{
char * jiejue;
zhuangtai * xubo;
int i,g,m;
LARGE_INTEGER lv,lv1,lv2;
double secondsPerTick;
QueryPerformanceFrequency( &lv );
secondsPerTick = 1000000.0/ lv.QuadPart;
while(1){
printf("*************************************************************************");
printf("\n请输入的初始状态产生器移动步数d(1-3000000):\n");
scanf("%d",&g);
if(g<=0){ //限制输入输出的大小1-3000000整数
printf("输入错误!\n");continue;
}
else if(g>3000000){
printf("数值太大,无法解决!抱歉!\n");continue;
}
xubo=jianztai(randep(g),0,nop);
printf("*******************\n");
printf("八数码初始状态:\n");
input8(xubo->p);
printf("*******************\n");
printf("\n***********************************");
printf("\n操作:\n1.迭代深入A*搜索求解 IDA*;\n2.递归最佳优先搜索求解 RBFS;\n3.两者同时.\n0.跳出");
printf("\n***********************************\n请输入操作对应的数字:");
scanf("%d",&m);
if(m<0|m>=4){ //限制输入输出的大小0-3整数
printf("输入错误!请重新输入!\n");continue;
}
while(m<4){
if(m==3)m=-1;
QueryPerformanceCounter( &lv1 );
if(m==1||m==-1)
jiejue=idas(xubo->p,g);
else if(m==2||m==-2)
jiejue=rbfs(xubo->p,g);
else if(m==0)
break;
else break;
QueryPerformanceCounter( &lv2 );
if(jiejue==NULL){
printf("Failed\n");
system("pause");
break;;
}
if(m==1||m==-1){printf("\n***********************************");printf("\n迭代深入A*搜索(IDA*)解得:");}
if(m==2||m==-2){printf("***********************************");printf("\n递归最佳优先搜索RBFS解得:");}
printf("\n运行结果:");
printf("共移动%d步\n",g);
printf("运行时间:%f us\n",secondsPerTick * (lv2.QuadPart-lv1.QuadPart));
printf("移动路径:");
for(i=0;i