diff --git a/A8code-修改版.c b/A8code-修改版.c new file mode 100644 index 0000000..2257d99 --- /dev/null +++ b/A8code-修改版.c @@ -0,0 +1,255 @@ +#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]) { + int i,j; + Node* newnode = (Node*)malloc(sizeof(Node)); + //ÇëʵÏָú¯Êý + for ( i = 0; i < N;i++) + for ( j = 0; j < N;j++){ + newnode->puzzle[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; + for ( i = 0; i < N;i++) + for ( j = 0; j < N;j++) + if (a[i][j]!=b[i][j]) + return false; + return true; +} + +// ´òӡƴͼ״̬ +void printPuzzle(int puzzle[N][N]) { + //Ë«ÖØforÑ­»·ÊµÏÖƴͼµÄ´òÓ¡ + int i,j; + for ( i = 0; i < N;i++){ + for ( j = 0; j < N;j++) + if(puzzle[i][j])printf("%d ", puzzle[i][j]); + else printf(" "); + putchar('\n'); + } + printf("\n"); +} + + +// Æô·¢º¯Êý£¬¼ÆË㵱ǰ״̬µ½Ä¿±ê״̬µÄ¹À¼Æ´ú¼Û +int heuristic(Node* current, Node* goal) { + int h = 0; + // ¼ÆË㲻ƥÅäµÄƴͼ¿éÊýÁ¿ + int i,j; + for ( i = 0; i < N;i++) + for ( j = 0; j < N;j++) + if(current->puzzle[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; i < N;i++) + for ( j = 0; j < N;j++) + if(!current->puzzle[i][j]){ + key_x = i; + key_y = j; + } + //¸ønew_x¡¢new_y¸³Öµ + int new_x = key_x; + int new_y = key_y; + switch (dir){ + case 0: + new_x--; + break; + case 1: + new_x++; + break; + case 2: + new_y--; + break; + case 3: + new_y++; + break; + default: + break; + } + // ¸ù¾ÝÒƶ¯·½Ïò¸üÐÂпéµÄλÖã¬ÉÏÏÂ×óÓÒÒƶ¯ + if(new_x>=3||new_x<0||new_y>=3||new_y<0) + 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; // ¹Ø±ÕÁбíµÄ´óС + + 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ÖµµÄ½Úµã + int i,j,dir; + for ( i = 0; i < OPEN_SIZE;i++){ + if(OPEN[i]->ff; + min_index = i; + } + } + Node *current = OPEN[min_index]; // »ñÈ¡¾ßÓÐ×îСfÖµµÄ½Úµã + if(isSamePuzzle(current->puzzle,goal->puzzle)) + return current; + // Èç¹ûµ±Ç°½ÚµãÓëÄ¿±ê״̬ƥÅ䣬±íʾÕÒµ½½â + OPEN_SIZE--; + //¿ª·ÅÁбíµÄ´óС¼õ1£¬±íʾ´Ó¿ª·ÅÁбíÖÐÒƳýÁËÒ»¸ö½Úµã + + //½«×îС f ÖµµÄ½ÚµãÒƵ½¿ª·ÅÁбíµÄĩ⣬ÒÔ±ãÉÔºó½«ÆäÌí¼Óµ½¹Ø±ÕÁбíÖС£ + //ÕâÊÇΪÁËÓÅ»¯¿ª·ÅÁбíµÄ½á¹¹¡£ + Node* temp = OPEN[min_index]; + OPEN[min_index] = OPEN[OPEN_SIZE]; + OPEN[OPEN_SIZE] = temp; + CLOSED[CLOSED_SIZE] = current; + CLOSED_SIZE++; + //½«µ±Ç°½ÚµãÌí¼Óµ½¹Ø±ÕÁÐ±í£¬¹Ø±ÕÁбí´óС¼Ó1 + 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; + int closed_index = -1; + for (i = 0; i < CLOSED_SIZE; i++) { + if (isSamePuzzle(new_node->puzzle, CLOSED[i]->puzzle)) { + in_CLOSED = true; + closed_index = i; + break; + } + } + // ¼ì²éнڵãÊÇ·ñÔڹرÕÁбíÖÐ + //Èô¸Ã½Úµã»ú²»ÔÚ¿ª·ÅÁбíÖÐÒ²²»ÔڹرÕÁбíÖÐ + if (!in_OPEN && !in_CLOSED) { + new_node->f = fNew; + new_node->g = gNew; + new_node->h = hNew; + new_node->parent = current; + //°ÑgNew¡¢hNew¡¢fNew¸³¸ønew_nod¶ÔÓ¦µÄg¡¢h¡¢fÖµ£¬²¢½«Æ丸½ÚµãÉèÖÃΪµ±Ç°½Úµã¡£ + OPEN[OPEN_SIZE] = new_node; + OPEN_SIZE++; + // Ìí¼Óнڵãnew_nodeµ½¿ª·ÅÁÐ±í£¬¿ª·ÅÁбí´óС¼Ó1 + + } + //Èç¹ûнڵãÒѾ­ÔÚ¿ª·ÅÁбíÖУ¬µ«Ð嵀 f Öµ¸üС£¬½«¸üпª·ÅÁбíÖÐÒÑ´æÔÚ½ÚµãµÄÐÅÏ¢¡£ + else if (in_OPEN && fNew < OPEN[open_index]->f) { + new_node->f = fNew; + new_node->g = gNew; + new_node->h = hNew; + new_node->parent = current; + } + } + } + } + + 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; +}