def _beta_operator(self, board: Board): """ ß-operator of the ß-climbing, introduces exploration to the algorithm :param board: Neighbouring state of the board :return: New state of the board """ values = board.values() # scan the board for pos in board.unfilled_positions(): # regenerate the value if it meets the probability of beta if self._with_probability(self._beta_prob): values[pos.y, pos.x] = self._generate_fill_number() # fill the board board.fill_board(values) return board
def _step(self, board: Board) -> Board: """ Performs one hill climb step :param board: Current state of the board to step from :return: Board after the step """ # select random line from unfilled ones unfilled = board.unfilled_by_row() row = list(unfilled.keys())[random.randint(0, len(unfilled) - 1)] line = board.values()[row] # swap 2 characters in it self._swap_in_line(line, unfilled[row]) # update original board board.fill_line(row, line) return board
def _neighbouring_operator(self, board: Board): """ N-operator of the ß-climbing, introduces exploitation to the algorithm :param board: State of the board :return: Neighbouring state """ values = board.values() # iterate modifiable tiles for pos in board.unfilled_positions(): # modify the tile if it meets the probability of n if self._with_probability(self._n_prob): values[pos.y, pos.x] = self._neighbouring_val(values[pos.y, pos.x]) # fill the board board.fill_board(values) return board
def _beta_operator(self, board: Board): """ ß-operator of the ß-climbing, introduces exploration to the algorithm :param board: Neighbouring state of the board :return: New state of the board """ # go through modifiable rows unfilled = board.unfilled_by_row() for row in unfilled: # regenerate the row with probability of beta if self._with_probability(self._beta_prob): line = board.values()[row] # clear for index in unfilled[row]: line[index] = 0 # refill board.fill_line(row, np.array(self._fill_line_unique(line))) return board
def _neighbouring_operator(self, board: Board): """ N-operator of the ß-climbing, introduces exploitation to the algorithm :param board: State of the board :return: Neighbouring state """ values = board.values() # iterate rows unfilled = board.unfilled_by_row() for row in unfilled: # only modify the rows when they meet the probability of n if self._with_probability(self._n_prob): # swap 2 tiles self._swap_in_line(values[row], unfilled[row]) # update original board board.fill_board(values) return board
def _objective(self, board: Board): """ Objective operator Acts as an heuristic, its value represents deviation from the solution) The lower the better, ideal value is 0 :type board: proposed solution :return: Heuristic value for the board """ values = board.values() dev_sum = 0 # rows for row in values: dev_sum += self._eval_tiles(row) # columns for i in range(self._board_size): col = values[:, i] dev_sum += self._eval_tiles(col) # squares for square in board.squares(): dev_sum += self._eval_tiles(square) return dev_sum