def solve(chess_pieces, generation_limit): total_population = 50 population = initialize_population(total_population, chess_pieces) best_solution_overall = population[0] for generation in range(generation_limit): print('\rGeneration number {}, record best: {}'.format( generation, evaluator.boardNumConflicting( convert_list_to_matrix(best_solution_overall))), end='') crossover(population) remove_worst_config(population) for x in range(total_population): if (random.randint(1, 100) % 7 == 0): mutation(population[x]) best_solution = get_best_fit(population) if (is_better( evaluator.boardNumConflicting( convert_list_to_matrix(best_solution)), evaluator.boardNumConflicting( convert_list_to_matrix(best_solution_overall)))): best_solution_overall = best_solution print() print() return convert_list_to_matrix(best_solution_overall)
def remove_worst_config(population): worstConfiguration = population[0] worstConfigurationConflicting = evaluator.boardNumConflicting( convert_list_to_matrix(worstConfiguration)) for listOfPiece in population: listOfPieceConflicting = evaluator.boardNumConflicting( convert_list_to_matrix(listOfPiece)) if (is_better(worstConfigurationConflicting, listOfPieceConflicting)): worstConfiguration = listOfPiece worstConfigurationConflicting = listOfPieceConflicting population.remove(worstConfiguration)
def get_best_fit(population): #initialize the best fit bestFitParent = population[0] bestFitConflicting = evaluator.boardNumConflicting( convert_list_to_matrix(bestFitParent)) #searching for the best fit configuration in population for pieceList in population: numConflicting = evaluator.boardNumConflicting( convert_list_to_matrix(pieceList)) if (is_better(numConflicting, bestFitConflicting)): bestFitParent = pieceList bestFitConflicting = numConflicting return bestFitParent
def crossover(population): # Using russian roulette method weight = [] # Get probability for each configuration for configuration in population: conflictNumber = evaluator.boardNumConflicting( convert_list_to_matrix(configuration)) #prevent division by zero if conflictNumber[0] == 0: weight.append(2) else: weight.append(1 / conflictNumber[0]) # Use random with probability to choose parent parent1 = random.choices(population, weight)[0] parent2 = random.choices(population, weight)[0] while parent1 == parent2: parent2 = random.choices(population, weight)[0] # Choose the crossover point # Use two-point crossover crossoverBeginPoint = random.randint(0, len(parent1) - 1) crossoverEndingPoint = random.randint(0, len(parent1) - 1) #begining point must be more than it's ending point if crossoverBeginPoint > crossoverEndingPoint: temp = crossoverBeginPoint crossoverBeginPoint = crossoverEndingPoint crossoverEndingPoint = temp # Make child that inherit both parents genes child = convert_matrix_to_list(convert_list_to_matrix(parent1)) child.sort(key=lambda piece: piece.jenis) parent2.sort(key=lambda piece: piece.jenis) # Mix genes from parent1 and parent2 childMatrix = convert_list_to_matrix(child) for i in range(crossoverBeginPoint, crossoverEndingPoint): # Check whether the position has occupied if (childMatrix[parent2[i].posisiX][parent2[i].posisiY] == ''): child[i] = parent2[i] childMatrix = convert_list_to_matrix(child) population.append(child)
def solve(board, wandering_steps=20): boredom_threshold = wandering_steps steps = 0 while True: steps += 1 print('\rClimbing the hill', '.' * (steps // 10 % 5 + 1), end='') hasmoved = False pieceBestMoves = [] prevScore = normalize_scoring(ev.boardNumConflicting(board)) pieceScores = find_piece_scores(board) for piece in pieceScores: scr_collection, bestMoves = find_best_move(board, piece['pos'][0], piece['pos'][1]) pieceBestMoves.append([piece, bestMoves]) move = random.choice(bestMoves) if prevScore > move['scr']: # Do the move since smaller score is better move_piece(board, piece['pos'], move['pos']) hasmoved = True break if not hasmoved: boredom_threshold -= 1 if boredom_threshold < 0: break else: # Find moves that doesn't change the score possiblePlateau = [x for x in pieceBestMoves if len(x[1]) > 1] if possiblePlateau: if boredom_threshold == wandering_steps - 1: print( '\nEncountered a plateau, taking at most {} wandering steps' .format(wandering_steps)) piece, bestMoves = random.choice(possiblePlateau) move = random.choice(bestMoves) move_piece(board, piece['pos'], move['pos']) else: break else: boredom_threshold = wandering_steps print('\nThis is the top of the hill')
def find_best_move(board, toBeMoved_x, toBeMoved_y): toBeMoved = board[toBeMoved_x][toBeMoved_y] board[toBeMoved_x][toBeMoved_y] = EMPTY_TILE newScores = [] bestScore = [256, 256] bestNewPos = None scr_collection = [] for i in range(8): for j in range(8): if board[i][j] == EMPTY_TILE: board[i][j] = toBeMoved score = normalize_scoring(ev.boardNumConflicting(board)) newScores.append({'pos': [i, j], 'scr': score}) scr_collection.append(score) if score < bestScore: bestScore = score bestNewPos = [i, j] board[i][j] = EMPTY_TILE board[toBeMoved_x][toBeMoved_y] = toBeMoved bestMoves = [x for x in newScores if x['scr'] == bestScore] return scr_collection, bestMoves
def solve(init_state, limit_step=15000, temperature=10): global initial_temperature # Initialize initial values initial_temperature = temperature current_state = init_state current_score = boardNumConflicting(current_state) current_solution = [ ] # Current solution [board,num_of_inter-color_conflicts] is_a_solution_found = False print("Press Ctrl+C at any time to terminate search") try: for step in range(limit_step): temp = get_temperature(step) reset_possible_moves() print("\rCurrently on step #" + str(step + 1) + " with current temp. " + str(temp), end="") has_stepped = False while not has_stepped: new_state = get_random_next_state(current_state) new_score = boardNumConflicting(new_state) # If "solution" is reached if (new_score[0] == 0): current_state = new_state current_score = new_score # Compare it with current_solution if current_solution: if (current_solution[1] < new_score[1]): current_solution[0] = new_state current_solution[1] = new_score[1] else: current_solution = [new_state, new_score[1]] has_stepped = True # Print notification if (first) solution is found if not is_a_solution_found: print() print( "A solution has been found! Press Ctrl+C to stop search and output current best solution..." ) is_a_solution_found = True # If new state is better than current state elif ((new_score[0] <= current_score[0]) and (new_score[1] >= current_score[1])): current_state = new_state current_score = new_score has_stepped = True # If new state is worse than current state elif is_accept(current_score, new_score, temp): current_state = new_state current_score = new_score has_stepped = True except KeyboardInterrupt: print() print("Ctrl+C received, stopping search...") print() if current_solution: current_state = current_solution[0] return current_state
def display_state(): input_helper.display_board(input_helper.board) print(eva.boardNumConflicting(input_helper.board))