def hill_climbing_caterpillar(protein, iterations, max_non_improvements):

    # Check if unsupported 3d mode.
    check_dimensions(protein.chain.chain_list)

    # We start with a straight protein, you could replace this with a search (random for example)
    build_straight_protein(protein)
    # Save the score at every iteration (Not yet implemented)
    scores = []
    total_iterations = 0

    # The amount of turns the score hasnt improved.
    times_not_improved = 0
    times_not_improved_limit = max_non_improvements

    # The overal best score and chain is saved here
    best_score = 1
    best_chain = []

    while total_iterations < iterations:

        # pick random index for chain and that amino.
        max_index = len(protein.amino_string) - 1
        chosen_index = random.randint(1, max_index - 1)

        # get the amino and his fold with the random index
        chosen_amino = protein.chain.chain_list[chosen_index]
        chosen_amino_fold = chosen_amino.fold

        # Save old chain if the random move doesnt turn out to be legal
        old_chain = copy.deepcopy(protein.chain.chain_list)

        # Also pick random move and apply.
        moves = get_legal_moves(chosen_amino.coordinates,
                                protein.chain.chain_list)

        # remove initial move from the moves
        if chosen_amino_fold in moves:
            moves.remove(chosen_amino_fold)

        # if there a no possible new moves for this amino loop again
        if not moves:
            continue

        # choose random fold and adjust fold of amino
        chosen_move = random.choice(moves)
        chosen_amino.fold = chosen_move

        # get the amino thereafter from the chain
        next_amino = protein.chain.chain_list[chosen_index + 1]

        # If the chosen amino is the one before the last only this amino needed to change
        if chosen_index == max_index - 1:
            pass

        # if the there need to be changed only 2 aminos
        elif chosen_move == next_amino.fold or chosen_index + 2 >= max_index:
            next_amino.fold = chosen_amino_fold

        # skip if new move is 180 degrees to the other side, rearanging gets very difficult
        elif chosen_move * -1 == chosen_amino_fold:
            protein.chain.chain_list = old_chain
            continue

        else:
            # change next fold and the fold after that
            next_amino.fold = chosen_amino_fold
            after_next_amino = protein.chain.chain_list[chosen_index + 2]
            after_next_amino.fold = chosen_move * -1

            # pull rest of the chain by changing position of aminos thereafter 2 places
            for i in range(chosen_index + 1, max_index - 2):
                amino_changed = old_chain[i]
                amino_pulled = protein.chain.chain_list[i + 2]
                amino_pulled.fold = amino_changed.fold

        # Make sure last amino gets a fold of 0
        last_amino = protein.chain.chain_list[-1]
        last_amino.fold = 0

        # Rebuild the chain/matrix.
        legal_chain = rebuild_chain(protein, chosen_index + 1)

        # Function returns False if it isnt a legal chain.
        # If illegal chain, load back old_chain
        if not legal_chain:
            protein.chain.chain_list = old_chain
            continue

        total_iterations += 1

        # Load matrix of new chain
        protein.matrix, protein.chain.chain_list = get_matrix(
            protein.chain.chain_list)

        # check for errror and revert to old chain
        if protein.chain.chain_list == False:
            protein.chain.chain_list = old_chain
            print("error: false chain")
            continue

        # Calculate score of new chain
        score = get_score(protein.chain.chain_list, protein.matrix)

        # Continue with new chain if same or better score
        if score <= protein.chain.score:
            if len(best_chain) == 0:
                best_chain = copy.deepcopy(protein.chain.chain_list)
            # New "local" best score
            if score < protein.chain.score:
                print("new best score: ", end="")
                print(score)
                # Reset times not improved
                times_not_improved = 0

                # Actual new best score
                if score < best_score:
                    best_score = score
                    best_chain = copy.deepcopy(protein.chain.chain_list)

            # Score is same so not improved.
            else:
                times_not_improved += 1

            protein.chain.score = score

        # Chain is worse
        else:

            # If times not improved limit is reaced, continue with that chain anyway
            if times_not_improved >= times_not_improved_limit:
                protein.chain.score = score
                times_not_improved = 0

            # abandon that chain.
            else:
                protein.chain.chain_list = old_chain

    # Save the best score and chain in the protein
    protein.chain.chain_list = best_chain
    protein.matrix, protein.chain.chain_list = get_matrix(best_chain)
