八数码问题高效算法(人工智能实验)

人工智能第一次实验\八数码问题、八数码问题(人工智能实验)

迭代深入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


 

你可能感兴趣的:(C语言,课程,高效算法,C语言,八数码问题高效算法人工智能实验)