八数码难题(转)

 

问题描述:

3×3的棋盘上,摆着8个将牌,每个将牌都刻有18数码中的某个数码。棋盘中留有一个空格,允许其周围的某个将牌向空格移动,这样通过移动将牌就可以不断改变棋牌的布局。

请用计算机实现算法解决八数码问题:提供输入初始将牌布局和目标将牌布局的功能,在接收输入之后,输出移动的步骤(方式)。

 

 

 

/* * ===================================================================================== * * Filename: eightnum.c * * Description: 8数码问题(A算法) * * Version: 1.0 * Created: 2008-11-4 19:43:19 * Revision: none * Compiler: gcc * * Author: MneeHNXM (Mnee), [email protected] * Company: HeNan University * * ===================================================================================== */ #include #include typedef struct Node { int num[9]; //棋盘状态 int deepth; //派生的深度 g(n) int diffnum; //不在位的数目 h(n) int value; //耗散值 f(n)=g(n)+h(n) struct Node * pre; struct Node * next; struct Node * parent; }numNode; /* ---------- end of struct numNode ---------- */ int origin[9]; //棋盘初始状态 int target[9]; //棋盘目标状态 int numNode_num,total_step; numNode *open,*close; //Open表和Close表 numNode *create_numNode() { return (numNode *)malloc(sizeof(numNode)); } numNode *open_getfirst(numNode *head); //返回第一项,并从Open表中删除 void open_insert(numNode *head,numNode *item); //向Open表中按序插入新节点 void close_append(numNode *head,numNode *item); //向Close表中插入新节点 int expand(numNode *item); //扩展节点 int print_result(numNode *item); //打印结果 numNode *copy_numNode(numNode *orgin); char isNewNode(numNode *open,numNode *close,int num[9]); //是否在Open表或Close表中 void print_num(int num[9]); //打印棋盘状态 int diff(int num[9]); //求不在位棋子的个数 void init(); //初始化,获得棋盘初始状态和目标状态 void swap(int *a,int *b); int operate(int num[],int op); void free_list(numNode *head); /* * === FUNCTION ====================================================================== * Name: 主函數 * Description: 程序入口 * ===================================================================================== */ int main ( int argc, char *argv[] ) { //初始化Open表和Close表 open=create_numNode(); close=create_numNode(); open->pre=open->next=close->pre=close->next=NULL; init(); //由用户输入初始和目标状态 //初始化初始节点 numNode *p1; p1=create_numNode(); p1->parent=NULL; p1->deepth=0; int i=0; for ( i=0; i<9; i++) { p1->num[i]=origin[i]; } open_insert(open,p1); numNode_num=1; p1=open_getfirst(open); while (p1!=NULL) { close_append(close,p1); if(expand(p1)) return EXIT_SUCCESS; p1=open_getfirst(open); } printf("No solution!/n"); return EXIT_SUCCESS; } /* ---------- end of function main ---------- */ void init ( ) { while(1) { printf("Please input opriginal status:/nFor example:123456780 stands for/n" "1 2 3/n" "4 5 6/n" "7 8 0/n"); char temp[10]; scanf("%s",&temp); int i=0; for ( i=0;i<9 && temp[i]-'0'>=0 && temp[i]-'0'<=8; i++) { origin[i]=temp[i]-'0'; } printf("Please input target status:/n"); scanf("%s",&temp); int j=0; for ( j=0; j<9 && temp[j]-'0'>=0 && temp[j]-'0'<=8; j++) { target[j]=temp[j]-'0'; } system("cls"); if ( i==9&&j==9) { break; } } } /* ----- end of function init ----- */ void open_insert (numNode *head,numNode *item) { numNode *p,*q; p=head->next; q=head; while ( p!=NULL && item->value > p->value ) { q=p; p=p->next; } q->next=item; item->pre=q; item->next=p; if(p!=NULL) { p->pre=item; } } /* ----- end of function open_insert ----- */ numNode * open_getfirst (numNode *head) { numNode *p; if ( head->next == NULL ) { return NULL; } p=head->next; head->next=p->next; if ( p->next != NULL ) { p->next->pre=head; } p->pre=NULL; p->next=NULL; return p; } /* ----- end of function open_getfirst ----- */ void close_append (numNode *head,numNode *item) { item->next=head->next; item->pre=head; head->next=item; if ( item->next!=NULL ) { item->next->pre=item; } } /* ----- end of function close_append ----- */ int expand (numNode *p1) { numNode * p2; int op=1; for ( op=1; op<=4; op++) { p2=copy_numNode(p1); operate(p2->num,op); if(isNewNode(open,close,p2->num)=='N') { p2->parent=p1; p2->deepth=p1->deepth+1; p2->diffnum=diff(p2->num); p2->value=p2->deepth+p2->diffnum; if(p2->diffnum==0) { total_step=print_result(p2); printf("Total step: %d/n",total_step); free_list(open); free_list(close); return 1; } else { numNode_num++; open_insert(open,p2); } } else free(p2); } return 0; } /* ----- end of function expand ----- */ int operate(int m[], int op) { int blank; blank=0; while (m[blank]!=0 && blank<9 ) ++blank; if (blank==9) return 1; switch (op) { case 1: /* up */ if (blank>2) swap(m+blank,m+blank-3); break; case 2: /* down */ if (blank<6) swap(m+blank,m+blank+3); break; case 3: /* left */ if (blank!=0 && blank!=3 && blank!=6) swap(m+blank,m+blank-1); break; case 4: /* right */ if (blank!=2 && blank!=5 && blank!=8) swap(m+blank,m+blank+1); break; default : return 1; } return 0; } void swap(int *a, int *b) { int c; c=*a; *a=*b; *b=c; } numNode * copy_numNode (numNode *origin) { numNode *p; p=create_numNode(); p->deepth=origin->deepth; p->diffnum=origin->diffnum; p->value=origin->value; int i; for ( i=0; i<9; i++) { (p->num)[i]=(origin->num)[i]; } return p; } /* ----- end of function copy_numNode ----- */ int diff (int num[9]) { int i,diffnum=0; for(i=0;i<9;i++) if(num[i]!=target[i]) diffnum++; return diffnum; } /* ----- end of function diff ----- */ char isNewNode (numNode *open,numNode *close,int num[9]) { numNode *p; int i=0; p=open->next; while ( p!=NULL ) { for ( i=0; i<9; i++) { if(p->num[i]!=num[i]) break; } if(i==9) return 'O'; //Open p=p->next; } p=close->next; while ( p!=NULL ) { for ( i=0; i<9; i++) { if(p->num[i]!=num[i]) break; } if(i==9) return 'C'; //Close p=p->next; } return 'N'; } /* ----- end of function isNewNode ----- */ void free_list (numNode *head) { numNode *p,*q; p=head->next; while ( p!=NULL ) { q=p->next; free(p); p=q; } free(head); } /* ----- end of function free_list ----- */ void print_num (int num[9]) { int i; for ( i=0; i<9; i++) { printf("%d/t",num[i]); if((i%3)==2) printf("/n"); } } /* ----- end of function print_num ----- */ int print_result ( numNode *item) { numNode *p; int step; p=item; if(p!=NULL) { step=print_result(p->parent); printf("/nStep %d:/n",step+1); print_num(p->num); return step+1; } else { return -1; } } /* ----- end of function print_result ----- */ 

你可能感兴趣的:(function,null,insert,struct,list,compiler)