main
高世波 1 year ago
parent eb4ea3fa4e
commit 5839212c90

@ -18,13 +18,13 @@ Node* createNode(int puzzle[N][N]) {
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
newnode.puzzle[i][j] = puzzle[i][j];
newnode->puzzle[i][j] = puzzle[i][j];
}
}
newnode.parent = NULL;
newnode.f = 0;
newnode.g = 0;
newnode.h = 0;
newnode->parent = NULL;
newnode->f = 0;
newnode->g = 0;
newnode->h = 0;
}
// 检查两个拼图状态是否相同
@ -45,7 +45,7 @@ void printPuzzle(int puzzle[N][N]) {
for(int j = 0; j < N; j++){
printf("%d ",puzzle[i][j]);
}
printf("\n")
printf("\n");
}
}
@ -57,7 +57,7 @@ int heuristic(Node* current, Node* goal) {
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
if(current.puzzle[i][j] != goal.puzzle[i][j]) h++;
if(current->puzzle[i][j] != goal->puzzle[i][j]) h++;
}
}
return h;
@ -67,13 +67,30 @@ int heuristic(Node* current, Node* goal) {
Node* move(Node* current, int dir) {
int key_x, key_y;//记录空白块的位置
// 找到空白块的位置
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
if(current->puzzle[i][j] == 0){
key_x = i;
key_y = j;
break;
}
}
}
//给new_x、new_y赋值
int new_x = key_x;
int 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_x >= N || new_y < 0 || new_y >= N){
return NULL;
}
// 创建新节点,复制当前拼图状态,并交换块的位置
Node* new_node = createNode(current->puzzle);
@ -97,15 +114,22 @@ Node* AStar(Node* start, Node* goal) {
int min_f = OPEN[0]->f;//初始化最小的f
int min_index = 0;
// 查找开放列表中具有最小f值的节点
for(int i = 0; i < OPEN_SIZE; i++){
if(OPEN[i]->f < min_f){
min_f = OPEN[i]->f;
min_index = i;
}
}
Node* current = OPEN[min_index]; // 获取具有最小f值的节点
// 如果当前节点与目标状态匹配,表示找到解
if(isSamePuzzle(current->puzzle,goal->puzzle)){
return current;
}
//开放列表的大小减1表示从开放列表中移除了一个节点
OPEN_SIZE--;
//将最小 f 值的节点移到开放列表的末尾,以便稍后将其添加到关闭列表中。
//这是为了优化开放列表的结构。
@ -114,7 +138,7 @@ Node* AStar(Node* start, Node* goal) {
OPEN[OPEN_SIZE] = temp;
//将当前节点添加到关闭列表关闭列表大小加1
CLOSED[CLOSED_SIZE++] = current;
int key = 0;
// 查找当前节点中空白块的位置
@ -151,17 +175,31 @@ Node* AStar(Node* start, Node* goal) {
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;
}
//如果新节点已经在开放列表中,但新的 f 值更小,将更新开放列表中已存在节点的信息。
else if (in_OPEN && fNew < OPEN[open_index]->f) {
OPEN[open_index]->g = gNew;
OPEN[open_index]->h = hNew;
OPEN[open_index]->f = fNew;
OPEN[open_index]->parent = current;
}
}
}

Loading…
Cancel
Save