def execute(input_chain, total_iterations, dimension): """This function takes as input an unfolded Amino_acid_chain object, folds it randomly 40 times, and returns the chain with the best score.""" # create new chain with sequence of input chain new_random_chain = AminoAcidChain.Amino_acid_chain(input_chain.sequence) for i in range (total_iterations): # fold random new chain and calculate stability score new_random_chain = helpers.fold_random(new_random_chain, dimension) new_random_chain.stability() # if score of new chain is higher than current input_chain if new_random_chain.score < input_chain.score: # fold input_chain like new chain and update score input_chain.chain = new_random_chain.chain input_chain.stability() # if score of best radom is still 0, fold like new_random_chain if input_chain.score == 0: input_chain.chain = new_random_chain.chain
# > Able to fold amino acid chains consisting of up to 14 amino acids (H / P) # --> first H/P chain (2D) # Runtime: aprox. 10 seconds # # imports from Classes import AminoAcidChain from collections import deque import copy import math import timeit # variables used for score checking best_chain = [] best_score = 0 new_acid_chain = AminoAcidChain.Amino_acid_chain("p") def execute(input, d, max_time): """Search for the best possible chain, utilizing the Depth-first method. If this takes more than 15 seconds, quit and return the best solution found. Keyword arguments: input -- the chain to work with (contains acid type and default coordinates, [0,0,0]). d -- determines the dimension to work in, 2D/3D. max_time -- determines how long the function is allowed to run. """ # initialize timer start = timeit.default_timer() # initialize input chain with starting coords
def execute(input_chain, start_point, iterations, dimension): """ Folds using simulated annealing, keeping chains only with a probability derived from exponential cooling schedule. Keyword arguments: input_chain -- the chain to work with (contains acid type and coordinates, [x, y, c] start_point -- the chain position with which to start making changes (straight-folded / random_folded) iterations -- the amount of changes this function will make (10000 recommended) dimension -- the dimension to fold chain in (2D / 3D)""" # parameters simulated annealing T_begin = 100 T_current = 0 T_end = 1 # initialize variables to store temporary acid chains new_acid_chain = AminoAcidChain.Amino_acid_chain(input_chain.sequence) rotated_acid_chain = AminoAcidChain.Amino_acid_chain(input_chain.sequence) best_acid_chain = AminoAcidChain.Amino_acid_chain(input_chain.sequence)\ if start_point == "straight_folded": # fold amino acid chain straight for i, acid in enumerate(new_acid_chain.chain): acid.coordinates = [i, 0, 0] elif start_point == "random_folded": new_acid_chain = helpers.fold_random(input_chain, dimension) new_acid_chain.stability() start_score = new_acid_chain.score current_iteration = 0 while current_iteration < iterations: # calculate current temperature using exponential cooling schedule T_current = T_begin * (T_end / T_begin) ** ((current_iteration * 1.5 ) / iterations) rotated_chain = new_acid_chain.rotate(dimension, 0) if rotated_chain == 1: # no possible rotations found, break out of loop break # set chain to new rotated_chain and update stability score rotated_acid_chain.chain = rotated_chain rotated_acid_chain.stability() cost = ((new_acid_chain.score) - rotated_acid_chain.score) acceptance_prob = math.e ** (cost / T_current) if random() < acceptance_prob: # set current chain to new chain and update stability score new_acid_chain.chain = rotated_chain new_acid_chain.stability() if acceptance_prob == 1: if random() < 0.5: # set current chain to new chain and update stability score new_acid_chain.chain = rotated_chain new_acid_chain.stability() # increase number of iterations with 1 current_iteration += 1 # print start_score to show whether hillclimber improved stability print("Start score:", start_score) # set input chain random folded chain with best score input_chain.chain = new_acid_chain.chain
def main(): if len(sys.argv) == 4: dimension = sys.argv[1].lower() algorithm = sys.argv[2].lower() sequence = sys.argv[3].lower() if dimension != "2d" and dimension != "3d": sys.exit( "\nUsage: application.py dimension algorithm HHPHHHPHPHHHPH/CHPHCHPHCHHCPH\n" "dimension: 2D/3D\nalgorithms: Random / Breadth / Breadth_heur / Depth / Depth_hill / Hillclimber / RandomHillclimber / Simulatedannealing / RandomSimulatedannealing\n" ) # if iterative algorithm, ask user to input number of iterations if (algorithm == "hillclimber" or algorithm == "randomhillclimber" or algorithm == "simulatedannealing" or algorithm == "randomsimulatedannealing" or algorithm == "random"): iterations = helpers.ask_for_iterations(algorithm) elif algorithm == "depth": algorithm = helpers.ask_for_hillclimbing() elif len(sys.argv) > 1: sys.exit( "\nUsage: application.py dimension algorithm HHPHHHPHPHHHPH/CHPHCHPHCHHCPH\n" "dimension: 2D/3D\nalgorithms: Random / Breadth / Breadth_heur / Depth / Depth_hill / Hillclimber / RandomHillclimber / Simulatedannealing / RandomSimulatedannealing\n" ) else: app = GuiApplication.Gui_Application() app.run("csv", "sequences.csv") specs = app.specs() sequence = specs["sequence"] algorithm = specs["algorithm"] dimension = specs["dimension"] if (algorithm == "hillclimber" or algorithm == "randomhillclimber" or algorithm == "simulatedannealing" or algorithm == "randomsimulatedannealing" or algorithm == "random"): iterations = specs["iterations"] # initialize timer start = timeit.default_timer() # create AminoAcidChain object amino_acid_chain = AminoAcidChain.Amino_acid_chain(sequence) # set x and y coordinates of the aminoacids of chain, depending on the algorithm if algorithm == "random": random_algorithm.execute(amino_acid_chain, iterations, dimension) # breadth-first elif algorithm == "breadth": breadth_algorithm.execute(amino_acid_chain, dimension) # breadth-first with heuristics elif algorithm == "breadth_heur": breadth_heur_algorithm.execute(amino_acid_chain, dimension) # depth-first elif algorithm == "depth" or algorithm == "depth_hill": max_duration = 15 finished = depth_algorithm.execute(amino_acid_chain, dimension, max_duration) if algorithm == "depth_hill" and finished == False: amino_acid_chain.stability() print("Performing hillclimber.. Current score: ", amino_acid_chain.score) hillclimber_algorithm.execute(amino_acid_chain, "dept_chain", 1000, dimension) # hillclimber elif algorithm == "hillclimber": hillclimber_algorithm.execute(amino_acid_chain, "straight_folded", iterations, dimension) # hillclimber with random start elif algorithm == "randomhillclimber": hillclimber_algorithm.execute(amino_acid_chain, "random_folded", iterations, dimension) # simulated annealing elif algorithm == "simulatedannealing": simulated_annealing.execute(amino_acid_chain, "straight_folded", iterations, dimension) # simulated annealing with random start elif algorithm == "randomsimulatedannealing": simulated_annealing.execute(amino_acid_chain, "random_folded", iterations, dimension) # invalid commandline arg else: sys.exit( "\nUsage: application.py dimension algorithm HHPHHHPHPHHHPH/CHPHCHPHCHHCPH\n" "dimension: 2D/3D\nalgorithms: Random / Breadth / Breadth_heur / Depth / Depth_hill / Hillclimber / RandomHillclimber / Simulatedannealing / RandomSimulatedannealing\n" ) # stop timer stop = timeit.default_timer() print("Runtime:", (stop - start)) # calculate chains stability score amino_acid_chain.stability() print("Score:", (amino_acid_chain.score)) # plot the "folded" aminoacid chain amino_acid_chain.plot(dimension)
def execute(input_chain, start_point, iterations, dimension): """Folds using hillclimber, keeping new chains only if score is equal or better than old chain. Keyword arguments: input_chain -- the chain to work with (contains acid type and coordinates, [x, y, z]) start_point -- the chain position with which to start making changes (straight-folded / random-folded / after depth-first) iterations -- the amount of changes this function will make (1000 recommended) dimension -- the dimension to fold chain in (2D / 3D)""" # initialize variables to store temporary acid chains new_acid_chain = AminoAcidChain.Amino_acid_chain(input_chain.sequence) rotated_acid_chain = AminoAcidChain.Amino_acid_chain(input_chain.sequence) best_acid_chain = AminoAcidChain.Amino_acid_chain(input_chain.sequence) # fold new_acid_chain accordinly based on input (start_point) if start_point == "straight_folded": # fold amino acid chain straight for i, acid in enumerate(new_acid_chain.chain): acid.coordinates = [i, 0, 0] elif start_point == "random_folded": # fold amino acid chain randomly new_acid_chain = helpers.fold_random(input_chain, dimension) elif start_point == "dept_chain": # set new amino acid chain to input_chainm (depth-first output) new_acid_chain = copy.deepcopy(input_chain) scores = [] current_iteration = 0 # score of current new_acid_chain is the start score new_acid_chain.stability() start_score = new_acid_chain.score while current_iteration < iterations: rotated_chain = new_acid_chain.rotate(dimension, 0) if rotated_chain == 1: print("no possible rotations found at iteration nr", current_iteration) # no possible rotations found, break out of loop break # set chain to new rotated_chain and update stability score rotated_acid_chain.chain = rotated_chain rotated_acid_chain.stability() # if new score is lower than current score if rotated_acid_chain.score <= new_acid_chain.score: # set current chain to new chain and update stability score new_acid_chain.chain = rotated_chain new_acid_chain.stability() # increase number of current_iteration with 1 current_iteration += 1 else: # else, increase number of current_iteration with 1 current_iteration += 1 # print start_score to show whether hillclimber improved stability print("Start score:", start_score) # set input chain random folded chain with best score input_chain.chain = new_acid_chain.chain
def fold_random(input_chain, dimension): """Folds input_chain randomly. Keyword arguments: input_chain -- the chain to work with (of class AminoAcidChain.Amino_acid_chain, containing acid type and default coordinates, [0, 0, 0]). dimension -- the dimension in which this function should fold (2D / 3D)""" # create AminoAcidChain.Amino_acid_chain class to store random folded amino_acid output_chain = AminoAcidChain.Amino_acid_chain(input_chain.sequence) # iterate over each aminoacid for i in range(1, len(input_chain.chain)): # remember coordinates of previous amino acid x = output_chain.chain[i - 1].coordinates[0] y = output_chain.chain[i - 1].coordinates[1] z = output_chain.chain[i - 1].coordinates[2] # create array containing possible positions options = [[x + 1, y, z], [x - 1, y, z], [x, y + 1, z], [x, y - 1, z]] # add more options if dimension is 3D if dimension == "3d": options.append([x, y, z + 1]) options.append([x, y, z - 1]) # keep track of (the amount of) conflicts conflict = True conflicts = 0 while conflict: # if conflicts more than 20, chain is probably stuck, break if conflicts >= 20: conflict = False break # randomly choose one of the possible positions option = randint(0, len(options) - 1) coordinates = options[option] # iterate over all previously positioned amino acids for j in range(0, i): # if coordinates match, break to choose new coordinates if coordinates == output_chain.chain[j].coordinates: conflict = True conflicts += 1 break # if none of the previous coordinates match, break out of while loop else: conflict = False if conflicts < 20: # set coordinates of current amino acid output_chain.chain[i].coordinates = coordinates else: break #if chain stuck in conflict, set coordinates back and fold again if conflicts >= 20: output_chain = fold_random(input_chain, dimension) return output_chain