Exemplo n.º 2
0
def simulated_annealing(protein, iterations, temp_start, temp_end):
    # We start with a straight protein, you could replace this with a search (random for example)
    build_straight_protein(protein)

    # Save the score at every iteration (Not yet implemented)
    scores = []
    total_iterations = 0

    # The overal best score and chain is saved here
    best_score = 1
    best_chain = []

    temperature_start = temp_start
    temperature_end = temp_end
    temp_step = (temperature_start - temperature_end) / iterations
    temperature = temperature_start

    while total_iterations < iterations:

        # pick random index for chain and that amino.
        chosen_index = random.randint(0, len(protein.amino_string) - 1)
        chosen_amino = protein.chain.chain_list[chosen_index]

        # Save old chain if the random move doesnt turn out to be legal
        old_chain = copy.deepcopy(protein.chain.chain_list)

        # Also pick random move and apply.
        moves = get_legal_moves(chosen_amino.coordinates,
                                protein.chain.chain_list)

        if not moves:
            continue

        chosen_move = random.choice(moves)
        chosen_amino.fold = chosen_move

        # Rebuild chain for that point on.
        legal_chain = rebuild_chain(protein, chosen_index + 1)

        # Function returns False if it isnt a legal chain.
        # If illegal chain, load back old_chain
        if not legal_chain:
            protein.chain.chain_list = old_chain

        total_iterations += 1

        # Load matrix of new chain
        protein.matrix, protein.chain.chain_list = get_matrix(
            protein.chain.chain_list)

        # Calculate score of new chain
        score = get_score(protein.chain.chain_list, protein.matrix)

        # New best score
        if score < best_score:
            if len(best_chain) == 0:
                best_chain = copy.deepcopy(protein.chain.chain_list)
            print("new best score: ", end="")
            print(score)
            best_score = score
            best_chain = copy.deepcopy(protein.chain.chain_list)

        # Calculate if chain should be accepted based on:
        # New score, old score, temperature, random number
        acceptance_rate = (2**(abs(score) -
                               abs(protein.chain.score))) / temperature
        random_number = random.uniform(0, 1)

        # Accept iteration
        if random_number < acceptance_rate:
            protein.chain.score = score

        # Abbandon iteration
        else:
            protein.chain.chain_list = old_chain

        temperature = temperature - temp_step

    protein.chain.chain_list = best_chain
    protein.matrix, protein.chain.chain_list = get_matrix(best_chain)
Exemplo n.º 3
0
def beam_search(protein, ch_score):

    # Check if unsupported 3d mode.
    check_dimensions(protein.chain.chain_list)

    # Get chain WITH first amino already in it.
    start_chain = protein.chain
    # Create queue and put the first amino in it.
    queue = Queue(maxsize=0)
    queue.put(start_chain)

    # Finished queues. Is this smart?
    finished_chains = []

    # Keeps track of scores in 1 layer.
    scores = []

    # Go trough the queue.
    while not queue.empty():
        # Get the first chain from the queue.
        chain_actual = queue.get()

        # Get the index from the length of the chain.
        index = len(chain_actual.chain_list)

        # get the globals
        global global_index
        global avg_scores

        # check for level change level change by comparing global index with actual index
        if index == global_index + 1:
            # change global index to new level
            global_index = index

            # update global avg score and reset scores
            sum_scores = sum(scores) / len(scores)
            avg_scores = sum_scores
            scores = []

        # Remove chain from queue if score is worse than cutoff score.
        chain_score = chain_actual.score
        if chain_score > avg_scores:
            continue

        # Last amino always has fold of 0.
        if index + 1 == len(protein.amino_string):

            fold = 0
            atype = protein.amino_string[index]
            coordinates = chain_actual.chain_list[-1].get_fold_coordinates()

            new_amino = Amino(atype, fold, coordinates)
            chain_actual.chain_list.append(new_amino)

            finished_chains.append(chain_actual)

        # Determine fold and make new chain for every possibility.
        else:
            legal_moves = get_legal_moves(
                chain_actual.chain_list[-1].get_fold_coordinates(),
                chain_actual.chain_list)

            # If there are no legal moves chain ends here.
            if legal_moves:
                # Go trough the legal moves and make a new_chain for every move, then put them in the queue.
                for move in legal_moves:
                    atype = protein.amino_string[index]
                    coordinates = chain_actual.chain_list[
                        -1].get_fold_coordinates()

                    # Make a new amino and add it to the a new chain with deepcopy.
                    amino = Amino(atype, move, coordinates)
                    new_chain = copy.deepcopy(chain_actual)
                    new_chain.chain_list.append(amino)

                    # Put the new chain in the queue, set chain's score variable to its score, and add score to this layer's score list.

                    matrix, offset = get_matrix_efficient(new_chain.chain_list)
                    score = get_score_efficient(new_chain.chain_list, matrix,
                                                offset, 1)
                    new_chain.score = score
                    queue.put(new_chain)

                    # add score to the list which tracks all scores in this level
                    scores.append(score)

    # The best score and corresponding chain that has been found.
    best_score = 1
    best_chains = []

    # Goes over all finished chains to find the one with the best score.
    for chain in finished_chains:
        protein1 = Protein(protein.amino_string, "2d")
        protein1.matrix, protein1.chain = get_matrix(
            copy.deepcopy(chain).chain_list)

        matrix, xy_offset = get_matrix_efficient(chain.chain_list)
        score = get_score_efficient(chain.chain_list, matrix, xy_offset,
                                    ch_score)

        # If the score is better than the best score, replace best_chains.
        # If score is equal add chain to best_chains.
        if score < best_score:
            best_score = score
            best_chains = []
            print("New best score: " + str(score))
            best_chains.append(chain)
        elif score == best_score:
            best_chains.append(chain)

    protein.matrix, protein.chain.chain_list = get_matrix(
        best_chains[0].chain_list)
