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 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 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 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)