def depth_search_lookahead(protein, ch_score, max_lookahead): global best_chain global best_score chars = protein.amino_string chain_length_goal = len(chars) # The first char amino is build in the proteine class chars = chars [1:] # Skips the first char the index. while True: char = chars[0] # Get the location the last amino folded to. # Note: an index of -1 gets the last object in a list. amino_xy = protein.chain.chain_list[-1].get_fold_coordinates() # Last amino always has fold of 0. if protein.char_counter + 1 == len(protein.amino_string): fold = 0 # Determine which fold to pick. Ideal chain is returned as true if the full chain is already processed. # If ideal_chain is false, the next ideal fold is given. else: ideal_chain, fold = fold_selector(protein.chain, chars, max_lookahead, chain_length_goal, ch_score) # Ideal chain is already found, replace chain with ideal chain and break loop. if ideal_chain: protein.matrix, protein.chain.chain_list = get_matrix(best_chain) break # Adds amino to the protein chain. protein.chain.chain_list.append(Amino(char, fold, amino_xy)) protein.chain.update_mirror_status() print("Char " + str(len(protein.chain.chain_list)) +"/" + str(len(protein.amino_string)) + ". Beste score: " + str(best_score), file=sys.stdout) print("") # Pop the first char from the string. That one has been processed now chars = chars[1:] # Reset the best score and best chain best_score = 1 best_chain = [] # Update matrix and protein of the chain. Offset happens now. protein.matrix, protein.chain.chain_list = get_matrix(protein.chain.chain_list) best_score = 1 best_chain = []
def depth_search(protein, ch_score): char_counter = 1 # Skips the first char the index. while protein.char_counter < len(protein.amino_string): char = protein.amino_string[protein.char_counter] # Get the location the last amino folded to. # Note: an index of -1 gets the last object in a list. amino_xy = protein.chain.chain_list[-1].get_fold_coordinates() # Last amino always has fold of 0. if protein.char_counter + 1 == len(protein.amino_string): fold = 0 # Determine which fold to pick else: illegal_folds = None ideal_chain = fold_selector(amino_xy, char, protein.chain, illegal_folds, protein.amino_string, ch_score) # Ideal chain is already found, replace chain with ideal chain and break loop. if ideal_chain: protein.matrix, protein.chain.chain_list = get_matrix(best_chain) break # Adds amino to the protein chain. protein.chain.chain_list.append(Amino(char, fold, amino_xy)) char_counter += 1
def depth_search_iterative(protein, ch_score): char_counter = 1 # Build a matrix with dimensions of 2 * length of the protein +1 matrix_dimensions = 2 * len(protein.amino_string) + 1 for i in range(matrix_dimensions + 1): row = [] for j in range(matrix_dimensions + 1): row.append(" ") protein.chain.matrix.append(row) # Center the first amino's coordinates in the matrix and add it to the matrix. protein.chain.chain_list[0].coordinates = [ len(protein.amino_string) + 1, len(protein.amino_string) + 1 ] protein.chain.matrix[len(protein.amino_string) + 1][len(protein.amino_string) + 1] = protein.chain.chain_list[0] # Skips the first char the index. while protein.char_counter < len(protein.amino_string): char = protein.amino_string[protein.char_counter] # Get the location the last amino folded to. # Note: an index of -1 gets the last object in a list. amino_xy = protein.chain.chain_list[-1].get_fold_coordinates() # Last amino always has fold of 0. if protein.char_counter + 1 == len(protein.amino_string): fold = 0 # Determine which fold to pick else: illegal_folds = None ideal_chain = fold_selector(amino_xy, char, protein.chain, illegal_folds, protein.amino_string, ch_score) # Ideal chain is already found, replace chain with ideal chain and break loop. if ideal_chain: protein.matrix, protein.chain.chain_list = get_matrix(best_chain) break # Adds amino to the protein chain. protein.chain.chain_list.append(Amino(char, fold, amino_xy)) char_counter += 1
def build_straight_protein(protein): mode_3d = protein.mode_3d if mode_3d: protein.chain.chain_list[0].coordinates = [0, 0, 0] else: protein.chain.chain_list[0].coordinates = [0, 0] for index, char in enumerate(protein.amino_string): if index == 0: continue new_amino = Amino( char, 2, protein.chain.chain_list[index - 1].get_fold_coordinates()) protein.chain.chain_list.append(new_amino) protein.matrix, protein.chain.chain_list = get_matrix( protein.chain.chain_list)
def branch_and_bound_random(protein, ch_score, best_score_import, p1, p2): global best_score global p_below_average global p_above_average p_below_average = p1 p_above_average = p2 # Check if unsupported 3d mode. check_dimensions(protein.chain.chain_list) # You could import a score to start at (if you know the score to be at least that amount). best_score = best_score_import char_counter = 1 mode_3d = protein.mode_3d # Build up the partial energy list for every depth in the chain. global partial_energies partial_energies.append([]) for char in protein.amino_string: partial_energies.append([0, 0, 0]) if mode_3d: # Build a matrix with dimensions of 2 * length of the protein + 1. matrix_dimensions = 2 * len(protein.amino_string) + 1 for k in range(matrix_dimensions + 1): layer = [] for i in range(matrix_dimensions + 1): row = [] for j in range(matrix_dimensions + 1): row.append(" ") layer.append(row) protein.chain.matrix.append(layer) protein.chain.chain_list[0].coordinates = [ len(protein.amino_string) + 1, len(protein.amino_string) + 1, len(protein.amino_string) + 1 ] protein.chain.matrix[len(protein.amino_string) + 1][len(protein.amino_string) + 1][len(protein.amino_string) + 1] = protein.chain.chain_list[0] # 2D else: # Build a matrix with dimensions of 2 * length of the protein +1. matrix_dimensions = 2 * len(protein.amino_string) + 1 for i in range(matrix_dimensions + 1): row = [] for j in range(matrix_dimensions + 1): row.append(" ") protein.chain.matrix.append(row) # Center the first amino's coordinates in the matrix and add it to the matrix. protein.chain.chain_list[0].coordinates = [ len(protein.amino_string) + 1, len(protein.amino_string) + 1 ] protein.chain.matrix[len(protein.amino_string) + 1][len(protein.amino_string) + 1] = protein.chain.chain_list[0] # Perform all functions to add corrent spots. new_score, spots_to_add, spots_to_remove, spots_to_add_C, spots_to_remove_C = get_score_iterative_and_spots( protein.chain, protein.chain.matrix, 0) protein.chain.add_fold_spots(spots_to_add, "H") protein.chain.remove_fold_spots(spots_to_remove, "H") protein.chain.add_fold_spots(spots_to_add_C, "C") protein.chain.remove_fold_spots(spots_to_remove_C, "C") # Skips the first char the index. while protein.char_counter < len(protein.amino_string): char = protein.amino_string[protein.char_counter] # Get the location the last amino folded to. # Note: an index of -1 gets the last object in a list. amino_xy = protein.chain.chain_list[-1].get_fold_coordinates() # Last amino always has fold of 0. if protein.char_counter + 1 == len(protein.amino_string): fold = 0 # Determine which fold to pick. else: illegal_folds = None ideal_chain = fold_selector(amino_xy, char, protein.chain, illegal_folds, protein.amino_string, ch_score) # Ideal chain is already found, replace chain with ideal chain and break loop. if ideal_chain: protein.matrix, protein.chain.chain_list = get_matrix(best_chain) break # Adds amino to the protein chain. protein.chain.chain_list.append(Amino(char, fold, amino_xy)) char_counter += 1
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)
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)
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)
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)
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)
def branch_and_bound_lookahead(protein, ch_score, best_score_import, max_lookahead): global best_score global best_chain best_score = best_score_import mode_3d = is_chain_3d(chain) if mode_3d: matrix_dimensions = 2 * len(protein.amino_string) + 1 for k in range(matrix_dimensions + 1): layer = [] for i in range(matrix_dimensions + 1): row = [] for j in range(matrix_dimensions + 1): row.append(" ") layer.append(row) protein.matrix.append(layer) protein.chain.chain_list[0].coordinates = [len(protein.amino_string) + 1 , len(protein.amino_string) + 1, len(protein.amino_string) + 1] protein.chain.matrix[len(protein.amino_string) + 1][len(protein.amino_string) + 1][len(protein.amino_string) + 1] = protein.chain.chain_list[0] else: # Build a matrix with dimensions of 2 * length of the protein +1 matrix_dimensions = 2 * len(protein.amino_string) + 1 for i in range(matrix_dimensions + 1): row = [] for j in range(matrix_dimensions + 1): row.append(" ") protein.chain.matrix.append(row) # Center the first amino's coordinates in the matrix and add it to the matrix. protein.chain.chain_list[0].coordinates = [len(protein.amino_string) + 1 , len(protein.amino_string) + 1] protein.chain.matrix[len(protein.amino_string) + 1][len(protein.amino_string) + 1] = protein.chain.chain_list[0] new_score, spots_to_add, spots_to_remove, spots_to_add_C, spots_to_remove_C = get_score_iterative_and_spots(protein.chain, protein.chain.matrix, 0) protein.chain.add_fold_spots(spots_to_add, "H") protein.chain.add_fold_spots(spots_to_add_C, "C") current_score = 0 # Skips the first char the index. while protein.char_counter < len(protein.amino_string): # print(str(self.char_counter)) char = protein.amino_string[protein.char_counter] # Get the location the last amino folded to. # Note: an index of -1 gets the last object in a list. amino_xy = protein.chain.chain_list[-1].get_fold_coordinates() # Last amino always has fold of 0. if protein.char_counter + 1 == len(protein.amino_string): fold = 0 # Determine which fold to pick else: ideal_chain, fold = fold_selector(amino_xy, char, protein.chain, protein.amino_string[protein.char_counter - 1:], ch_score, max_lookahead, current_score) # Ideal chain is already found, replace chain with ideal chain and break loop. if ideal_chain: for amino in best_chain: print(amino) protein.matrix, protein.chain.chain_list = get_matrix(best_chain) break new_amino = Amino(char, fold, amino_xy) # Adds amino to the protein chain. protein.chain.chain_list.append(new_amino) protein.chain.update_mirror_status() if mode_3d: protein.chain.matrix[amino_xy[0]][amino_xy[1]][amino_xy[2]] = new_amino else: # Also add that amino to the matrix, and update the mirror starus protein.chain.matrix[amino_xy[0]][amino_xy[1]] = new_amino # Calculate new score and and/remove the correct fold spots new_score, spots_to_add, spots_to_remove, spots_to_add_C, spots_to_remove_C = get_score_iterative_and_spots(protein.chain, protein.chain.matrix, current_score) current_score = new_score # Remove the spots that are now filled by aminos. protein.chain.remove_fold_spots(spots_to_remove, "H") protein.chain.remove_fold_spots(spots_to_remove_C, "C") # Change odd/even protein.chain.odd = not protein.chain.odd # Add the spots that were newly created. if protein.chain.chain_list[-1].atype == "H": spots_to_add.append(protein.chain.chain_list[-1].get_fold_coordinates()) if protein.chain.chain_list[-1].atype == "C": spots_to_add_C.append(protein.chain.chain_list[-1].get_fold_coordinates()) protein.chain.add_fold_spots(spots_to_add, "H") protein.chain.add_fold_spots(spots_to_add_C, "C") protein.chain.get_max_possible_extra_score(protein.amino_string[protein.char_counter:]) protein.char_counter += 1 for amino in protein.chain.chain_list: print(amino, end='') print() best_chain = [] best_score = 1 current_lookahead = 0 print(protein.chain.available_bonds_odd_H) print(protein.chain.available_bonds_odd_C) print(protein.chain.available_bonds_even_H) print(protein.chain.available_bonds_even_C) protein.matrix, protein.chain.chain_list = get_matrix(protein.chain.chain_list)