diff --git a/README.md b/README.md index de8ea84..9a9dc95 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,249 @@ # A8solution +#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)); + //��ʵ�ָú��� + for(int 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 flag=0; + for(int i=0;ipuzzle[i][j]!=goal->puzzle[i][j])&&i!=2&&j!=2) h++; + } + } + return h; + + +} + +// �ƶ������������µ�ƴͼ״̬ +Node* move(Node* current, int dir) { + int key_x, key_y;//��¼�հ׿��λ�� + // �ҵ��հ׿��λ�� + for(int i=0;i<3;i++){ + for(int j=0;j<3;j++){ + if(current->puzzle[i][j]==0){ + key_x=i;key_y=j; + } + } + } + int new_x,new_y; + new_x=key_x; + new_y=key_y; + + //��new_x��new_y��ֵ + if(dir==0)new_y--; + if(dir==1)new_y++; + if(dir==2)new_x--; + if(dir==3)new_x++; + // �����ƶ���������¿��λ�ã����������ƶ� + if(new_x<0||new_x>N-1||new_y>N-1||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ֵ�Ľڵ� + for(int i=0;iOPEN[i]->f){ + min_f=OPEN[i]->f; + 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]=OPEN[OPEN_SIZE]; + CLOSED_SIZE++; + int key = 0; + // ���ҵ�ǰ�ڵ��пհ׿��λ�� + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + if (current->puzzle[i][j] == 0) { + key = i * N + j; + break; + } + } + } + + // �����ĸ�������ƶ����� + for (int 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 (int 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 (int 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->h=hNew; + new_node->f=fNew; + 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; + OPEN[open_index]->h=hNew; + OPEN[open_index]->g=gNew; + OPEN[open_index]->parent=current; + } + } + } + } + + return NULL; // �޽� +} + +// ��ӡ��·�� +void printPath(Node* final) { + if (final == NULL) { + return; + } + printPath(final->parent); // �ݹ��ӡ·�� + for (int i = 0; i < N; i++) { + if (i%3==0){ + printf("-------\n"); + } + for (int 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; +}