def evaluate_bfs_children(open_list: List[Tuple[float, int, Node]],
                          open_set: Set[str], closed_set: set, node: Node,
                          heuristic_algorithm: str):
    """
    Evaluate all of a node's children and add them to the open list
    :param open_list: Priority Queue containing all discovered nodes
    :param open_set: Set containing all grid strings of all discovered nodes from open_list
    :param closed_set: Set containing all visited grid strings
    :param node: Node object
    :param heuristic_algorithm: Which heuristic to use
    :return: void
    """
    for row, col in np.ndindex(node.grid.shape):
        child_grid = np.copy(node.grid)
        diff_black_tokens = flip_token(child_grid, row, col)
        child_s_grid: str = grid_to_string(child_grid)
        child_move = '{}:{}'.format(row, col)
        child_hn: float = get_heuristic(heuristic_algorithm, node.black_tokens,
                                        diff_black_tokens, node.move_history,
                                        child_move)
        if child_hn != DOUBLE_PRESS and child_s_grid not in open_set and child_s_grid not in closed_set:
            child_path = copy.deepcopy(node.path_from_root)
            child_path.append(get_solution_move(row, col, child_s_grid))
            child_moves = copy.deepcopy(node.move_history)
            child_moves.add(child_move)

            child_node = Node(child_grid, child_s_grid, node.depth, child_path,
                              child_hn, node.black_tokens + diff_black_tokens,
                              child_moves)
            # Add child to open set and priority queue
            heappush(open_list,
                     (child_node.get_hn(), get_white_token_score(child_s_grid),
                      child_node))
            open_set.add(child_s_grid)
Example #2
0
def get_board_score(board, is_max, use_heuristic):
    score = 0
    for i in range(60):
        if board[i] != EMPTY:
            score += board[i]

    if use_heuristic:
        score += get_heuristic(board, is_max)

    return score
def execute_bfs(grid: np.ndarray, goal: str, max_l: int, puzzle_number: int,
                heuristic_algorithm: str):
    """
    Wrapper function to run bfs
    :param grid: numpy 2D array representation of the input board.
    :param goal: goal grid string
    :param max_l: maximum search path length
    :param puzzle_number: line number of the puzzle
    :param heuristic_algorithm: Heuristic algorithm to be used for this run
    :return: void
    """
    print(
        "Executing BFS Algorithm with heuristic {} and max search length of {} on the grid\n{}"
        .format(heuristic_algorithm, max_l, grid))
    # Initialize necessary data structures
    """
    float: h(n)
    int: pegs
    Node: board state
    """
    open_list: List[Tuple[float, int, Node]] = []
    open_set = set()  # path needed
    closed_set = set()  # nodes already visited
    search_path: List[str] = []

    # initialize root node information
    s_grid = grid_to_string(grid)
    path = ['{}   {}'.format(0, s_grid)
            ]  # adds the initial board state to the grid
    num_black_tokens = s_grid.count('1')
    hn = get_heuristic(heuristic_algorithm, num_black_tokens, 0, set(), '')
    root_node = Node(grid, s_grid, 1, path, hn, num_black_tokens, set())

    heappush(open_list,
             (root_node.get_hn(), get_white_token_score(s_grid), root_node))
    open_set.add(s_grid)

    start_time = time.time()
    solution_path = bfs(open_list, open_set, closed_set, search_path, goal,
                        max_l, heuristic_algorithm,
                        start_time + TIME_TO_SOLVE_PUZZLE_SECONDS)
    end_time = time.time()
    write_results(puzzle_number, BEST_FIRST_ALGORITHM, heuristic_algorithm,
                  solution_path, search_path)
    gather_performance(puzzle_number, np.size(grid, 0), solution_path,
                       len(search_path), start_time, end_time,
                       BEST_FIRST_ALGORITHM, heuristic_algorithm)
    print('Found no solution' if solution_path == constant.NO_SOLUTION else
          'Found solution in {} moves'.format(len(solution_path) - 1))