def main(seed, exp_no, run_specs, test_set): # set the randomized seed for experimentation duplication random.seed(seed) # set experiment number experiment = exp_no # assign the test set for GP test_set = test_set # sets the specs for the run POP = run_specs['pop_size'] GENS = run_specs['gens'] HOF_SIZE = run_specs['hof_size'] CROSS_PROB = run_specs['cross_prob'] MUT_PROB = 1.0 IND_MUT_PROB = run_specs['mut_rate'] SELECTOR = run_specs['selector'] ELITISM = run_specs['elitism'] alg = run_specs['algorithm'] REC_FITS = run_specs['rec_fits'] SEEDED = run_specs['seeded_pop'] # sets hof and fs on/off FS = run_specs['FS'] HOF = run_specs['HOF'] """____SET UP ANY LISTS FOR TRACKING DATA HERE___""" stats_rel_b = [] stats_bgp_b = [] stats_agp_b = [] stats_rel_r = [] stats_bgp_r = [] stats_agp_r = [] # set evolutionary operators toolbox.register("mutate", helpers.gaussian, mu=0, sigma=1.0, indpb=IND_MUT_PROB) toolbox.register("mate", tools.cxOnePoint) toolbox.register("evaluate", helpers.evaluate) if SELECTOR == 'SUS': toolbox.register("select", helpers.selStochasticUniversalSampling) elif SELECTOR == 'RANKED': toolbox.register("select", helpers.selRanked) # create gene templates toolbox.register("turn_range", Gene, min_turn_range, max_turn_range) toolbox.register("turn_angle", Gene, min_turn_angle, max_turn_angle) toolbox.register("desired_displ", Gene, min_displ, max_displ) toolbox.register("conv_range", Gene, min_conv_range, max_conv_range) toolbox.register("no_closer_range", Gene, min_closer_range, max_closer_range) # create chromosome template toolbox.register( "tactic", tools.initCycle, creator.Tactic, (toolbox.turn_range, toolbox.turn_angle, toolbox.desired_displ, toolbox.conv_range, toolbox.no_closer_range), n=CYCLES) # create population template toolbox.register("population", tools.initRepeat, list, toolbox.tactic, POP) # create the population initializer toolbox.register("population", tools.initRepeat, list, toolbox.tactic, POP) """<------------------------------------- START ---------------------------------------->""" if SEEDED == 1: print " no seeded pop" else: # initialize populations blue_pop = toolbox.population() red_pop = toolbox.population() # initialize hall of fame blue_hof = hof.HallOfFame(HOF_SIZE) red_hof = hof.HallOfFame(HOF_SIZE) # get working folder for this set of runs folder_string = run_specs['folder'] # Make new folder for experiemnt results save_path = os.getcwd() sub_folder_string = folder_string + str(exp_no) + '_Seed_' + str( seed) + '/' folder = os.path.join(save_path, sub_folder_string) if not os.path.isdir(folder): os.makedirs(folder) # create out file text_file = sub_folder_string + 'results.txt' sys.stdout = open(text_file, 'w') # reset random seed to clock time algseed = datetime.now() random.seed(algseed) algseed = random.randint(0, 10001) random.seed(algseed) print 'Algorithm seed: ', algseed # create csv writer and file for fitness and initial/final population output csv_fits = sub_folder_string + 'relative_fitness.csv' fits = open(csv_fits, 'ab') fit_writer = csv.writer(fits) # csv writer for outputting all fitnesses of blue population blue_pop_fits = sub_folder_string + 'blue_all_fits.csv' blue_fits_file = open(blue_pop_fits, 'ab') blue_fits_writer = csv.writer(blue_fits_file) # do the same for red ^^^ red_pop_fits = sub_folder_string + 'red_all_fits.csv' red_fits_file = open(red_pop_fits, 'ab') red_fits_writer = csv.writer(red_fits_file) blue_gp = sub_folder_string + 'blue_gp.csv' blue_gp_file = open(blue_gp, 'ab') blue_gp_writer = csv.writer(blue_gp_file) blue_gp_writer.writerow(['best', 'avg']) blue_chromosomes = sub_folder_string + 'blue_best.txt' blue_best_file = open(blue_chromosomes, 'w') red_gp = sub_folder_string + 'red_gp.csv' red_gp_file = open(red_gp, 'ab') red_gp_writer = csv.writer(red_gp_file) red_gp_writer.writerow(['best', 'avg']) red_chromosomes = sub_folder_string + 'red_best.txt' red_best_file = open(red_chromosomes, 'w') print "<-----INITIAL BLUE----->" for b, ind in enumerate(blue_pop): print "Chromosome ", str(b), ': ' print helpers.list_to_string(ind) print "<-----INITIAL RED----->" for r, ind in enumerate(red_pop): print "Chromosome ", str(r), ': ' print helpers.list_to_string(ind) # create csv writer and file for GP data # csv_fits = sub_folder_string + 'Gen_performance.csv' # gp = open(csv_fits, 'ab') # gp_writer = csv.writer(gp) # set up headings for graph csv fit_writer.writerow( ('Generation', 'BestB', 'AvgB', 'WorstB', 'BestR', 'AvgR', 'WorstR')) # set up GP headings # gp_writer.writerow(('Generation', 'BestB_GP', 'AvgB_GP', 'BestR_GP', 'AvgR_GP')) print( '-------------------------------------Stats----------------------------------------' ) print 'Seed: ', seed print 'Selection: ', SELECTOR print("Pop size: " + str(POP)) print("Generations: " + str(GENS)) print("Crossover Prob: " + str(CROSS_PROB)) print("Mutation Prob: " + str(IND_MUT_PROB)) print 'Elitism: ', ELITISM print 'Hall of Fame: ', HOF print 'Fitness Sharing: ', FS print 'Algorithm: ', alg i = 0 while i <= GENS: i += 1 print('--------------------------------' + 'Generation: ' + str(i) + '-----------------------------------') """ ----------------------------------- EVALUATE THE POPULATIONS --------------------------------------- """ # Reset fitness scores to zero so they can be accumulated each generation for index, x in enumerate(blue_pop): x.fitness.values = (0.0, ) for index, y in enumerate(red_pop): y.fitness.values = (0.0, ) """<----------RELATIVE FITNESS EVALUATIONS--------->""" # Evaluate the populations and return with summed fitness scores of all engagements # THIS FITNESS SCORE NEEDS TO BE AVERAGED AFTER HOF EVALS blue_pop, red_pop = helpers.sum_pop_v_pop_evals(blue_pop, red_pop) """<----------HALL OF FAME EVALUATIONS--------->""" # check hof not empty, if not, loop through and evaluate # Only if HOF is turned on if HOF == 1: if len(red_hof) != 0: blue_pop = helpers.sum_pop_v_hof_evals(blue_pop, red_hof) if len(blue_hof) != 0: red_pop = helpers.sum_pop_v_hof_evals(red_pop, blue_hof) """<-------AVERAGE THE FITNESS SCORES------>""" # average the accumulated fitness scores by size of population and also output fitnesses to csv blue_fits_row = [] blue_fits_row.append(i) for index, x in enumerate(blue_pop): if HOF == 1: x.fitness.values = (x.fitness.values[0] / (POP + len(red_hof)), ) else: x.fitness.values = (x.fitness.values[0] / POP, ) blue_fits_row.append(x.fitness.values[0]) red_fits_row = [] red_fits_row.append(i) for index, y in enumerate(red_pop): if HOF == 1: y.fitness.values = (y.fitness.values[0] / (POP + len(blue_hof)), ) else: y.fitness.values = (y.fitness.values[0] / POP, ) red_fits_row.append(y.fitness.values[0]) if REC_FITS == 1: blue_fits_writer.writerow(blue_fits_row) red_fits_writer.writerow(red_fits_row) """------------GET BEST---------------------""" blue_best_file.write("<------------ GEN " + str(i) + "--------------->\n") red_best_file.write("<------------ GEN " + str(i) + "--------------->\n") best_blue = tools.selBest(blue_pop, 5) best_red = tools.selBest(red_pop, 5) for index, b in enumerate(best_blue): blue_best_file.write("Chromsome [" + str(index) + "]: " + "(" + str(b.fitness.values[0]) + ")" + helpers.list_to_string(b) + "\n") for index, r in enumerate(best_red): red_best_file.write("Chromsome [" + str(index) + "]: " + "(" + str(r.fitness.values[0]) + ")" + helpers.list_to_string(r) + "\n") """ <---------------- Gen Perf ---------------->""" # cloned so the GP can be calculated without wiping relative scores blue_copy = list(map(toolbox.clone, best_blue)) red_copy = list(map(toolbox.clone, best_red)) # Reset fitness scores to zero so they can be accumulated each generation for index, x in enumerate(blue_copy): x.fitness.values = (0.0, ) for index, y in enumerate(red_copy): y.fitness.values = (0.0, ) blue_copy = helpers.sum_pop_v_hof_evals(blue_copy, test_set) red_copy = helpers.sum_pop_v_hof_evals(red_copy, test_set) sum_gp_b = 0.0 sum_gp_r = 0.0 for index_x, x in enumerate(blue_copy): x.fitness.values = (x.fitness.values[0] / len(test_set), ) sum_gp_b += x.fitness.values[0] for index_y, y in enumerate(red_copy): y.fitness.values = (y.fitness.values[0] / len(test_set), ) sum_gp_r += y.fitness.values[0] avg_gp_b = sum_gp_b / len(blue_copy) avg_gp_r = sum_gp_r / len(red_copy) best_gp_b = tools.selBest(blue_copy, 1)[0].fitness.values[0] best_gp_r = tools.selBest(red_copy, 1)[0].fitness.values[0] blue_gp_writer.writerow([best_gp_b, avg_gp_b]) red_gp_writer.writerow([best_gp_r, avg_gp_r]) del blue_copy del red_copy """<----------OUTPUT INFO TO TEXT FILE---------->""" # BLUE best_blue_ind = tools.selBest(blue_pop, 1)[0] print 'Best Blue fitness score: ', best_blue_ind.fitness.values[0] print 'Best blue chromosome: ', helpers.list_to_string(best_blue_ind) worst_blue_ind = tools.selWorst(blue_pop, 1)[0] print "Worst Blue fitness: ", worst_blue_ind.fitness.values[0] print "Worst Blue chromosome: ", helpers.list_to_string(worst_blue_ind) # get the average fitness of the generation sum_fits = sum(ind.fitness.values[0] for ind in blue_pop) avg_blue_fitness = sum_fits / POP print "Generation average Blue fitness: ", avg_blue_fitness # RED # get best chromosome and output best_red_ind = tools.selBest(red_pop, 1)[0] print "Best Red fitness: ", best_red_ind.fitness.values[0] print 'Best Red chromosome: ', helpers.list_to_string(best_red_ind) # get worst and display worst_red_ind = tools.selWorst(red_pop, 1)[0] print "Worst Red fitness: ", worst_red_ind.fitness.values[0] print "Worst Red chromosome: ", helpers.list_to_string(worst_red_ind) # get the average fitness of the generation sum_fits = sum(ind.fitness.values[0] for ind in red_pop) avg_red_fitness = sum_fits / POP print "Generation average red fitness: ", avg_red_fitness # Write best avg & worst to fits_csv fit_writer.writerow( (i, best_blue_ind.fitness.values[0], avg_blue_fitness, worst_blue_ind.fitness.values[0], best_red_ind.fitness.values[0], avg_red_fitness, worst_red_ind.fitness.values[0])) # if i % 5 == 0 or i == 1: # # Fill the dictionary using the dict(key=value[, ...]) constructor # cp = dict(population=blue_pop, generation=i, rndstate=random.getstate()) # # with open(sub_folder_string + "zgeneration" + str(i) + ".pkl", "wb") as cp_file: # cPickle.dump(cp, cp_file) stats_rel_b.append(best_blue_ind.fitness.values[0]) stats_bgp_b.append(best_gp_b) stats_agp_b.append(avg_gp_b) stats_rel_r.append(best_red_ind.fitness.values[0]) stats_bgp_r.append(best_gp_r) stats_agp_r.append(avg_gp_r) if i > 10: stats_rel_b.pop(0) stats_bgp_b.pop(0) stats_agp_b.pop(0) stats_rel_r.pop(0) stats_bgp_r.pop(0) stats_agp_r.pop(0) # if i > GENS-10: # stats_rel_b.append(best_blue_ind.fitness.values[0]) # stats_bgp_b.append(best_gp_b) # stats_agp_b.append(avg_gp_b) # stats_rel_r.append(best_red_ind.fitness.values[0]) # stats_bgp_r.append(best_gp_r) # stats_agp_r.append(avg_gp_r) if i == GENS: break """<------------HALL OF FAME UPDATE----------->""" blue_hof.update(tools.selBest(blue_pop, 1), i) red_hof.update(tools.selBest(red_pop, 1), i) """<--------------------BEGIN EVOLUTION------------------>""" # Select offspring for next generation if ELITISM == 1: blue_offspring = toolbox.select(blue_pop, POP - 1, POP) red_offspring = toolbox.select(red_pop, POP - 1, POP) else: blue_offspring = toolbox.select(blue_pop, POP, POP) red_offspring = toolbox.select(red_pop, POP, POP) # Clone the offspring so we can evolve blue_offspring = list(map(toolbox.clone, blue_offspring)) red_offspring = list(map(toolbox.clone, red_offspring)) random.shuffle(blue_offspring) random.shuffle(red_offspring) # CROSSOVER blue_cross_count = 0 # Blue for child1, child2 in zip(blue_offspring[::2], blue_offspring[1::2]): if random.random() < CROSS_PROB: # MATE toolbox.mate(child1, child2) blue_cross_count += 1 # Red red_cross_count = 0 for child1, child2 in zip(red_offspring[::2], red_offspring[1::2]): if random.random() < CROSS_PROB: # MATE toolbox.mate(child1, child2) red_cross_count += 1 print "blue crossover count: ", str(blue_cross_count) print "red crossover count: ", str(red_cross_count) # MUTATION for mutant in blue_offspring: if random.random() < MUT_PROB: # MUTATE for index, x in enumerate(mutant): mutant[index].value = helpers.convert_range( mutant[index].value, mutant[index].min, mutant[index].max) toolbox.mutate(mutant) for index, x in enumerate(mutant): mutant[index].value = helpers.change_back( mutant[index].value, mutant[index].min, mutant[index].max) helpers.bounds_check(mutant[index]) for mutant in red_offspring: if random.random() < MUT_PROB: # MUTATE for index, x in enumerate(mutant): mutant[index].value = helpers.convert_range( mutant[index].value, mutant[index].min, mutant[index].max) toolbox.mutate(mutant) for index, x in enumerate(mutant): mutant[index].value = helpers.change_back( mutant[index].value, mutant[index].min, mutant[index].max) helpers.bounds_check(mutant[index]) if ELITISM == 1: elite_blue = toolbox.clone(tools.selBest(blue_pop, 1)) elite_red = toolbox.clone(tools.selBest(red_pop, 1)) blue_offspring += elite_blue red_offspring += elite_red # REPLACE blue_pop[:] = blue_offspring red_pop[:] = red_offspring print( '-------------------------------------Hall Of Fame Regular----------------------------------------' ) print "BLUE: " # for chromosomes in blue_hof: # print 'Chromosome: ', helpers.list_to_string(chromosomes), 'Fitness: ', chromosomes.fitness.values if len(blue_hof) != 0: blue_hof.print_hof() print "RED: " # for chromosomes in red_hof: # print 'Chromosome: ', helpers.list_to_string(chromosomes), 'Fitness: ', chromosomes.fitness.values if len(red_hof) != 0: red_hof.print_hof() print "Generation ", i, " complete." print( '-------------------------------------Hall Of Fame Regular----------------------------------------' ) print "BLUE: " # for chromosomes in blue_hof: # print 'Chromosome: ', helpers.list_to_string(chromosomes), 'Fitness: ', chromosomes.fitness.values if len(blue_hof) != 0: blue_hof.print_hof() print "RED: " # for chromosomes in red_hof: # print 'Chromosome: ', helpers.list_to_string(chromosomes), 'Fitness: ', chromosomes.fitness.values if len(red_hof) != 0: red_hof.print_hof() print( '-------------------------------------Stats----------------------------------------' ) print 'Seed: ', seed print 'Selection: ', SELECTOR print("Pop size: " + str(POP)) print("Generations: " + str(GENS)) print("Crossover Prob: " + str(CROSS_PROB)) print("Mutation Prob: " + str(IND_MUT_PROB)) print 'Elitism: ', ELITISM print 'Hall of Fame: ', HOF print 'Fitness Sharing: ', FS print 'Algorithm: ', alg fits.close() blue_fits_file.close() red_fits_file.close() red_best_file.close() blue_best_file.close() blue_gp_file.close() red_gp_file.close() stats = [ seed, sum(stats_rel_b) / 10, sum(stats_bgp_b) / 10, sum(stats_agp_b) / 10, sum(stats_rel_r) / 10, sum(stats_bgp_r) / 10, sum(stats_agp_r) / 10 ] # stats = {"blue_est_avg_gp": blue_est_avg_gp, "blue_est_best_gp": blue_est_best_gp, # "red_est_avg_gp": red_est_avg_gp, "red_est_best_gp": red_est_best_gp} return stats
def run_algorithm(self, seed): # Set up hall of fame to keep track of the top chromosomes # custom hall of fame to track the generation it was found hall_of_fame = hof.HallOfFame(self.HOF_SIZE) # standard hall of fame that comes with DEAP hall_of_fame_with_dupes = hof.HallOfFameStandard(self.HOF_SIZE) # write out all text to a file file_name = str(seed) + '_with_HOF.txt' sys.stdout = open(file_name, 'w') print 'Seed:', seed # track the current generation i = 0 while i < self.GENERATIONS and not self.isConverged: i += 1 print('--------------------------------' + 'Generation: ' + str(i) + '-----------------------------------') # evaluate each chromosome in the population and assign its fitness score for index, x in enumerate(self.population): # update the chromosome, writes out to JSON tactics file chromosome_parameters.update_ecu_basic_chromosome(x) # use Ace0 to evaluate the chromosome x.fitness.values = helper.multi_evaluate(self.num_of_processors) # Select the best chromosome from this generation and display it best_chromosome = tools.selBest(self.population, 10)[0] print "Best chromosome is: ", best_chromosome.fitness.values # check if the best chromosome value has changed if float(best_chromosome.fitness.values[0]) == self.temp_best_fitness: self.converge_tracker_2 += 1 if self.converge_tracker_2 >= self.converge_stagnant_fitness: print 'CONVERGED due to stagnant fit' self.isConverged = True else: self.converge_tracker_2 = 0 self.temp_best_fitness = best_chromosome.fitness.values[0] # Get the over all fitness values sum_fits = sum(ind.fitness.values[0] for ind in self.population) average_fitness = sum_fits / self.POP print 'Generation average fitness: ', average_fitness csv_name = str(seed) + '_output.csv' f = open(csv_name, 'ab') writer = csv.writer(f) writer.writerow((str(i), str(best_chromosome.fitness.values[0]), str(average_fitness))) f.close() # save best and average fitness to plot lists self.plot_best_fitness.append(best_chromosome.fitness.values) self.plot_average_fitness.append(average_fitness) # Update the hall of fame to track the best chromosomes from each generation hall_of_fame.update(self.population, i) hall_of_fame_with_dupes.update(self.population) print ('-----------------------------------Hall Of Fame at Gen ' + str(i) + '-----------------------------------') hall_of_fame.print_hof() # this is where we evolve the population # Select the next generation individuals offspring = self.toolbox.select(self.population, len(self.population)) # Clone the selected individuals so we can apply crossover offspring = list(map(self.toolbox.clone, offspring)) # Apply crossover on the offspring for child1, child2 in zip(offspring[::2], offspring[::-2]): if random.random() < self.CROSSOVER_PROBABILITY: # mate the two children self.toolbox.mate(child1, child2) # Apply mutation on the offspring for mutant in offspring: if random.random() < self.MUTATION_PROBABILITY: for index, x in enumerate(mutant): mutant[index].value = helper.convert_range(mutant[index].value, mutant[index].min, mutant[index].max) self.toolbox.mutate(mutant) for index, x in enumerate(mutant): mutant[index].value = helper.change_back(mutant[index].value, mutant[index].min, mutant[index].max) # check if the mutated value is outside the min/max helper.bounds_check(mutant[index]) # The population is entirely replaced by the offspring self.population[:] = offspring # check to see if the avg fitness is the same as the best fitness if float(best_chromosome.fitness.values[0]) - average_fitness < 0.0001: self.converge_tracker += 1 if self.converge_tracker >= self.converge_tracker_max: print 'CONVERGED due to best = avg' self.isConverged = True else: self.converge_tracker = 0 # elitism, carry over the best chromosome from this generation self.population[0] = hall_of_fame[0] # print the hall of fame to file so we can access the chromosomes print ('-------------------------------------Hall Of Fame Regular----------------------------------------') for chromosomes in hall_of_fame_with_dupes: print 'Chromosome: ', helper.list_to_string(chromosomes), 'Fitness: ', chromosomes.fitness print ('-------------------------------------Hall Of Fame with Gen----------------------------------------') hall_of_fame.print_hof() title = 'Seed: ' + str(seed) # save the chart to an image file visualization.draw_plot(title, self.plot_average_fitness, self.plot_best_fitness, 'average per generation', 'best fitness', 'average per generation', 'best fitness', 0, 250, 150, seed) # delete the created objects so we can loop and automate the GA process for many seeds del creator.fitness del creator.Tactic
def main(seed, exp_no, run_specs, test_set): # set the randomized seed for experimentation duplication random.seed(seed) # set experiment number experiment = exp_no # assign the test set for GP test_set = test_set # sets the specs for the run POP = run_specs['pop_size'] GENS = run_specs['gens'] HOF_SIZE = run_specs['hof_size'] CROSS_PROB = run_specs['cross_prob'] MUT_PROB = 1.0 IND_MUT_PROB = run_specs['mut_rate'] SELECTOR = run_specs['selector'] ELITISM = run_specs['elitism'] alg = run_specs['algorithm'] REC_FITS = run_specs['rec_fits'] SEEDED = run_specs['seeded_pop'] # sets hof and fs on/off FS = run_specs['FS'] HOF = run_specs['HOF'] """____SET UP ANY LISTS FOR TRACKING DATA HERE___""" plot_best_fitness = [] plot_average_fitness = [] plot_worst_fitness = [] blue_est_best_gp = [] red_est_best_gp = [] blue_est_avg_gp = [] red_est_avg_gp = [] # set evolutionary operators toolbox.register("mutate", helpers.gaussian, mu=0, sigma=0.2, indpb=IND_MUT_PROB) toolbox.register("mate", tools.cxOnePoint) toolbox.register("evaluate", helpers.evaluate) if SELECTOR == 'SUS': toolbox.register("select", tools.selStochasticUniversalSampling) elif SELECTOR == 'RANKED': toolbox.register("select", helpers.selRanked) # Initialise all the gene's to be used in the chromosome. toolbox.register("px_min", Gene, MIN_DISTANCE, MAX_DISTANCE, True) toolbox.register("px_max", Gene, MIN_DISTANCE, MAX_DISTANCE, False) toolbox.register("py_min", Gene, MIN_DISTANCE, MAX_DISTANCE, True) toolbox.register("py_max", Gene, MIN_DISTANCE, MAX_DISTANCE, False) toolbox.register("pz_min", Gene, MIN_DISTANCE, MAX_DISTANCE, True) toolbox.register("pz_max", Gene, MIN_DISTANCE, MAX_DISTANCE, False) toolbox.register("vx_min", Gene, MIN_VELOCITY, MAX_VELOCITY, True) toolbox.register("vx_max", Gene, MIN_VELOCITY, MAX_VELOCITY, False) toolbox.register("vy_min", Gene, MIN_VELOCITY, MAX_VELOCITY, True) toolbox.register("vy_max", Gene, MIN_VELOCITY, MAX_VELOCITY, False) toolbox.register("vz_min", Gene, MIN_VELOCITY, MAX_VELOCITY, True) toolbox.register("vz_max", Gene, MIN_VELOCITY, MAX_VELOCITY, False) toolbox.register("ax_min", Gene, MIN_ACCEL, MAX_ACCEL, True) toolbox.register("ax_max", Gene, MIN_ACCEL, MAX_ACCEL, False) toolbox.register("ay_min", Gene, MIN_ACCEL, MAX_ACCEL, True) toolbox.register("ay_max", Gene, MIN_ACCEL, MAX_ACCEL, False) toolbox.register("az_min", Gene, MIN_ACCEL, MAX_ACCEL, True) toolbox.register("az_max", Gene, MIN_ACCEL, MAX_ACCEL, False) # Initialize the structure of the chromosome # Sets tactic as a Tactic object and populates it with genes from gene template toolbox.register( "tactic", tools.initCycle, creator.Tactic, (toolbox.px_min, toolbox.px_max, toolbox.py_min, toolbox.py_max, toolbox.pz_min, toolbox.pz_max, toolbox.vx_min, toolbox.vx_max, toolbox.vy_min, toolbox.vy_max, toolbox.vz_min, toolbox.vz_max, toolbox.ax_min, toolbox.ax_max, toolbox.ay_min, toolbox.ay_max, toolbox.az_min, toolbox.az_max), n=CYCLES) # create the population initializer toolbox.register("population", tools.initRepeat, list, toolbox.tactic, POP) """<------------------------------------- START ---------------------------------------->""" if SEEDED == 1: blue_pop = pop_init.run() red_pop = pop_init.run() # Load the test set from the pickle file # with open("biased_blue_pop.pkl", "r") as cp_file: # cp = cPickle.load(cp_file) # blue_pop = cp["population"] # with open("biased_red_pop.pkl", "r") as cp_file: # cp = cPickle.load(cp_file) # red_pop = cp["population"] else: # initialize populations blue_pop = toolbox.population() red_pop = toolbox.population() # initialize hall of fame blue_hof = hof.HallOfFame(HOF_SIZE) red_hof = hof.HallOfFame(HOF_SIZE) # reset random seed to clock time algseed = datetime.now() random.seed(algseed) algseed = random.randint(0, 1001) random.seed(algseed) print 'Algorithm seed: ', algseed # get working folder for this set of runs folder_string = run_specs['folder'] # Make new folder for experiemnt results save_path = os.getcwd() sub_folder_string = folder_string + str(exp_no) + '_Seed_' + str( seed) + '/' folder = os.path.join(save_path, sub_folder_string) if not os.path.isdir(folder): os.makedirs(folder) # create out file text_file = sub_folder_string + 'results.txt' sys.stdout = open(text_file, 'w') # create csv writer and file for fitness and initial/final population output csv_fits = sub_folder_string + 'relative_fitness.csv' fits = open(csv_fits, 'ab') fit_writer = csv.writer(fits) # create csv writer and file for detailed results for graph output # csv_pops = sub_folder_string + 'populations.csv' # pops = open(csv_pops, 'ab') # pops_writer = csv.writer(pops) # csv writer for outputting all fitnesses of blue population blue_pop_fits = sub_folder_string + 'blue_all_fits.csv' blue_fits_file = open(blue_pop_fits, 'ab') blue_fits_writer = csv.writer(blue_fits_file) # do the same for red ^^^ red_pop_fits = sub_folder_string + 'red_all_fits.csv' red_fits_file = open(red_pop_fits, 'ab') red_fits_writer = csv.writer(red_fits_file) # create csv writer and file for GP data csv_fits = sub_folder_string + 'Gen_performance.csv' gp = open(csv_fits, 'ab') gp_writer = csv.writer(gp) # set up headings for graph csv fit_writer.writerow( ('Generation', 'BestB', 'AvgB', 'WorstB', 'BestR', 'AvgR', 'WorstR')) # set up GP headings gp_writer.writerow( ('Generation', 'BestB_GP', 'AvgB_GP', 'BestR_GP', 'AvgR_GP')) print 'Seed: ', seed i = 0 while i <= GENS: i += 1 print('--------------------------------' + 'Generation: ' + str(i) + '-----------------------------------') """ ----------------------------------- EVALUATE THE POPULATIONS --------------------------------------- """ # Reset fitness scores to zero so they can be accumulated each generation for index, x in enumerate(blue_pop): x.fitness.values = (0.0, ) for index, y in enumerate(red_pop): y.fitness.values = (0.0, ) """<----------RELATIVE FITNESS EVALUATIONS--------->""" # Evaluate the populations and return with summed fitness scores of all engagements # THIS FITNESS SCORE NEEDS TO BE AVERAGED AFTER HOF EVALS blue_pop, red_pop = helpers.sum_pop_v_pop_evals(blue_pop, red_pop) """<----------HALL OF FAME EVALUATIONS--------->""" # check hof not empty, if not, loop through and evaluate # Only if HOF is turned on if HOF == 1: if len(red_hof) != 0: blue_pop = helpers.sum_pop_v_hof_evals(blue_pop, red_hof) if len(blue_hof) != 0: red_pop = helpers.sum_pop_v_hof_evals(red_pop, blue_hof) """<-------AVERAGE THE FITNESS SCORES------>""" # average the accumulated fitness scores by size of population and also output fitnesses to csv blue_fits_row = [] blue_fits_row.append(i) for index, x in enumerate(blue_pop): if HOF == 1: x.fitness.values = (x.fitness.values[0] / (POP + len(red_hof)), ) else: x.fitness.values = (x.fitness.values[0] / POP, ) blue_fits_row.append(x.fitness.values[0]) red_fits_row = [] red_fits_row.append(i) for index, y in enumerate(red_pop): if HOF == 1: y.fitness.values = (y.fitness.values[0] / (POP + len(blue_hof)), ) else: y.fitness.values = (y.fitness.values[0] / POP, ) red_fits_row.append(y.fitness.values[0]) if REC_FITS == 1: blue_fits_writer.writerow(blue_fits_row) red_fits_writer.writerow(red_fits_row) """------------Generalisation Performance---------------------""" # EVERY 5TH GEN RECORD STATS # if i % 5 == 0 or i == 1: # # CLONE THE POPS SO GP CAN BE CALCULATED WITHOUT AFFECTING FITNESS SCORES # blue_copy = list(map(toolbox.clone, blue_pop)) # red_copy = list(map(toolbox.clone, red_pop)) # blue_copy = tools.selBest(blue_copy, 5) # red_copy = tools.selBest(red_copy, 5) # # Get generalisation performance of two populations # blue_copy = helpers.sum_pop_v_hof_evals(blue_copy, test_set) # for index_x, x in enumerate(blue_copy): # x.fitness.values = (x.fitness.values[0] / len(test_set),) # # red_copy = helpers.sum_pop_v_hof_evals(red_copy, test_set) # for index_x, x in enumerate(red_copy): # x.fitness.values = (x.fitness.values[0] / len(test_set),) # # # create variables for estimated best and average GPs # nBest_blue = tools.selBest(blue_copy, 5) # blue_ebgp = tools.selBest(nBest_blue, 1) # blue_est_best_gp.append(blue_ebgp[0].fitness.values[0]) # blue_eagp_tally = [] # for index, x in enumerate(nBest_blue): # blue_eagp_tally.append(x.fitness.values[0]) # blue_avg = sum(blue_eagp_tally) / len(nBest_blue) # blue_est_avg_gp.append(blue_avg) # # nBest_red = tools.selBest(red_copy, 5) # red_ebgp = tools.selBest(nBest_red, 1) # red_est_best_gp.append(red_ebgp[0].fitness.values[0]) # red_eagp_tally = [] # for index, x in enumerate(nBest_red): # red_eagp_tally.append(x.fitness.values[0]) # red_avg = sum(red_eagp_tally) / len(nBest_red) # red_est_avg_gp.append(red_avg) """<----------OUTPUT INFO TO TEXT FILE---------->""" # BLUE best_blue_ind = tools.selBest(blue_pop, 1)[0] print 'Best Blue fitness score: ', best_blue_ind.fitness.values[0] print 'Best blue chromosome: ', helpers.list_to_string(best_blue_ind) worst_blue_ind = tools.selWorst(blue_pop, 1)[0] print "Worst Blue fitness: ", worst_blue_ind.fitness.values[0] # get the average fitness of the generation sum_fits = sum(ind.fitness.values[0] for ind in blue_pop) avg_blue_fitness = sum_fits / POP print "Generation average Blue fitness: ", avg_blue_fitness # if i % 5 == 0 or i == 1: # print 'Performance Measures:' # # output the GP and diversity of the generation # print 'Blue Estimated Average GP: ', blue_avg # print 'Blue Estimated Best GP: ', blue_ebgp[0].fitness.values[0] # # #Print the 5 best GP inds # print 'Top Blue GP performers' # for index, x in enumerate(nBest_blue): # print index+1, ':' # print helpers.list_to_string(x), 'GP: ', x.fitness.values[0] # RED # get best chromosome and output best_red_ind = tools.selBest(red_pop, 1)[0] print "Best Red fitness: ", best_red_ind.fitness.values[0] print 'Best Red chromosome: ', helpers.list_to_string(best_red_ind) # get worst and display worst_red_ind = tools.selWorst(red_pop, 1)[0] print "Worst Red fitness: ", worst_red_ind.fitness.values[0] # get the average fitness of the generation sum_fits = sum(ind.fitness.values[0] for ind in red_pop) avg_red_fitness = sum_fits / POP print "Generation average red fitness: ", avg_red_fitness # if i % 5 == 0 or i == 1: # print 'Performance Measures:' # # output the GP and diversity of the generation # print 'Red Estimated Average GP: ', red_avg # print 'Red Estimated Best GP: ', red_ebgp[0].fitness.values[0] # # # Print the 5 best GP inds # print 'Top red GP performers' # for index, x in enumerate(nBest_red): # print index + 1, ':' # print helpers.list_to_string(x), 'GP: ', x.fitness.values[0] # Write best avg & worst to fits_csv fit_writer.writerow( (i, best_blue_ind.fitness.values[0], avg_blue_fitness, worst_blue_ind.fitness.values[0], best_red_ind.fitness.values[0], avg_red_fitness, worst_red_ind.fitness.values[0])) # if i % 5 == 0 or i == 1: # # save the GP values to the GP file # gp_writer.writerow((i, blue_ebgp[0].fitness.values[0], blue_avg, red_ebgp[0].fitness.values[0], red_avg)) # if i % 5 == 0 or i == 1: # # Fill the dictionary using the dict(key=value[, ...]) constructor # cp = dict(population=blue_pop, generation=i, rndstate=random.getstate()) # # with open(sub_folder_string + "zgeneration" + str(i) + ".pkl", "wb") as cp_file: # cPickle.dump(cp, cp_file) if i == GENS: break """<------------HALL OF FAME UPDATE----------->""" blue_hof.update(tools.selBest(blue_pop, 1), i) red_hof.update(tools.selBest(red_pop, 1), i) """<------------FITNESS SHARING------------>""" """ NEEDS TO BE FIXED IN HELPERS TO USE NEW CHROMOSOME """ #MUST BE LAST THING BEFORE EVOLUTION HAPPENS # if FS == 1: # blue_pop = helpers.share_fitness(blue_pop, 0.2) # red_pop = helpers.share_fitness(red_pop, 0.2) """<--------------------BEGIN EVOLUTION------------------>""" # Select offspring for next generation if ELITISM == 1: blue_offspring = toolbox.select(blue_pop, POP - 1) red_offspring = toolbox.select(red_pop, POP - 1) else: blue_offspring = toolbox.select(blue_pop, POP) red_offspring = toolbox.select(red_pop, POP) # Clone the offspring so we can evolve blue_offspring = list(map(toolbox.clone, blue_offspring)) red_offspring = list(map(toolbox.clone, red_offspring)) # CROSSOVER # Blue for child1, child2 in zip(blue_offspring[::2], blue_offspring[1::2]): if random.random() < CROSS_PROB: # MATE toolbox.mate(child1, child2) # Red for child1, child2 in zip(red_offspring[::2], red_offspring[1::2]): if random.random() < CROSS_PROB: # MATE toolbox.mate(child1, child2) # MUTATION for mutant in blue_offspring: if random.random() < MUT_PROB: # MUTATE for index, x in enumerate(mutant): mutant[index].value = helpers.convert_range( mutant[index].value, mutant[index].min, mutant[index].max) toolbox.mutate(mutant) for index, x in enumerate(mutant): mutant[index].value = helpers.change_back( mutant[index].value, mutant[index].min, mutant[index].max) helpers.bounds_check(mutant[index]) for mutant in red_offspring: if random.random() < MUT_PROB: # MUTATE for index, x in enumerate(mutant): mutant[index].value = helpers.convert_range( mutant[index].value, mutant[index].min, mutant[index].max) toolbox.mutate(mutant) for index, x in enumerate(mutant): mutant[index].value = helpers.change_back( mutant[index].value, mutant[index].min, mutant[index].max) helpers.bounds_check(mutant[index]) if ELITISM == 1: blue_offspring += tools.selBest(blue_pop, 1) red_offspring += tools.selBest(red_pop, 1) # REPLACE blue_pop[:] = blue_offspring red_pop[:] = red_offspring print( '-------------------------------------Hall Of Fame Regular----------------------------------------' ) print "BLUE: " # for chromosomes in blue_hof: # print 'Chromosome: ', helpers.list_to_string(chromosomes), 'Fitness: ', chromosomes.fitness.values if len(blue_hof) != 0: blue_hof.print_hof() print "RED: " # for chromosomes in red_hof: # print 'Chromosome: ', helpers.list_to_string(chromosomes), 'Fitness: ', chromosomes.fitness.values if len(red_hof) != 0: red_hof.print_hof() print "Generation ", i, " complete." print( '-------------------------------------Hall Of Fame Regular----------------------------------------' ) print "BLUE: " # for chromosomes in blue_hof: # print 'Chromosome: ', helpers.list_to_string(chromosomes), 'Fitness: ', chromosomes.fitness.values if len(blue_hof) != 0: blue_hof.print_hof() print "RED: " # for chromosomes in red_hof: # print 'Chromosome: ', helpers.list_to_string(chromosomes), 'Fitness: ', chromosomes.fitness.values if len(red_hof) != 0: red_hof.print_hof() print( '-------------------------------------Stats----------------------------------------' ) print 'Seed: ', seed print 'Selection: ', SELECTOR print("Pop size: " + str(POP)) print("Generations: " + str(GENS)) print("Crossover Prob: " + str(CROSS_PROB)) print("Mutation Prob: " + str(IND_MUT_PROB)) print 'Elitism: ', ELITISM print 'Hall of Fame: ', HOF print 'Fitness Sharing: ', FS print 'Algorithm: ', alg # Print the 5 best GP inds # print 'Top 5 Blue GP performers:' # for index, x in enumerate(nBest_blue): # print index + 1, ':' # print helpers.list_to_string(x), 'GP: ', x.fitness.values[0] # Print the 5 best GP inds # print 'Top red GP performers:' # for index, x in enumerate(nBest_red): # print index + 1,":" # print helpers.list_to_string(x), 'GP: ', x.fitness.values[0] # pops_writer.writerow(('Final Blue population fitness scores',)) # for index, x in enumerate(blue_pop): # pops_writer.writerow(x.fitness.values) # pops_writer.writerow(('Final Red population fitness scores',)) # for index, y in enumerate(red_pop): # pops_writer.writerow(y.fitness.values) # blue_est_avg_gp = sum(blue_est_avg_gp) / len(blue_est_avg_gp) # red_est_avg_gp = sum(red_est_avg_gp) / len(red_est_avg_gp) # # blue_est_best_gp = sum(blue_est_best_gp) / len(blue_est_best_gp) # red_est_best_gp = sum(red_est_best_gp) / len(red_est_best_gp) fits.close() # pops.close() blue_fits_file.close() red_fits_file.close() # stats = {"blue_est_avg_gp": blue_est_avg_gp, "blue_est_best_gp": blue_est_best_gp, # "red_est_avg_gp": red_est_avg_gp, "red_est_best_gp": red_est_best_gp} return #stats
def run_algorithm(self, seed): # Set up custom hall of fame to keep track of the top chromosomes and their generations hall_of_fame = hof.HallOfFame(self.HOF_SIZE) # set up standard hall of fame that comes with DEAP hall_of_fame_with_dupes = tools.HallOfFame(self.HOF_SIZE) # Get date and time date_time = datetime.datetime.now().strftime("%m-%d_%I%M%p") # print out to file file_name = date_time + '.txt' sys.stdout = open(file_name, 'w') print 'Seed:', seed i = 0 while i < self.GENERATIONS and not self.isConverged: i += 1 print('--------------------------------' + 'Generation: ' + str(i) + '-----------------------------------') # evaluate each chromosome in the population and assign its fitness score for index, x in enumerate(self.population): # update the chromosome, write out to JSON tactical file chromosome_parameters.update_chromosome( x[0].value, x[1].value, x[2].value, x[3].value, x[4].value) # use Ace0 to evaluate the chromosome x.fitness.values = helper.evaluate(self.repetitions) # Select the best chromosome from this generation and display it best_chromosome = tools.selBest(self.population, 1)[0] print "Best chromosome is: ", helper.list_to_string( best_chromosome), best_chromosome.fitness.values # Select worst chromosome and display worst_chromosome = tools.selWorst(self.population, 1)[0] print "Worst chromosome is: ", helper.list_to_string( worst_chromosome), worst_chromosome.fitness.values # Get the over all fitness values sum_fits = sum(ind.fitness.values[0] for ind in self.population) average_fitness = sum_fits / self.POP print 'Generation average fitness: ', average_fitness # save best and average fitness to plot lists self.plot_best_fitness.append(best_chromosome.fitness.values) self.plot_average_fitness.append(average_fitness) self.plot_worst_fitness.append(worst_chromosome.fitness.values) # Update the hall of fame to track the best chromosomes from each generation hall_of_fame.update(self.population, i) hall_of_fame_with_dupes.update(self.population) # hall_of_fame.print_hof() # this is where we evolve the population # Select the next generation individuals offspring = self.toolbox.select(self.population, len(self.population)) # Clone the selected individuals so we can apply crossover offspring = list(map(self.toolbox.clone, offspring)) # Apply crossover on the offspring for child1, child2 in zip(offspring[::2], offspring[::-2]): if random.random() < self.CROSSOVER_PROBABILITY: # mate the two children self.toolbox.mate(child1, child2) # Apply mutation on the offspring for mutant in offspring: if random.random() < self.MUTATION_PROBABILITY: # print 'Mutated Chromosome before: ', helper.list_to_string(mutant) for index, x in enumerate(mutant): mutant[index].value = helper.convert_range( mutant[index].value, mutant[index].min, mutant[index].max) self.toolbox.mutate(mutant) for index, x in enumerate(mutant): mutant[index].value = helper.change_back( mutant[index].value, mutant[index].min, mutant[index].max) helper.bounds_check(mutant[index]) # print 'Mutated Chromosome after: ', helper.list_to_string(mutant) # The population is entirely replaced by the offspring self.population[:] = offspring if float(best_chromosome.fitness.values[0] ) - average_fitness < 0.0001: self.converge_tracker += 1 if self.converge_tracker >= self.converge_tracker_max: print 'CONVERGED' self.isConverged = True else: self.converge_tracker = 0 # # Elitism self.population[0] = hall_of_fame_with_dupes[0] print( '-------------------------------------Hall Of Fame Regular----------------------------------------' ) for chromosomes in hall_of_fame_with_dupes: print 'Chromosome: ', helper.list_to_string( chromosomes), 'Fitness: ', chromosomes.fitness print( '-------------------------------------Hall Of Fame with Gen----------------------------------------' ) hall_of_fame.print_hof() print( '-------------------------------------Stats----------------------------------------' ) print("Pop size: " + str(self.POP)) print("Generations: " + str(self.GENERATIONS)) print("Crossover Prob: " + str(self.CROSSOVER_PROBABILITY)) print("Mutation Prob: " + str(self.MUTATION_PROBABILITY)) # Select the best chromosome from this generation and display it best_chromosome = tools.selBest(self.population, 1)[0] print "Best chromosome is: ", helper.list_to_string( best_chromosome), best_chromosome.fitness.values # Select worst chromosome and display worst_chromosome = tools.selWorst(self.population, 1)[0] print "Worst chromosome is: ", helper.list_to_string( worst_chromosome), worst_chromosome.fitness.values # Get the over all fitness values sum_fits = sum(ind.fitness.values[0] for ind in self.population) average_fitness = sum_fits / self.POP print 'Generation average fitness: ', average_fitness title = 'Seed: ' + str(seed) visualization.draw_plot(title, self.plot_average_fitness, self.plot_best_fitness, self.plot_worst_fitness, 'average per generation', 'best fitness', 'worst fitness', 'generation', 'fitness', 1, 250, 150, date_time) del creator.fitness del creator.Tactic