Exemplo n.º 4
0
def breadth_search(protein, ch_score):

    # Check if unsupported 3d mode.
    check_dimensions(protein.chain.chain_list)

    # Get chain WITH first amino already in it.
    start_chain = protein.chain
    # Create queue and put the first amino in it
    queue = Queue(maxsize = 0)
    queue.put(start_chain)

    # Finished queues. Is this smart?
    finished_chains = []

    # Go trough the queue.
    while not queue.empty():
        # Get the first chain from the queue.
        chain_actual = queue.get()

        # Get the index from the length of the chain.
        index = len(chain_actual.chain_list)

        # Last amino always has fold of 0.
        if  index + 1 == len(protein.amino_string):

            fold = 0
            atype = protein.amino_string[index]
            coordinates = chain_actual.chain_list[-1].get_fold_coordinates()
            new_amino = Amino(atype, fold, coordinates)
            chain_actual.chain_list.append(new_amino)

            # Save the chain to the finished chain list.
            finished_chains.append(chain_actual)


        # Determine fold and make new chain for every possibility.
        else:
            legal_moves = get_legal_moves(chain_actual.chain_list[-1].get_fold_coordinates(), chain_actual.chain_list)

            # if there are no legal moves chain ends here.
            if legal_moves:
                # Go trough the legal moves and make a new_chain for every move, then put them in the queue.
                for move in legal_moves:

                    atype = protein.amino_string[index]
                    coordinates = chain_actual.chain_list[-1].get_fold_coordinates()
                    # Make a new amino and add it to the a new chain with deepcopy.
                    amino = Amino(atype, move, coordinates)
                    new_chain = copy.deepcopy(chain_actual)
                    new_chain.chain_list.append(amino)
                    # Put the new chain in the queue.
                    queue.put(new_chain)

    # The best score and corresponding chain that has been found.
    best_score = 1
    best_chains = []

    # Goes over all finished chains to find the one with the best score.
    for chain in finished_chains:

        matrix, xy_offset = get_matrix_efficient(chain.chain_list)
        score = get_score_efficient(chain.chain_list, matrix, xy_offset, ch_score)

        # If the score is better than the best score, replace best_chains.
        # if score is equal add chain to best_chains.
        if score < best_score:
            best_score = score
            best_chains = []
            print("New best score: " + str(score))
            best_chains.append(chain)
        elif score == best_score:
            best_chains.append(chain)

    protein.matrix, protein.chain.chain_list = get_matrix(best_chains[0].chain_list)
Exemplo n.º 5
0
def hill_climbing(protein, iterations, max_non_improvements):

    # We start with a straight protein, you could replace this with a search (random for example)
    build_straight_protein(protein)

    # Save the score at every iteration.
    total_iterations = 0

    # The amount of turns the score hasnt improved.
    times_not_improved = 0
    times_not_improved_limit = max_non_improvements

    # The overal best score and chain is saved here
    best_score = 1
    best_chain = []

    while total_iterations < iterations:

        # pick random index for chain and that amino.
        chosen_index = random.randint(0, len(protein.amino_string) - 1)
        chosen_amino = protein.chain.chain_list[chosen_index]

        # Save old chain if the random move doesnt turn out to be legal
        old_chain = copy.deepcopy(protein.chain.chain_list)

        # Also pick random move and apply.
        moves = get_legal_moves(chosen_amino.coordinates,
                                protein.chain.chain_list)

        if not moves:
            continue

        chosen_move = random.choice(moves)
        chosen_amino.fold = chosen_move

        # Rebuild the chain/matrix.
        legal_chain = rebuild_chain(protein, chosen_index + 1)

        # Function returns False if it isnt a legal chain.
        # If illegal chain, load back old_chain
        if not legal_chain:
            protein.chain.chain_list = old_chain

        total_iterations += 1

        # Load matrix of new chain
        protein.matrix, protein.chain.chain_list = get_matrix(
            protein.chain.chain_list)

        # Calculate score of new chain
        score = get_score(protein.chain.chain_list, protein.matrix)

        # Continue with new chain if same or better score
        if score <= protein.chain.score:
            if len(best_chain) == 0:
                best_chain = copy.deepcopy(protein.chain.chain_list)

            # New "local" best score
            if score < protein.chain.score:
                # Reset times not improved
                times_not_improved = 0

                # Actual new best score
                if score < best_score:
                    print("new best score: ", end="")
                    print(score)
                    best_score = score
                    best_chain = copy.deepcopy(protein.chain.chain_list)

            # Score is same so not improved.
            else:
                times_not_improved += 1

            protein.chain.score = score

        # Chain is worse
        else:

            # If times not improved limit is reaced, continue with that chain anyway
            if times_not_improved >= times_not_improved_limit:
                protein.chain.score = score
                times_not_improved = 0

            # abandon that chain.
            else:
                protein.chain.chain_list = old_chain

    # Save the best score and chain in the protein
    protein.chain.chain_list = best_chain
    protein.matrix, protein.chain.chain_list = get_matrix(best_chain)