diff --git a/A8code - 副本.c b/A8code - 副本.c new file mode 100644 index 0000000..2a4699b --- /dev/null +++ b/A8code - 副本.c @@ -0,0 +1,271 @@ +#include +#include +#include +#include + +#define N 3 // ¶¨ÒåƴͼµÄά¶È£¬ÕâÊÇÒ»¸ö3x3µÄƴͼ + +typedef struct Node { + int puzzle[N][N]; // ´æ´¢Æ´Í¼×´Ì¬µÄÊý×é + struct Node* parent; // Ö¸Ïò¸¸½ÚµãµÄÖ¸Õ룬ÓÃÓÚ×·×Ù·¾¶ + int f, g, h; // A*Ëã·¨ÖÐµÄ f, g, h Öµ +} Node; + +// ´´½¨ÐµÄƴͼ½Úµã +Node* createNode(int puzzle[N][N]) +{ + Node* newnode= (Node*)malloc(sizeof(Node)); + //ÇëʵÏָú¯Êý + int i,j; + for(i=0;ipuzzle[i][j]=puzzle[i][j]; + newnode->parent=NULL; + newnode->f=0; + newnode->g=0; + newnode->h=0; + return newnode; +} + +// ¼ì²éÁ½¸öƴͼ״̬ÊÇ·ñÏàͬ +bool isSamePuzzle(int a[N][N], int b[N][N]) { + //ÏàͬÔò·µ»Øtrue,·ñÔò·µ»Øfalse + int i,j; + int k=1; + for(i=0;ipuzzle[i][j]!=goal->puzzle[i][j]) + h++; + } + } + return h; + +} + +// Òƶ¯²Ù×÷£¬Éú³ÉеÄƴͼ״̬ +Node* move(Node* current, int dir) +{ + int key_x, key_y; + //¼Ç¼¿Õ°×¿éµÄλÖà + // ÕÒµ½¿Õ°×¿éµÄλÖà + int i,j; + for(i=0;ipuzzle[i][j]=0) + { + key_x=i; + key_y=j; + break; + } + } + //¸ønew_x¡¢new_y¸³Öµ + int new_x,new_y; + new_x=key_x; + new_y=key_y; + // ¸ù¾ÝÒƶ¯·½Ïò¸üÐÂпéµÄλÖã¬ÉÏÏÂ×óÓÒÒƶ¯ + if(dir==0) + new_y--; + else if(dir==1) + new_y++; + else if(dir==2) + new_x--; + else if(dir=3) + new_x++; + // ¼ì²éÐÂλÖÃÊÇ·ñÔڱ߽çÄÚ + if(new_x<0||new_y<0||new_x>N||new_y>N) + return NULL; + // ´´½¨Ð½ڵ㣬¸´ÖƵ±Ç°Æ´Í¼×´Ì¬£¬²¢½»»»¿éµÄλÖà + Node* new_node = createNode(current->puzzle); + new_node->puzzle[key_x][key_y] = current->puzzle[new_x][new_y]; + new_node->puzzle[new_x][new_y] = 0; + return new_node; +} + +// A*Ëã·¨£¬Ñ°ÕÒ×î¶Ì·¾¶ +Node* AStar(Node* start, Node* goal) { + Node* OPEN[1000]; // ¿ª·ÅÁÐ±í£¬ÓÃÓÚ´æ´¢´ý̽Ë÷µÄ½Úµã + Node* CLOSED[1000]; // ¹Ø±ÕÁÐ±í£¬ÓÃÓÚ´æ´¢ÒÑ̽Ë÷µÄ½Úµã + int OPEN_SIZE = 0; // ¿ª·ÅÁбíµÄ´óС + int CLOSED_SIZE = 0; // ¹Ø±ÕÁбíµÄ´óС + int i,j,dir; + + + OPEN[0] = start; // ½«Æðʼ½ÚµãÌí¼Óµ½¿ª·ÅÁбí + OPEN_SIZE = 1; // ¿ª·ÅÁбíµÄ´óСÉèÖÃΪ1 + CLOSED_SIZE = 0; // ¹Ø±ÕÁбíµÄ´óСÉèÖÃΪ0 + + while (OPEN_SIZE > 0) {//¶ÔopenÁбí½øÐвÙ×÷ + int min_f = OPEN[0]->f;//³õʼ»¯×îСµÄf + int min_index = 0; + // ²éÕÒ¿ª·ÅÁбíÖоßÓÐ×îСfÖµµÄ½Úµã + for(i=1;iff; + min_index=i; + } + } + + Node* current = OPEN[min_index]; // »ñÈ¡¾ßÓÐ×îСfÖµµÄ½Úµã + + // Èç¹ûµ±Ç°½ÚµãÓëÄ¿±ê״̬ƥÅ䣬±íʾÕÒµ½½â + if(isSamePuzzle(current->puzzle,goal->puzzle)==true) + { + return current; + } + + //¿ª·ÅÁбíµÄ´óС¼õ1£¬±íʾ´Ó¿ª·ÅÁбíÖÐÒƳýÁËÒ»¸ö½Úµã + OPEN_SIZE--; + //½«×îС f ÖµµÄ½ÚµãÒƵ½¿ª·ÅÁбíµÄĩ⣬ÒÔ±ãÉÔºó½«ÆäÌí¼Óµ½¹Ø±ÕÁбíÖС£ + //ÕâÊÇΪÁËÓÅ»¯¿ª·ÅÁбíµÄ½á¹¹¡£ + Node* temp = OPEN[min_index]; + OPEN[min_index] = OPEN[OPEN_SIZE]; + OPEN[OPEN_SIZE] = temp; + + //½«µ±Ç°½ÚµãÌí¼Óµ½¹Ø±ÕÁÐ±í£¬¹Ø±ÕÁбí´óС¼Ó1 + CLOSED[CLOSED_SIZE]=current; + CLOSED_SIZE++; + + int key = 0; + // ²éÕÒµ±Ç°½ÚµãÖпհ׿éµÄλÖà + for ( i = 0; i < N; i++) { + for ( j = 0; j < N; j++) { + if (current->puzzle[i][j] == 0) { + key = i * N + j; + break; + } + } + } + + // ³¢ÊÔËĸö·½ÏòµÄÒƶ¯²Ù×÷ + for (dir = 0; dir < 4; dir++) { + Node* new_node = move(current, dir); + + if (new_node != NULL && !isSamePuzzle(new_node->puzzle, current->puzzle)) { + //µÃµ½¶ÔÓ¦µÄg¡¢f¡¢hÖµ + int gNew = current->g + 1; + int hNew = heuristic(new_node, goal); + int fNew = gNew + hNew; + + bool in_OPEN = false; + int open_index = -1; + // ¼ì²éнڵãÊÇ·ñÔÚ¿ª·ÅÁбíÖÐ + for (i = 0; i < OPEN_SIZE; i++) { + if (isSamePuzzle(new_node->puzzle, OPEN[i]->puzzle)) { + in_OPEN = true; + open_index = i; + break; + } + } + + bool in_CLOSED = false; + // ¼ì²éнڵãÊÇ·ñÔڹرÕÁбíÖÐ + for (i = 0; i < CLOSED_SIZE; i++) { + if (isSamePuzzle(new_node->puzzle, CLOSED[i]->puzzle)) { + in_CLOSED = true; + break; + } + } + + //Èô¸Ã½Úµã»ú²»ÔÚ¿ª·ÅÁбíÖÐÒ²²»ÔڹرÕÁбíÖÐ + if (!in_OPEN && !in_CLOSED) { + //°ÑgNew¡¢hNew¡¢fNew¸³¸ønew_nod¶ÔÓ¦µÄg¡¢h¡¢fÖµ£¬²¢½«Æ丸½ÚµãÉèÖÃΪµ±Ç°½Úµã¡£ + new_node->g=gNew; + new_node->f=fNew; + new_node->h=hNew; + new_node->parent=current; + // Ìí¼Óнڵãnew_nodeµ½¿ª·ÅÁÐ±í£¬¿ª·ÅÁбí´óС¼Ó1 + OPEN[OPEN_SIZE]=new_node; + OPEN_SIZE++; + } + //Èç¹ûнڵãÒѾ­ÔÚ¿ª·ÅÁбíÖУ¬µ«Ð嵀 f Öµ¸üС£¬½«¸üпª·ÅÁбíÖÐÒÑ´æÔÚ½ÚµãµÄÐÅÏ¢¡£ + else if (in_OPEN && fNew < OPEN[open_index]->f) { + OPEN[open_index]->f=fNew;//Õâ¿é²»¶®Ê²Ã´Òâ˼ + + } + } + } + } + + return NULL; // ÎÞ½â +} + +// ´òÓ¡½â·¾¶ +void printPath(Node* final) { + int i,j; + if (final == NULL) { + return; + } + printPath(final->parent); // µÝ¹é´òӡ·¾¶ + for (i = 0; i < N; i++) { + if (i%3==0){ + printf("-------\n"); + } + for (j = 0; j < N; j++) { + printf("%d ", final->puzzle[i][j]); + } + + printf("\n"); + + } +} + +int main() { + //int start[N][N] = {{2, 0, 3}, {1, 8, 4}, {7, 6, 5}}; + //int target[N][N] = {{1, 2, 3}, {8, 0, 4}, {7, 6, 5}}; + + // int start[N][N] = {{2, 8, 3}, {1, 6, 4}, {7, 0, 5}}; + // int target[N][N] = {{1, 2, 3}, {8, 0, 4}, {7, 6, 5}}; + + int start[N][N] = {{2, 8, 3}, {1, 0, 4}, {7, 6, 5}}; + int target[N][N] = {{1, 2, 3}, {8, 0, 4}, {7, 6, 5}}; + Node* init = createNode(start); + Node* goal = createNode(target); + + Node* final = AStar(init, goal); + if (final) { + printf("This problem has a solution:\n"); + printPath(final); // ´òÓ¡½â·¾¶ + } else { + printf("This problem has no solution£¡\n"); + } + + return 0; +}