2015-10-07 78 views
0

我试图将宽度优先搜索算法应用于我的尝试来解决8益智游戏。但在某些情况下,我耗尽了内存,但在更简单的情况下,它可以毫无问题地解决问题。使用BFS改善8-Puzzle

我该如何改进我的算法来修复它?

的main.c

/* Standard Libraries */ 
#include <stdio.h> 
#include <stdlib.h> 

/* Game */ 
#include <8puzzle/queue.h> 
#include <8puzzle/node.h> 
#include <8puzzle/state.h> 
#include <8puzzle/action.h> 
#include <8puzzle/game.h> 

/* Main */ 
int main(void) 
{ 
    /* Queue containing the States */ 
    Queue *q = create_queue(); 

    /* Create Root State */ 
    State *root_state = malloc(sizeof(State)); 

    /* Read the State */ 
    for (int i = 0; i < 3; i++) 
    for (int j = 0; j < 3; j++) 
    { 
     unsigned int temp; 
     scanf("%u", &temp); 
     root_state->game[i][j] = temp; 
     if (temp == 0) 
     { 
     root_state->empty_space.line = i; 
     root_state->empty_space.column = j; 
     } 
    } 

    /* Create a Node */ 
    Node *root = malloc(sizeof(Node)); 
    root->data = root_state; 

    /* Check if it's finished */ 
    if (is_finished(root->data)) 
    { 
    printf("Já está finalizado.\n"); 
    return 0; 
    } 

    /* Add State to Queue */ 
    enqueue(q, root); 

    /* Iterate while queue isn't empty */ 
    while (!is_queue_empty(q)) 
    { 
    /* Get current node */ 
    Node *node = dequeue(q); 

    /* Check if it's correct */ 
    if (is_finished(node->data)) 
    { 
     Node *parent = node->prev; 
     while (parent) 
     { 
     printf("1\n"); 
     parent = parent->prev; 
     } 
     return 0; 
    } 

    /* Generate possible moves */ 
    Coordinate *sucessors = malloc(4 * sizeof(Coordinate)); 
    int amount_of_sucessors = generate_state_sucessors(node->data, sucessors); 

    /* For each new possibility of empty space coordinate */ 
    for (int i = 0; i < amount_of_sucessors; i++) 
    { 
     /* Create the new state */ 
     State *new_state = swap_state((State *)node->data, sucessors[i]); 

     /* Add it to queue */ 
     Node *new_node = malloc(sizeof(Node)); 
     new_node->data = new_state; 
     node->next = new_node; 
     new_node->prev = node; 
     enqueue(q, new_node); 
    } 
    } 

    /* Return to operating system */ 
    return 0; 
} 

game.c

/** 
* Game Implementation 
* 
* This file will produce the implementation of the game, along with the BFS 
* algorithm to solve the 8-Puzzle Problem. 
*/ 

/* Standard Libraries */ 
#include <stdbool.h> 

/* Game Files */ 
#include <8puzzle/state.h> 
#include <8puzzle/node.h> 
#include <8puzzle/queue.h> 
#include <8puzzle/action.h> 
#include <8puzzle/game.h> 

bool is_finished(State *s) 
{ 
    if (s->game[0][0] != 1) return false; 
    if (s->game[0][1] != 2) return false; 
    if (s->game[0][2] != 3) return false; 
    if (s->game[1][0] != 8) return false; 
    if (s->game[1][2] != 4) return false; 
    if (s->game[2][0] != 7) return false; 
    if (s->game[2][1] != 6) return false; 
    if (s->game[2][2] != 5) return false; 
    return true; 
} 

回答

3

8难题的可能位置的数量是9! (其中一半无法从给定的起始位置到达,因此实际上只有181440个可能)。

另一方面,最多可能需要31次移动来解决难题,according to wikipedia。在每个位置,有2,3或4个可能的移动。因此,广度优先搜索可以轻松排列2^31个职位。

这导致了一个明显的矛盾。当只有181440个职位可能时,BFS如何排队2^31职位?简单来说,有许多不同的方法可以达到同一个电路板的位置,而BFS正在排队大量重复。

解决方案:只排入尚未尝试过的位置。这可以通过使用一组362880布尔值来完成,这些布尔值跟踪已经尝试过的位置。通过避免重复,可以保证队列中的条目数不会超过181440.