예제 #1
0
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)
예제 #2
0
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)
예제 #3
0
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
예제 #4
0
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)
예제 #5
0
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')
예제 #6
0
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
예제 #7
0
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
예제 #8
0
def display_state():
    input_helper.display_board(input_helper.board)
    print(eva.boardNumConflicting(input_helper.board))