import sys, os sys.path.insert(0, 'evoman') from environmentclass import Environment from demo_controller import player_controller # imports other libs import numpy as np experiment_name = 'controller_generalist_demo' if not os.path.exists(experiment_name): os.makedirs(experiment_name) # initializes environment for multi objetive mode (generalist) with static enemy and ai player env = Environment(experiment_name=experiment_name, player_controller=player_controller(), speed="normal", enemymode="static", level=2) # sol = np.loadtxt('solutions_demo/demo_all.txt') sol = np.loadtxt('42.txt') print('\n LOADING SAVED GENERALIST SOLUTION FOR ALL ENEMIES \n') means = [] fitnesses = [] player_lifes = [] enemy_lifes = [] print(len(sol)) # tests saved demo solutions for each enemy
headless = True if headless: os.environ["SDL_VIDEODRIVER"] = "dummy" n_hidden_neurons = 10 experiment_name = 'multi_demo' if not os.path.exists(experiment_name): os.makedirs(experiment_name) # initializes simulation in multi evolution mode, for multiple static enemies. env = Environment(experiment_name=experiment_name, enemies=[7, 8], multiplemode="yes", playermode="ai", player_controller=player_controller(n_hidden_neurons), enemymode="static", level=2, speed="fastest") # default environment fitness is assumed for experiment env.state_to_log() # checks environment state #### Optimization for controller solution (best genotype-weights for phenotype-network): Ganetic Algorihm ### ini = time.time() # sets time marker # genetic algorithm params run_mode = 'train' # train or test
def main1(seed, game, algorithm, group): experiment_name = 'dummy_demo' if not os.path.exists(experiment_name): os.makedirs(experiment_name) # Initialize the amout of neurons n_hidden_neurons = 10 # initializes simulation in individual evolution mode, for single static enemy. env = Environment(experiment_name=experiment_name, enemies=[7, 8], playermode="ai", player_controller=player_controller(n_hidden_neurons), enemymode="static", level=2, multiplemode="yes", speed="fastest") # default environment fitness is assumed for experiment env.state_to_log() # checks environment state #### Optimization for controller solution (best genotype-weights for phenotype-network): Ganetic Algorihm ### ini = time.time() # sets time marker # genetic algorithm params run_mode = 'train' # train or test # number of weights for multilayer with 10 hidden neurons n_vars = (env.get_num_sensors() + 1) * n_hidden_neurons + (n_hidden_neurons + 1) * 5 #--------------------- creator.create("FitnessMin", base.Fitness, weights=(-30.0, -30.0)) creator.create("Individual", list, fitness=creator.FitnessMin) toolbox = base.Toolbox() # Attribute generator # define 'attr_bool' to be an attribute ('gene') # which corresponds to integers sampled uniformly # from the range [0,1] (i.e. 0 or 1 with equal # probability) toolbox.register("attr_bool", random.uniform, -1, 1) # Structure initializers # define 'individual' to be an individual # consisting of 100 'attr_bool' elements ('genes') toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_bool, n_vars) # define the population to be a list of individuals toolbox.register("population", tools.initRepeat, list, toolbox.individual) # the goal ('fitness') function to be maximized # evaluation function that is used in the DEAP algorithm def evaluate(x): return np.array(list(map(lambda y: simulation(env, y), x))), #---------- # Operator registration #---------- # register the goal / fitness function toolbox.register("evaluate", evaluate) # register the crossover operator toolbox.register("mate", tools.cxTwoPoint) # register a mutation operator with a probability to # flip each attribute/gene of 0.05 toolbox.register("mutate", tools.mutPolynomialBounded, eta=20.0, low=-1, up=1, indpb=0.05) # operator for selecting individuals for breeding the next # generation: each individual of the current generation # is replaced by the 'fittest' (best) of three individuals # drawn randomly from the current generation. toolbox.register("select", tools.selTournament) creator.create("FitnessMin", base.Fitness, weights=(-100, )) #---------- def simulation(env, x): f, p, e, t = env.play(pcont=x) return f, p # runs simulation def main(seed, game, group): file_aux = open(str(algorithm) + '_group_' + str(group) + '.txt', 'a') file_aux.write(f'\ngame {game} \n') file_aux.write('gen, best, mean, std, median, q1, q3, life') file_aux.close() # fitnesses = np.array([]) random.seed(seed) # create an initial population of 30 individuals (where # each individual is a list of integers) pop = toolbox.population(n=50) pop_array = np.array(pop) # CXPB is the probability with which two individuals # are crossed # MUTPB is the probability for mutating an individual CXPB = 0.8 print("Start of evolution") # Evaluates the entire population values = evaluate(pop_array) values = values[0].tolist() fitnesses = [] lifes = [] for value in values: fitnesses.append(value[0]) lifes.append(value[1]) for count, individual in enumerate(fitnesses): # Rewrites the fitness value in a way the DEAP algorithm can understand fitnesses[count] = (-individual, ) # Gives individual a fitness value for ind, fit in zip(pop, fitnesses): ind.fitness.values = fit print(" Evaluated %i individuals" % len(pop)) # Extracting all the fitnesses of fits = [ind.fitness.values[0] for ind in pop] # Variable keeping track of the number of generations g = 0 g_end = 15 # Saves first generation length = len(pop) mean = sum(fits) / length * -1 sum2 = sum(x * x for x in fits) std = abs(sum2 / length - abs(mean)**2)**0.5 q1 = np.percentile(fits, 25) * -1 median = np.percentile(fits, 50) * -1 q3 = np.percentile(fits, 75) * -1 max_life = max(lifes) file_aux = open(str(algorithm) + '_group_' + str(group) + '.txt', 'a') file_aux.write( f'\n{str(g)}, {str(round(min(fits)*-1,6))}, {str(round(mean,6))}, {str(round(std,6))}, {str(round(median,6))}, {str(round(q1,6))}, {str(round(q3,6))}, {str(round(max_life,6))}' ) file_aux.close() # Begin the evolution while max(fits) < 100 and g < g_end: # A new generation g = g + 1 print("-- Generation %i --" % g) # Select the next generation individuals offspring = toolbox.select(pop, len(pop), 6) for i in offspring: print(i.fitness.values[0]) # Clone the selected individuals offspring = list(map(toolbox.clone, offspring)) # Prints fitnesses of the offspring (does nothing for the algorithm # for i in offspring: # print(i.fitness.values[0]) # Apply crossover and mutation on the offspring for child1, child2 in zip(offspring[::2], offspring[1::2]): # cross two individuals with probability CXPB if random.random() < CXPB: toolbox.mate(child1, child2) # fitness values of the children # must be recalculated later del child1.fitness.values del child2.fitness.values for mutant in offspring: # mutate an individual with probability MUTPB if random.random() < (0.5): toolbox.mutate(mutant) del mutant.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] pop_array = np.array(invalid_ind) values = evaluate(pop_array) values = values[0].tolist() fitnesses = [] for value in values: fitnesses.append(value[0]) lifes.append(value[1]) for count, individual in enumerate(fitnesses): fitnesses[count] = (-individual, ) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit print(" Evaluated %i individuals" % len(invalid_ind)) # Changes best individuals of population with worst individuals of the offspring amount_swithed_individuals = int(len(pop) / 10) worst_offspring = deap.tools.selWorst(offspring, amount_swithed_individuals, fit_attr='fitness') best_gen = deap.tools.selBest(pop, amount_swithed_individuals, fit_attr='fitness') for count, individual in enumerate(worst_offspring): index = offspring.index(individual) offspring[index] = best_gen[count] # The population is entirely replaced by the offspring (plus best of previous generations) pop[:] = offspring print(f"There are {len(pop)} individuals in the population ") # Gather all the fitnesses in one list and print the stats fits = [ind.fitness.values[0] for ind in pop] length = len(pop) mean = sum(fits) / length * -1 sum2 = sum(x * x for x in fits) std = abs(sum2 / length - mean**2)**0.5 q1 = np.percentile(fits, 25) * -1 median = np.percentile(fits, 50) * -1 q3 = np.percentile(fits, 75) * -1 max_life = max(lifes) print(" Min %s" % max(fits)) print(" Max %s" % min(fits)) print(" Avg %s" % mean) print(" Std %s" % std) # saves results for first pop file_aux = open( str(algorithm) + '_group_' + str(group) + '.txt', 'a') file_aux.write( f'\n{str(g)}, {str(round(min(fits) *-1,6))}, {str(round(mean,6))}, {str(round(std,6))}, {str(round(median,6))}, {str(round(q1,6))}, {str(round(q3,6))}, {str(round(max_life,6))}' ) file_aux.close() best_ind = tools.selBest(pop, 1)[0] print("Best individual is %s, %s" % (best_ind, best_ind.fitness.values)) np.savetxt( experiment_name + '/Algorithm_' + algorithm_number + '_group_' + group + '/individuals_game_' + str(game) + '/game_' + str(game) + '_gen_' + str(g) + '_group_' + str(group) + '_Tournement.txt', best_ind) print("-- End of (successful) evolution --") main(seed, game, group)
def main1(seed, game, algorithm, group, algorithm_number, gen): experiment_name = 'dummy_demo' if not os.path.exists(experiment_name): os.makedirs(experiment_name) # Initialize the amout of neurons n_hidden_neurons = 10 # initializes simulation in individual evolution mode, for single static enemy. env = Environment(experiment_name=experiment_name, enemies=[1, 2, 3, 4, 5, 6, 7, 8], playermode="ai", player_controller=player_controller(n_hidden_neurons), enemymode="static", level=2, multiplemode="yes", speed="fastest") # default environment fitness is assumed for experiment env.state_to_log() # checks environment state #### Optimization for controller solution (best genotype-weights for phenotype-network): Ganetic Algorihm ### ini = time.time() # sets time marker # genetic algorithm params run_mode = 'train' # train or test # number of weights for multilayer with 10 hidden neurons n_vars = (env.get_num_sensors() + 1) * n_hidden_neurons + (n_hidden_neurons + 1) * 5 #--------------------- creator.create("FitnessMin", base.Fitness, weights=(30.0, 30.0)) creator.create("Individual", list, fitness=creator.FitnessMin) toolbox = base.Toolbox() # Attribute generator # define 'attr_bool' to be an attribute ('gene') # which corresponds to integers sampled uniformly # from the range [0,1] (i.e. 0 or 1 with equal # probability) toolbox.register("attr_bool", random.uniform, -1, 1) # Structure initializers # define 'individual' to be an individual # consisting of 100 'attr_bool' elements ('genes') toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_bool, n_vars) # define the population to be a list of individuals toolbox.register("population", tools.initRepeat, list, toolbox.individual) # the goal ('fitness') function to be maximized # evaluation function that is used in the DEAP algorithm def evaluate(x): return np.array(list(map(lambda y: simulation(env, y), x))), #---------- # Operator registration #---------- # register the goal / fitness function toolbox.register("evaluate", evaluate) # register the crossover operator toolbox.register("mate", tools.cxBlend) # register a mutation operator with a probability to # flip each attribute/gene of 0.05 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) # operator for selecting individuals for breeding the next # generation: each individual of the current generation # is replaced by the 'fittest' (best) of three individuals # drawn randomly from the current generation. toolbox.register("select", tools.selTournament) creator.create("FitnessMin", base.Fitness, weights=(100, )) #---------- def simulation(env, x): f, p, e, t = env.play(pcont=x) return f, p a = f'\Algorithm_{algorithm_number}_group_{group}\individuals_game_{game}\game_{game}_gen_{gen}_group_{group}_Tournement.txt' print(f"game = {game}, gen = {gen}") # Load specialist controller sol = np.loadtxt('dummy_demo' + a) print('\n LOADING SAVED SPECIALIST SOLUTION FOR ENEMY \n') print(evaluate([sol])) enemy_life = env.get_list_enemy_life() fitnesses = env.get_list_fitnesses() competition = env.get_lists_competition_life() sum_life = np.sum(competition[0]) sum_time = np.sum(competition[1]) if enemy_life.count(0) == 4: file_aux = open('champs.txt', 'a') file_aux.write( f"Algorithm = {algorithm_number}, Group = {group}, Game = {game}, Gen = {gen} sum_player_life = {str(sum_life)}, mean_enemy_life = {np.mean(enemy_life)}, sum_time = {sum_time}, mean_fitnesses = {np.mean(fitnesses)}\n" ) file_aux.close() elif enemy_life.count(0) == 5: file_aux = open('super_champs.txt', 'a') file_aux.write( f"Algorithm = {algorithm_number}, Group = {group}, Game = {game}, Enemy_lifes = {str(enemy_life)}, fitnesses = {fitnesses}\n" ) file_aux.close()
def main1(game, algorithm): # Setting up the game enemy = 167 experiment_name = 'adrian-testing-3' + "-algorithm-" + str(algorithm) print(experiment_name + " game: " + str(game) + " " + "enemy: " + str(enemy)) if not os.path.exists(experiment_name): os.makedirs(experiment_name) # Initialize the amout of neurons n_hidden_neurons = 10 # initializes simulation in individual evolution mode, for single static enemy. env = Environment( experiment_name=experiment_name, enemies=enemies, playermode="ai", player_controller=player_controller(n_hidden_neurons), enemymode="static", multiplemode="yes", level=2, # default environment fitness is assumed for experiment speed="fastest") # default environment fitness is assumed for experiment env.state_to_log() # checks environment state #Optimization for controller solution (best genotype-weights for phenotype-network): Ganetic Algorihm ### ini = time.time() # sets time marker # genetic algorithm params run_mode = 'train' # train or test # number of weights for multilayer with 10 hidden neurons n_vars = (env.get_num_sensors() + 1) * n_hidden_neurons + (n_hidden_neurons + 1) * 5 #------------ Setting up the GA --------------- # There are two main areas where change is possible a) and b) (Also new things could be added e.g. Doomsday..,) # a) GA Constants and parameters genome_lenght = n_vars #100 #lenght of the bit string to be optimized -> bit lenght is actually n_vars pop_size = 50 p_crossover = 0.8 p_mutation = 0.2 mutation_scaler = genome_lenght # The bitflip function iterates over every single value in an individuals genome, with a probability indpb it decides wether to flip or not. This value is independent from the mutation probability which decides IF a given individual in the population will be selected for mutation. max_generations = 15 # stopping condition tournament_size = 5 # tournament size seed = 50 #random.randint(1, 126) random.seed(seed) # For optimizing continuous functions bound_low = -1 bound_up = 1 crowding_factor = 20 # Defining a tool to create single gene toolbox = base.Toolbox() # toolbox.register("ZeroOrOne", random.randint, -1, 1) toolbox.register("ZeroOrOne", random.uniform, -1, 1) # Each gene is a float between -1 and 1 # Defining the fitness # creator.create("FitnessMin", base.Fitness, weights=(-30.0, -30.0)) # creator.create("FitnessMin", base.Fitness, weights=(-100,)) creator.create("FitnessMin", base.Fitness, weights=(100, )) # Defining an individual creatorfre creator.create( "Individual", list, fitness=creator.FitnessMin ) # An individual will be stored in a list format with fitness evaluated at "FitnessMin" toolbox.register( "individualCreator", tools.initRepeat, creator.Individual, toolbox.ZeroOrOne, genome_lenght ) # An individual consist of a list of n_var attributes (genes) populated by zeroorone # Defining the population cretor toolbox.register("populationCreator", tools.initRepeat, list, toolbox.individualCreator) # Defining the fitness function def evaluate(x): return np.array(list(map(lambda y: simulation(env, y), x))), toolbox.register("evaluate", evaluate) #------------- b) Registering the EA operators -------------- # 1. Standard operators toolbox.register("select", tools.selTournament, tournsize=tournament_size) # # toolbox.register("mate", tools.cxSimulatedBinaryBounded, low=bound_low, up=bound_up,eta=crowding_factor) # # toolbox.register("mutate", tools.mutPolynomialBounded, low=bound_low, up=bound_up,eta=crowding_factor,indpb=1.0/mutation_scaler) # toolbox.register("mate", tools.cxTwoPoint) # toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) # 2. Multiple operators # 2.1 All operators # 2.1.1 Crossover # Two-point: toolbox.register("mate", tools.cxTwoPoint) # Partially matched: toolbox.register("mate", tools.cxPartialyMatched) # Uniform: toolbox.register("mate", tools.cxUniform, indpb=0.05) # 2.1.2 Mutation # flip: toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) # shuffle: toolbox.register("mutate", tools.mutShuffleIndexes, indpb=0.05) # uniformint: toolbox.register("mutate", tools.mutUniformInt(low = -1, high = 1, indpb = 0.05) toolbox.register("mate", tools.cxTwoPoint) if algorithm == 1: p_crossover = 0.8 tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) elif algorithm == 2: p_crossover = 0.75 tournament_size = 5 toolbox.register("mutate", tools.mutShuffleIndexes, indpb=0.05) elif algorithm == 3: p_crossover = 0.70 tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) elif algorithm == 4: p_crossover = 0.85 tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) elif algorithm == 5: p_crossover = 0.90 tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) elif algorithm == 6: p_crossover = 0.95 tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) elif algorithm == 7: tournament_size = 6 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) elif algorithm == 8: tournament_size = 7 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) elif algorithm == 9: tournament_size = 8 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) elif algorithm == 10: tournament_size = 9 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) elif algorithm == 11: tournament_size = 10 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) elif algorithm == 12: tournament_size = 11 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) elif algorithm == 13: tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) elif algorithm == 14: tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.04) elif algorithm == 15: tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.03) elif algorithm == 16: tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.06) elif algorithm == 17: tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.07) elif algorithm == 18: tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.08) elif algorithm == 19: tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.075) elif algorithm == 20: tournament_size = 5 toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) else: print("why?") #---------------- Setting the game enviroment ---------------- def simulation(env, x): f, p, e, t = env.play(pcont=x) return f, p # Plotting maxFitnessValues = [] meanFitnessValues = [] # Running the simulation def main(game, enemy): file_aux=open(experiment_name+'/results_enemy' + \ str(enemy) + str(algorithm) + '.txt', 'a') file_aux.write(f'\ngame {game} \n') file_aux.write('gen, best, mean, std, median, q1, q3, life') file_aux.close() #Creating the population pop = toolbox.populationCreator( n=pop_size) # Population is created as a list object pop_array = np.array(pop) generationCounter = 0 print("Start of evolution") # Evaluating all the population # fitnessValues=list(map(toolbox.evaluate, pop_array)) -> Won't work. Used Kamiel's fitnessValue = evaluate(pop_array) fitnessValue = fitnessValue[0].tolist() fitnesses = [] lifes = [] for value in fitnessValue: fitnesses.append(value[0]) lifes.append(value[1]) for count, individual in enumerate(fitnesses): # Rewrites the fitness value in a way the DEAP algorithm can understand fitnesses[count] = (-individual, ) # Assigning the fitness value to each individual for individual, fitnessValue in zip(pop, fitnesses): individual.fitness.values = fitnessValue # Extract each fitness value fitnessValues = [individual.fitness.values[0] for individual in pop] # Saves first generation fits = fitnessValues g = generationCounter length = len(pop) mean = sum(fits) / length sum2 = sum(x * x for x in fits) std = abs(sum2 / length - abs(mean)**2)**0.5 q1 = np.percentile(fits, 25) median = np.percentile(fits, 50) q3 = np.percentile(fits, 75) max_life = max(lifes) file_aux = open( experiment_name + '/results_enemy' + str(enemy) + 'Tournement.txt', 'a') file_aux.write( f'\n{str(g)}, {str(round(max(fits)))}, {str(round(mean,6))}, {str(round(std,6))}, {str(round(median,6))}, {str(round(q1,6))}, {str(round(q3,6))}, {str(round(max_life,6))}' ) file_aux.close() # Beggin the genetic loop # First, we start with the stopping condition while max(fitnessValues) < 100 and generationCounter < max_generations: begin_time = datetime.datetime.now() print("Being evolution time:", begin_time, "!!!") # Update generation counter generationCounter = generationCounter + 1 print("-- Generation %i --" % generationCounter) # Begin genetic operators # 1. Selection: since we already defined the tournament before # we only need to select the population and its lenght # Selected individuals now will be in a list print("selection...") offspring = toolbox.select(pop, len(pop)) for i in offspring: print(i.fitness.values[0]) # Cloning the selected indv so we can apply the next genetic operators without affecting the original pop offspring = list(map(toolbox.clone, offspring)) print("done") # 2. Crossover. Note taht the mate function takes two individuals as arguments and # modifies them in place, meaning they don't need to be reassigned print("Crossover...") for child1, child2 in zip(offspring[::2], offspring[1::2]): if random.random() < p_crossover: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values print("done") # 3. Mutation print("Mutation...") for mutant in offspring: # if random.random() < p_mutation: if random.random() < (1 - (generationCounter / max_generations)): toolbox.mutate(mutant) del mutant.fitness.values # Individuals that werent mutated remain intact, their fitness values don't need to eb recalculated # The rest of the individuals will have this value EMPTY # We now find those individuals and calculate the new fitness print("...re-evaluating fitness...") freshIndividuals = [ ind for ind in offspring if not ind.fitness.valid ] # Eval not work!!! :(( used Kamiels # freshFitnessValues=list(map(toolbox.evaluate, freshIndividuals)) # for individual, fitnessValue in zip(freshIndividuals, freshFitnessValues): # individual.fitness.values=fitnessValue pop_array = np.array(freshIndividuals) values = evaluate(pop_array) values = values[0].tolist() fitnesses = [] for value in values: fitnesses.append(value[0]) lifes.append(value[1]) for count, individual in enumerate(fitnesses): fitnesses[count] = (individual, ) for ind, fit in zip(freshIndividuals, fitnesses): ind.fitness.values = fit print("done") # Changes best individuals of population with worst individuals of the offspring amount_swithed_individuals = int(len(pop) / 10) worst_offspring = deap.tools.selWorst(offspring, amount_swithed_individuals, fit_attr='fitness') best_gen = deap.tools.selBest(pop, amount_swithed_individuals, fit_attr='fitness') for count, individual in enumerate(worst_offspring): index = offspring.index(individual) offspring[index] = best_gen[count] # End of the proccess -> replace the old population wiht the new one pop[:] = offspring print(f"There are {len(pop)} individuals in the population ") # Gather all the fitnesses in one list and print the stats fits = [ind.fitness.values[0] for ind in pop] length = len(pop) mean = sum(fits) / length sum2 = sum(x * x for x in fits) std = abs(sum2 / length - abs(mean)**2)**0.5 q1 = np.percentile(fits, 25) median = np.percentile(fits, 50) q3 = np.percentile(fits, 75) max_life = max(lifes) # For plotting maxFitness = max(fits) meanFitness = sum(fits) / len(pop) maxFitnessValues.append(maxFitness) meanFitnessValues.append(meanFitness) print(" Min %s" % min(fits)) print(" Max %s" % max(fits)) print(" Avg %s" % mean) print(" Std %s" % std) # Plot plt.plot(maxFitnessValues) plt.plot(meanFitnessValues) ymax = max(maxFitnessValues) plt.ylabel("Values") plt.xlabel("Generations") plt.title("Maximum fitness: " + str(ymax) + " Algorithm :" + str(algorithm)) plt.savefig("adrian-testing-3" + "-algorithm-" + str(algorithm) + "-enemy-" + str(enemy) + ".png") plt.show() # DataFrame df.loc[int(algorithm)] = [min(fits), max(fits), mean, std] df.to_csv("adrian-testing-3" + "-algorithm-" + str(algorithm) + "-enemy-" + str(enemy) + ".csv", index=False) print("Saving...") # saves results for first pop file_aux=open(experiment_name+'/results_enemy' + \ str(enemy)+'Tournement.txt', 'a') file_aux.write( f'\n{str(g)}, {str(round(max(fits),6))}, {str(round(mean,6))}, {str(round(std,6))}, {str(round(median,6))}, {str(round(q1,6))}, {str(round(q3,6))}, {str(round(max_life,6))}' ) file_aux.close() print("Evolution ended in:", datetime.datetime.now() - begin_time) print("-- End of (successful) evolution --") best_ind = tools.selBest(pop, 1)[0] print("Best individual is %s, %s" % (best_ind, best_ind.fitness.values)) np.savetxt(experiment_name+'/best_game_'+str(game) + \ ',enemy_'+str(enemy)+'Tournement.txt', best_ind) print("Done. New generation...") main(game, enemy) plt.show() print("Run ended in:", datetime.datetime.now() - begin_game)
def __init__(self, neurons=10, gen=10, popsize=5, pc=0.5, pm=0.5): self.gen = gen # Number of generations self.pc = pc # Crossover probability self.pm = pm # Mutation probability # Make a folder for results self.experiment_name = 'task1_2' if not os.path.exists(self.experiment_name): os.makedirs(self.experiment_name) fitness_results = open(self.experiment_name + '/results.txt', 'a') self.env = Environment(experiment_name=self.experiment_name, enemies=[5], level=2, playermode='ai', enemymode='static', player_controller=player_controller(neurons), speed='fastest') n_vars = (self.env.get_num_sensors() + 1) * neurons + (neurons + 1) * 5 # Create framework for individuals/population creator.create("FitnessMax", base.Fitness, weights=(1.0, )) # What do these weights mean? creator.create("Individual", list, fitness=creator.FitnessMax) self.toolbox = base.Toolbox() self.toolbox.register("new_ind", np.random.uniform, -1, 1) self.toolbox.register("individual", tools.initRepeat, creator.Individual, self.toolbox.new_ind, n=n_vars) self.toolbox.register("select", tools.selTournament, tournsize=2) self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual) self.toolbox.register("mate", tools.cxTwoPoint) self.toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.2) self.toolbox.register("evaluate", self.evaluate) self.pop = self.toolbox.population(n=popsize) # Set up some tools for calculating statistics self.stats = tools.Statistics(key=lambda ind: ind.fitness.values) self.stats.register("avg", np.mean, axis=0) self.stats.register("std", np.std, axis=0) self.stats.register("min", np.min, axis=0) self.stats.register("max", np.max, axis=0) # Calculate the fitness for every member in the new population fitnesses = np.array( list(map(lambda y: self.toolbox.evaluate(self.env, y), self.pop))) for ind, fit in zip(self.pop, fitnesses): ind.fitness.values = [fit] self.record = self.stats.compile(self.pop)
def cons_multi(self, values): return values n_hidden = 10 env_all = OurEnv( experiment_name=experiment_name, enemies=[1, 2, 3, 4, 5, 6, 7, 8], level=2, # integer playermode="ai", # ai or human multiplemode="yes", enemymode="static", logs="off", player_controller=player_controller(n_hidden), speed="fastest") def run(individual): f, _, _, _ = env_all.play(pcont=np.asarray(individual)) return f def main(ea_type): fittest_individuals = open_pickle("data/" + ea_type + "_merged_individuals") pop_fitnesses = [] for fi in fittest_individuals:
def deap_generalist_twopoint(experiment_name, enemies_in_group, iteration_number): if not os.path.exists(experiment_name): os.makedirs(experiment_name) if os.path.exists(experiment_name + '/results.csv'): os.remove(experiment_name + '/results.csv') if os.path.exists(experiment_name + '/best.txt'): os.remove(experiment_name + '/best.txt') n_hidden_neurons = 10 # initializes simulation in individual evolution mode, for single static enemy. env = Environment( experiment_name=experiment_name, enemies=enemies_in_group, multiplemode="yes", playermode="ai", player_controller=player_controller(n_hidden_neurons), enemymode="static", level=2, speed="fastest", ) # GLOBAL VARIABLES POP_SIZE = 100 # Population size GENS = 15 # Amount of generations MUTPB = 0.2 # MUTPB is the probability for mutating an individual toolbox = base.Toolbox() n_vars = (env.get_num_sensors() + 1) * n_hidden_neurons + (n_hidden_neurons + 1) * 5 #DATA genlist = [] bestlist = [] meanlist = [] stdlist = [] def evaluate(pop): """ This function will start a game with one individual from the population Args: individual (np.ndarray of Floats between -1 and 1): One individual from the population Returns: Float: Fitness """ for ind in pop: f, p, e, t = env.play( pcont=ind ) # return fitness, self.player.life, self.enemy.life, self.time fitness = p - e ind.fitness.values = [fitness] def setup_DEAP(): """ This function sets up the DEAP environment to our liking. creator.create is used to create a class under a certain name toolbox.register is used to register a function under a certain name which can be called For more information about which examples are used and the DEAP documentation: # https://deap.readthedocs.io/en/master/ # https://deap.readthedocs.io/en/master/examples/ga_onemax.html """ # this tells DEAP that the fitness should be as high as possible. (therefore Max) creator.create("FitnessMax", base.Fitness, weights=(1.0, )) # an individual is a np.ndarray filled with random floats which are the inputs of the game creator.create("Individual", np.ndarray, fitness=creator.FitnessMax) toolbox.register("attr_float", random.uniform, -1, 1) # registers function to create an individual # n_vars is the amount of floats in the individual toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n_vars) # registers function to create the population of individuals toolbox.register("population", tools.initRepeat, list, toolbox.individual) # registers function which links to our evaluate function toolbox.register("evaluate", evaluate) # registers crossover function: We use One Point Crossover toolbox.register("mate", tools.cxTwoPoint) # registers mutation function: We use bit-flipping toolbox.register("mutate", tools.mutShuffleIndexes, indpb=0.2) # Because it already changes 2 values # registers selection function: We select using tournament selection of 2. toolbox.register("select", tools.selTournament, tournsize=2) # registers survival selection function toolbox.register("survive", tools.selRandom) def mutation(offspring): """ 'Mutation is applied to the offspring delivered by crossover.' Args: offspring (List of individuals): Selected offspring from the population """ for mutant in offspring: if random.random() < MUTPB: toolbox.mutate(mutant) def crossover_and_mutation(offspring): """ 'In evolutionary computing, the combination of features from two individuals in offspring is often called crossover (or recombination).' We currently use one point crossover. Args: offspring (List of individuals): Selected offspring from the population """ children = [] for parent1, parent2 in zip(offspring[::2], offspring[1::2]): # NOT USED. if random.random() < CXPB: child1 = toolbox.clone(parent1) child2 = toolbox.clone(parent2) toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values children.extend((child1, child2)) # apply mutation to children mutation(children) # add children to population offspring.extend((child for child in children)) def configure_results(pop, generation, ultimate_best): fits = [ind.fitness.values[0] for ind in pop] length = len(pop) mean = sum(fits) / length sum2 = sum(x * x for x in fits) std = abs(sum2 / length - mean**2)**0.5 max_fitness = max(fits) print(" Min %s" % min(fits)) print(" Max %s" % max_fitness) print(" Avg %s" % mean) print(" Std %s" % std) # 7. best = fits.index(max_fitness) if max_fitness > ultimate_best: print("ultimate best") ultimate_best = best np.savetxt(experiment_name + "/best.txt", pop[best]) if max_fitness > winner["fitness"]: print("WINNER") winner["solution"] = pop[best] winner["fitness"] = max_fitness genlist.append(generation) bestlist.append(round(max_fitness, 6)) meanlist.append(round(mean, 6)) stdlist.append(round(std, 6)) # save result of each generation # file_aux = open(experiment_name+'/results.txt','a') # file_aux.write('\n\ngen best mean std') # file_aux.write('\n'+str(generation)+' '+str(round(max_fitness,6))+' '+str(round(mean,6))+' '+str(round(std,6)) ) # file_aux.close() return fits, ultimate_best def evolution(pop, ultimate_best): """ Evolution Steps: 1. Select next generation of individuals from population 2. Clone is used (I think) to let the DEAP algorithm know it is a new generation 3. Apply Crossover on the offspring 4. Apply Mutation on the offspring 5. Evaluate individuals that have been changed due to crossover or mutation 6. Apply survivor selection by picking the best of a group 6. Show statistics of the fitness levels of the population and save best individual of that run 7. Update environment solutions Args: pop (list): A list containing individuals """ current_g = 0 while current_g < GENS: current_g = current_g + 1 print("-- Generation %i --" % current_g) # 1. selected = toolbox.select(pop, len(pop)) # 2. offspring = list(map(toolbox.clone, selected)) shuffle(offspring) #3. #4. crossover_and_mutation(offspring) #5. changed_individuals = [ ind for ind in offspring if not ind.fitness.valid ] toolbox.evaluate(changed_individuals) #6 survivors = toolbox.survive(offspring, POP_SIZE) # Replace old population by offspring pop[:] = survivors # 7. fits, ultimate_best = configure_results(pop, current_g, ultimate_best) print(fits) # 8. solutions = [pop, fits] env.update_solutions(solutions) env.save_state() def main(iteration_number): """ This is the start of the program. Program Steps: 1. Setup Deap Environment 2. Initialize Population of individuals 3. Evaluate population by playing the game and assigning fitness levels 4. Show and save results for that population 4. Start Evolution """ # 1. setup_DEAP() # 2. print("-- Form Population --") random.seed(2) #starts with the same population pop = toolbox.population(n=POP_SIZE) random.seed(iteration_number) print(iteration_number) # 3. toolbox.evaluate(pop) ultimate_best = -200 # 4. fits, ultimate_best = configure_results(pop, 0, ultimate_best) # 5. evolution(pop, ultimate_best) # Print results to csv print("PRINT TO CSV") with open(experiment_name + '/results.csv', 'w+', newline='') as csvfile: filewriter = csv.writer(csvfile, delimiter=',') filewriter.writerow(["generation", "best", "mean"]) #, "std"]) for i in range(len(bestlist)): filewriter.writerow( [genlist[i], bestlist[i], meanlist[i], stdlist[i]]) main(iteration_number)
def main(): # Define variables for this enemy's loop very_best_fitness = 0 # Keeps track of the entire experiment its best fitness value very_best_individual = None # Keeps track of the entire experiement its best individual (with best fitness value) global env # Make the environment global so we can use the environment in the evaluate function. The environment should be initialized here # since in this scope we know the current enemy. The evaluate function cannot be changed w.r.t. its parameters so we define the environment here. env = Environment(experiment_name=experiment_name, playermode="ai", speed="fastest", multiplemode="yes", enemies=enemies, player_controller=player_controller(n_hidden_neurons), enemymode="static", level=2) # Initialize population with shape (n_size, pop_size) pop = toolbox.population(n=pop_size) fitnesses = list(map(toolbox.evaluate, pop)) # List of tuples: (fitness, ) for ind, fit in zip(pop, fitnesses): ind.fitness.values = fit # Set each individual's fitness level for the framework best_f, best_i = find_best_individual(pop) print("best fitness value is currently: {}".format(best_f)) fits = [ind.fitness.values[0] for ind in pop] g = 0 # Generation counter # As long as we haven't reached our fitness goal or the max generations, keep running while max(fits) < goal_fit and g < generations: temp_best_fitness, temp_best_ind = find_best_individual( pop ) # Store best fitness here at the beginning of this generation so we can track improvement for this generation g += 1 print("\n\nGeneration {} of {}, current best fitness is: {}. \n\n". format(g, generations, temp_best_fitness)) offspring = map(toolbox.clone, toolbox.select(pop, len(pop))) # Select and clone offspring = algorithms.varAnd( offspring, toolbox, CXPB, MUTPB) # Apply crossover and mutation on the offspring # Evaluate the individuals with an invalid fitness since for some we deleted their fitness values invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit pop[:] = offspring # Replace the pop variable with the new offspring best_fitness, best_ind = find_best_individual(pop) if best_fitness > very_best_fitness: very_best_fitness = best_fitness very_best_individual = best_ind print( "End of generation, best fitness is now: {}".format(best_fitness)) # End of the entire run, save best individual path = experiment_name + "/best_individual.pkl" print("Saving the best individual with fitness: {}".format( very_best_fitness)) with open(path, "wb") as f: pickle.dump(very_best_individual, f) f.close()
from task1_recombination import Recombination from task1_initialization import Initialization from task1_evaluation import Evaluation from task1_constants import * from task1_logger import Logger from demo_controller import player_controller from environment import Environment experiment_name = 'task1_specialist1_enemy_{}'.format(ENEMY) if not os.path.exists(experiment_name): os.makedirs(experiment_name) env = Environment(experiment_name=experiment_name,level=2, enemies=ENEMY, player_controller=player_controller(N_HIDDEN_NEURONS), speed="fastest") N_VARS = (env.get_num_sensors() + 1) * N_HIDDEN_NEURONS + (N_HIDDEN_NEURONS + 1) * 5 init = Initialization(DOM_L, DOM_U) evaluator = Evaluation(env) selector = Selection() logger = Logger(experiment_name) recombinator = Recombination() mutator = Mutation(MIN_DEV, ROTATION_MUTATION, STANDARD_DEVIATION, DOM_L, DOM_U) population = init.uniform_initialization(NPOP, N_VARS) best = None for i in range(NGEN): print(i) fitness_list = evaluator.simple_eval(population)
genome_neat = pickle.load(open('winners/neat-winner-e{}-r{}'.format(e, r), 'rb')) ffn = neat.nn.FeedForwardNetwork.create(genome_neat, config) total_gain_neat = 0 total_gain_neuro = 0 for enemy in range(1, 9): env_neat = Environment(experiment_name=experiment_name, enemies=[enemy], player_controller=PlayerController()) _, pe_neat, ee_neat, _ = env_neat.play(pcont=ffn) total_gain_neat += pe_neat - ee_neat env_neuro = Environment(experiment_name=experiment_name, enemies=[enemy], player_controller=player_controller(10)) _, pe_neuro, ee_neuro, _ = env_neuro.play(pcont=genome_neuro) total_gain_neuro += pe_neuro - ee_neuro if winners_neat[e][1] < total_gain_neat: winners_neat[e] = (r, total_gain_neat) if winners_neuro[e][1] < total_gain_neuro: winners_neuro[e] = (r, total_gain_neuro) print(winners_neat) print(winners_neuro) genome_neuro = pickle.load(open('winners/neuro-winner-e{}-r{}'.format(e, winners_neuro[e][0]), 'rb')) genome_neat = pickle.load(open('winners/neat-winner-e{}-r{}'.format(e, winners_neat[e][0]), 'rb')) ffn = neat.nn.FeedForwardNetwork.create(genome_neat, config)
min_species_size = 2 max_stagnation = 10 mutation_params = { "mutation_rate": 0.7, "mutation_power": 0.5, "mutation_replace_rate": 0.1 } for e, enemies in enumerate(enemy_groups): env = Environment( experiment_name=experiment_name, enemies=enemies, multiplemode='yes', player_controller=player_controller(num_hidden_nodes)) for r in range(num_runs): population = init_population(population_size, 20, 5, num_hidden_nodes, initial_species) num_species = initial_species stagnation_array = [[0, -99] for _ in range(num_species) ] # [stagnation counter, max_fitness] winner = [None, 0] # [genome, fitness] # evaluate all individuals for g in range(max_generations): print("GENERATION", g)