def report(): print "\nNumber of runs: %s\n" % sys.argv[2] print "\t Gen. \t Nodes \t Conn. \t Evals. \t Score \n" print "average %3.2f \t %2.2f \t %2.2f \t %2.2f \t %2.2f" \ % (mean(total_gens), mean(total_nodes), mean(total_conns), mean(total_evals), mean(total_score)) print "stdev %3.2f \t %2.2f \t %2.2f \t %2.2f \t %2.2f" \ % (stdev(total_gens), stdev(total_nodes), stdev(total_conns), stdev(total_evals), stdev(total_score))
def post_evaluate(self, config, population, species, best_genome): sparse_mean, sparse_dev = self.compute_sparseness(population) fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) distances = [c.dist for c in itervalues(population)] dist_mean = mean(distances) dist_std = stdev(distances) best_species_id = species.get_species_id(best_genome.key) with open(self.filename, "a+") as f: print('Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'. format(fit_mean, fit_std)) f.write( 'Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}\n'. format(fit_mean, fit_std)) print('Population\'s diversity: {0:3.5f} stdev: {1:3.5f}'.format( dist_mean, dist_std)) f.write( 'Population\'s diversity: {0:3.5f} stdev: {1:3.5f}\n'.format( dist_mean, dist_std)) print('Population\'s sparseness: {0:3.5f} stdev: {1:3.5f}'.format( sparse_mean, sparse_dev)) f.write( 'Population\'s sparseness: {0:3.5f} stdev: {1:3.5f}\n'.format( sparse_mean, sparse_dev)) print('Best fitness: {}'.format(best_genome.fitness)) print( 'Best distance: {0:3.5f}\nSize: {1!r} - species {2} - id {3}'. format(best_genome.dist, best_genome.size(), best_species_id, best_genome.key)) f.write('Best fitness: {}\n'.format(best_genome.fitness)) f.write( 'Best distance: {0:3.5f}\nSize: {1!r} - species {2} - id {3}\n' .format(best_genome.dist, best_genome.size(), best_species_id, best_genome.key))
def report(): print "\nNumber of runs: {0!s}\n".format(sys.argv[2]) print "\t Gen. \t Nodes \t Conn. \t Evals. \t Score \n" print "average {0:3.2f} \t {1:2.2f} \t {2:2.2f} \t {3:2.2f} \t {4:2.2f}".format( mean(total_gens), mean(total_nodes), mean(total_conns), mean(total_evals), mean(total_score)) print "stdev {0:3.2f} \t {1:2.2f} \t {2:2.2f} \t {3:2.2f} \t {4:2.2f}".format( stdev(total_gens), stdev(total_nodes), stdev(total_conns), stdev(total_evals), stdev(total_score))
def compute_adjusted_fitness(all_fitnesses, remaining_species): min_fitness = min(all_fitnesses) max_fitness = max(all_fitnesses) fitness_range = max(1.0, max_fitness - min_fitness) for afs in remaining_species: msf = mean([m.fitness for m in itervalues(afs.members)]) af = (msf - min_fitness) / fitness_range afs.adjusted_fitness = af adjusted_fitnesses = [s.adjusted_fitness for s in remaining_species] avg_adjusted_fitness = mean(adjusted_fitnesses) return adjusted_fitnesses, avg_adjusted_fitness
def post_evaluate(self, config, population, species, best_genome): # pylint: disable=no-self-use fitnesses = [c.fitness for c in itervalues(population)] if type(fitnesses[0]) is float: fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) elif type(fitnesses[0]) is FitnessObj: fit_mean = mean_vector(fitnesses) fit_std = std_vector(fitnesses) else: fit_mean = 0 fit_std = 0 best_species_id = species.get_species_id(best_genome.key) print('Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'.format( fit_mean, fit_std)) print('Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}'. format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key)) with open(self.filename, "a+") as f: f.write( 'Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}\n'. format(fit_mean, fit_std)) f.write( 'Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}\n' .format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key))
def post_evaluate(self, config, population, species, best_genome): # pylint: disable=no-self-use fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) best_species_id = species.get_species_id(best_genome.key) best = None with open("risultati\seed" + str(self.seed) + ".csv", 'a') as f: for key in population: if best is None: best = population[key] if population[key].fitness > best.fitness: best = population[key] f.write( str(fit_mean) + "," + str(fit_std) + "," + str(best.fitness)) f.write("\n") with gzip.open("migliori_genomi\seed" + str(self.seed), 'a', compresslevel=5) as f: pickle.dump(best, f, protocol=pickle.HIGHEST_PROTOCOL) #pickle.dump("\n;\n", f, protocol=pickle.HIGHEST_PROTOCOL) print('Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'.format( fit_mean, fit_std)) print('Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}'. format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key))
def post_evaluate(self, config, population, species, best_genome): # Ordinary report if not novelty search if config.novelty is None: StdOutReporter.post_evaluate( self, config, population, species, best_genome) # Special report for novelty search else: novelties = [c.fitness for c in population.values()] nov_mean = mean(novelties) nov_std = stdev(novelties) best_species_id = species.get_species_id(best_genome.key) print('Population\'s average novelty: %3.5f stdev: %3.5f' % (nov_mean, nov_std)) print('Best novelty: %3.5f - size: (%d,%d) - species %d - id %d' % (best_genome.fitness, best_genome.size()[0], best_genome.size()[1], best_species_id, best_genome.key)) print('Best actual fitness: %f ' % best_genome.actual_fitness) print('Evaluations this generation: %d' % config.current_evaluations)
def post_evaluate(self, config, population, species, best_genome): # pylint: disable=no-self-use fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) best_species_id = species.get_species_id(best_genome.key) '''
def get_species_fitness(self, null_value: str = '' ) -> List[List[Union[str, float]]]: """ 世代数だけの長さの配列を返す ret[x][sid] = x世代目における種sidに含まれる個体全体の平均適応度 """ # 世代全体で出現した種IDセット all_species: Set[int] = set() for gen_data in self.generation_statistics: all_species: Set[int] = all_species.union(gen_data.keys()) max_species: int = max(all_species) # 各世代における各種の適応度の平均 # species_fitness[x][sid] = x世代目における種sidに含まれる全個体の適応度の平均 species_fitness: List[List[Union[str, float]]] = [] for gen_data in self.generation_statistics: # ある世代における 各種に含まれる各個体の適応度 member_fitness: List[Union[Dict[int, float], List]] = [ gen_data.get(sid, []) for sid in range(1, max_species + 1) ] fitness: List[Union[str, float]] = [] for mf in member_fitness: if mf: fitness.append(mean(mf)) else: fitness.append(null_value) species_fitness.append(fitness) return species_fitness
def post_evaluate(self, config, population, species, best_genome): # pylint: disable=no-self-use body = [] fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) best_species_id = species.get_species_id(best_genome.key) with open('fitplot', 'a') as f: f.write('{},{},{}\n'.format(fit_mean, fit_std, best_genome.fitness)) print('Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'.format( fit_mean, fit_std)) print('Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}'. format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key)) body.append( 'Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}\n'.format( fit_mean, fit_std)) body.append( 'Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}\n'. format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key)) if body: img = plot_fitness_over_gen('fitplot', 'fitplot.png') report(body, img)
def post_evaluate(self, config, population, species, best_genome): fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) best_species_id = species.get_species_id(best_genome.key) print('Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'.format(fit_mean, fit_std)) print('Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}'.format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key))
def get_average_fitness(population): avg_fitness = [] for stats in population.generation_statistics: scores = [] for fitness in stats.values(): scores.extend(fitness) avg_fitness.append(mean(scores)) return avg_fitness
def post_evaluate(self, config, population, species, best_genome): if not self.ctr % self.freq: self.best.append(best_genome.modularity()) modularities = [g.modularity() for g in itervalues(population)] self.means.append(mean(modularities)) self.stddevs.append(stdev(modularities)) print( "\n\nMODULARITY (MOST FIT): {:.4f}\nMEAN MODULARITY: {:.4f}\n\n" .format(self.best[-1], self.means[-1])) self.ctr += 1
def get_average_cross_validation_fitness(self): """Get the per-generation average cross_validation fitness.""" avg_cross_validation_fitness = [] for stats in self.generation_cross_validation_statistics: scores = [] for fitness in stats.values(): scores.extend(fitness) avg_cross_validation_fitness.append(mean(scores)) return avg_cross_validation_fitness
def post_evaluate(self, config, population, species, best_genome): # pylint: disable=no-self-use fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) best_species_id = species.get_species_id(best_genome.key) log.info('Population\'s average fitness: %f stdev: %f', fit_mean, fit_std) log.info('Best fitness: %f - size: %d - species %s - id %s', best_genome.fitness, best_genome.size(), best_species_id, best_genome.key)
def post_evaluate(self, population, species, best): fit_mean = mean([c.fitness for c in population]) fit_std = stdev([c.fitness for c in population]) print('Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'.format(fit_mean, fit_std)) print('Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}'.format(best.fitness, best.size(), best.species_id, best.ID)) print('Species length: {0:d} totaling {1:d} individuals'.format(len(species), sum( [len(s.members) for s in species]))) print('Species ID : {0!s}'.format([s.ID for s in species])) print('Species size : {0!s}'.format([len(s.members) for s in species])) print('Species age : {0}'.format([s.age for s in species]))
def post_evaluate(self, config, population, species, best_genome): fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) species_ids = list(iterkeys(species.species)) for i in species_ids: s = species.species[i] self.log(self.generation, i, s.fitness, fit_mean) best_genome = None for g in itervalues(s.members): if best_genome is None or (g.fitness > best_genome.fitness): best_genome = g
def compute_adjusted_fitness(all_fitnesses, remaining_species): min_fitness = min(all_fitnesses) max_fitness = max(all_fitnesses) # Do not allow the fitness range to be zero, as we divide by it below. fitness_range = max(FitnessObj(0.1, 1), max_fitness - min_fitness) for afs in remaining_species: # Compute adjusted fitness. array = [m.fitness for m in itervalues(afs.members)] if type(array[0]) is FitnessObj: msf = mean_vector(array) else: msf = mean(array) af = (msf - min_fitness) / fitness_range afs.adjusted_fitness = af adjusted_fitnesses = [s.adjusted_fitness for s in remaining_species] if type(adjusted_fitnesses[0]) is FitnessObj: avg_adjusted_fitness = mean_vector(adjusted_fitnesses) else: avg_adjusted_fitness = mean(adjusted_fitnesses) return adjusted_fitnesses, avg_adjusted_fitness
def post_evaluate(self, config, population, species, best_genome): print("Here") fitnesses = [c.fitness for c in itervalues(population)] self.mean_arr.append(mean(fitnesses)) self.best_arr.append(best_genome.fitness) # Show the thing length_range = arange(len(self.mean_arr)) plt.plot(length_range, self.mean_arr, 'r--', length_range, self.best_arr, 'b') plt.pause(0.000001)
def average_fitness(self): """ Returns the raw average fitness for this species """ avg_fitness = mean([c.fitness for c in self.members]) # Check for increase in mean fitness and adjust "no improvement" count as necessary. if avg_fitness > self.last_avg_fitness: self.last_avg_fitness = avg_fitness self.no_improvement_age = 0 else: self.no_improvement_age += 1 return avg_fitness
def post_evaluate(self, config, population, species, best_genome): # pylint: disable=no-self-use fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) best_species_id = species.get_species_id(best_genome.key) outputString = ''; outputString += ('Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'.format(fit_mean, fit_std)) + '\n' outputString += ('Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}'.format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key)) + '\n'; self.output(outputString);
def post_evaluate(self, config: Config, population: Dict[int, DefaultGenome], species_set: DefaultSpeciesSet, best_genome: DefaultGenome) -> None: # pylint: disable=no-self-use fitnesses: List[float] = [c.fitness for c in population.values()] fit_mean: float = mean(fitnesses) fit_std: float = stdev(fitnesses) best_species_id: int = species_set.get_species_id(best_genome.key) print('Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'.format( fit_mean, fit_std)) print('Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}'. format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key))
def bench(num_runs): results = [] while len(results) < num_runs: try: result = run() except population.CompleteExtinctionException: continue results.append(result) if len(results) % 10 == 0: print("Completed run %d of %d" % (len(results), num_runs)) generations = [r[0] for r in results] hidden = [r[1] for r in results] connections = [r[2] for r in results] enabled = [r[3] for r in results] print(" mean (stdev)") print(" Generations: %.3f (%.3f)" % (mean(generations), stdev(generations))) print("hidden nodes: %.3f (%.3f)" % (mean(hidden), stdev(hidden))) print(" connections: %.3f (%.3f)" % (mean(connections), stdev(connections))) print(" enabled: %.3f (%.3f)" % (mean(enabled), stdev(enabled)))
def post_evaluate(self, config, population, species, best_genome): fits = [c.actual_fitness for c in population.values()] # Save current generation info to history file fit_max = max(fits) self.csvfile.write('%d,%f,%+5.3f,%+5.3f,%+5.3f' % (config.gen, time() - self.start, mean(fits), stdev(fits), fit_max)) if config.is_novelty(): novs = [c.fitness for c in population.values()] self.csvfile.write(',%+5.3f,%+5.3f,%+5.3f' % (mean(novs), stdev(novs), max(novs))) self.csvfile.write('\n') self.csvfile.flush() # Track best if self.checkpoint and fit_max > self.best_fitness: self.best_fitness = fit_max print('############# Saving new best %f ##############' % self.best_fitness) config.save_genome(best_genome)
def post_evaluate(self, config, population, species, best_genome): if config.novelty is None: StdOutReporter.post_evaluate(self, config, population, species, best_genome) return fitnesses = [c.fitness for c in population.values()] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) best_species_id = species.get_species_id(best_genome.key) print('Population\'s average novelty: {0:3.5f} stdev: {1:3.5f}'.format( fit_mean, fit_std)) print('Best novelty: {0:3.5f} - size: {1!r} - species {2} - id {3}'. format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key)) print('Best actual fitness: %f ' % best_genome.actual_fitness)
def post_evaluate(self, config, population, species, best_genome): # pylint: disable=no-self-use fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) best_species_id = species.get_species_id(best_genome.key) fd = open(self.filename, 'a') fd.write( 'Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}\n'.format( fit_mean, fit_std)) fd.write( 'Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}\n'. format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key)) fd.close()
def post_evaluate(self, config, population, species, best_genome): # pylint: disable=no-self-use fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) best_species_id = species.get_species_id(best_genome.key) print('Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'.format( fit_mean, fit_std)) print('Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}'. format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key)) # andrew add if (best_genome.fitness > self.bestFitness): res = open("result.txt", "a") res.write('\nBest genome:\n{!s}'.format(best_genome)) res.close()
def post_evaluate(self, config, population, species, best_genome, score_max, score_mean): # pylint: disable=no-self-use fitnesses = [c.fitness for c in population.values()] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) score_max.append(max(fitnesses)) score_mean.append(fit_mean) best_species_id = species.get_species_id(best_genome.key) print('Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'.format( fit_mean, fit_std)) print('Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}'. format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key))
def post_evaluate(self, config, population, species, best_genome): # pylint: disable=no-self-use fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) best_species_id = species.get_species_id(best_genome.key) self.stream( 'Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'.format( fit_mean, fit_std)) self.stream( 'Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}'. format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key)) msk = "[" + ", ".join( [f"{x:,.0f}" for x in best_genome.metascorekeeper.score_listing()]) + "]" self.stream(f"Metascorekeeper summary: {msk}")
def post_evaluate(self, config, population, species, best_genome): # pylint: disable=no-self-use fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) best_species_id = species.get_species_id(best_genome.key) self._logger.info( 'Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'.format( fit_mean, fit_std)) self._logger.info( 'Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}'. format(best_genome.fitness, best_genome.size(), best_species_id, best_genome.key)) self._mlflow.log_metric(key="best_fitness", value=best_genome.fitness) self._mlflow.log_metric(key="best_fitness_species", value=best_species_id) self._mlflow.log_metric(key="best_fitness_id", value=best_genome.key)
def get_species_fitness(population, null_value=''): all_species = set() for gen_data in population.generation_statistics: all_species = all_species.union(gen_data.keys()) max_species = max(all_species) species_fitness = [] for gen_data in population.generation_statistics: member_fitness = [gen_data.get(sid, []) for sid in range(1, max_species + 1)] fitness = [] for mf in member_fitness: if mf: fitness.append(mean(mf)) else: fitness.append(null_value) species_fitness.append(fitness) return species_fitness
def plot_fitness(checkpoints, name): gens = [c.generation for c in checkpoints] bests = [c.best_genome.fitness for c in checkpoints] avgs = [mean([f.fitness for _, f in c.population.items()]) for c in checkpoints] fig, ax = plt.subplots(figsize = (10,5)) ax.set_title(name+" - Fitness over Generations") ax.plot(gens, bests, color='blue', linewidth=1, label="Best") ax.plot(gens, avgs, color='black', linewidth=1, label="Average") ax.legend() ax.set_xlabel('Generation') ax.set_ylabel('Fitness (Flight Time)') plt.tight_layout() fig.savefig(name+'.png', format='png', dpi=300) plt.show() plt.close()
def get_species_fitness(self, null_value=''): all_species = set() for gen_data in self.generation_statistics: all_species = all_species.union(gen_data.keys()) max_species = max(all_species) species_fitness = [] for gen_data in self.generation_statistics: member_fitness = [gen_data.get(sid, []) for sid in range(1, max_species + 1)] fitness = [] for mf in member_fitness: if mf: fitness.append(mean(mf)) else: fitness.append(null_value) species_fitness.append(fitness) return species_fitness
def post_evaluate(self, population, species, best): fit_mean = mean([c.fitness for c in population]) fit_std = stdev([c.fitness for c in population]) print('Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}' .format(fit_mean, fit_std)) print('Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}' .format(best.fitness, best.size(), best.species_id, best.ID)) print('Species length: {0:d} totaling {1:d} individuals' .format(len(species), sum([len(s.members) for s in species]))) print('Species ID : {0!s}'.format([s.ID for s in species])) print('Species size : {0!s}' .format([len(s.members) for s in species])) print('Species age : {0}'.format([s.age for s in species])) [cl.write_message(('\n Fitness promedio de la poblacion: {0:3.5f}' + ' Desviacion: {1:3.5f}') .format(fit_mean, fit_std)) for cl in clientes] [cl.write_message( '\n Mejor fitness: {0:3.5f} - size: {1!r} - Especie {2} - ID {3}\n' .format(best.fitness, best.size(), best.species_id, best.ID)) for cl in clientes]
def get_average_fitness(self): """ Returns the average fitness over all members in the species.""" return mean([c.fitness for c in self.members])
def species_mean_fitness(species): return mean([m.fitness for m in species.members])
def epoch(self, fitness_function, n, report=True, save_best=False, checkpoint_interval=10, checkpoint_generation=None): """ Runs NEAT's genetic algorithm for n epochs. Keyword arguments: report -- show stats at each epoch (default True) save_best -- save the best genome from each epoch (default False) checkpoint_interval -- time in minutes between saving checkpoints (default 10 minutes) checkpoint_generation -- time in generations between saving checkpoints (default None -- option disabled) """ t0 = time.time() # for saving checkpoints for g in range(n): self.generation += 1 if report: print('\n ****** Running generation %d ****** \n' % self.generation) # Evaluate individuals fitness_function(self.population) # Speciates the population self.__speciate(report) # Current generation's best genome self.most_fit_genomes.append(max(self.population)) # Current population's average fitness self.avg_fitness_scores.append(mean([c.fitness for c in self.population])) # Print some statistics best = self.most_fit_genomes[-1] # saves the best genome from the current generation if save_best: f = open('best_genome_' + str(self.generation), 'w') pickle.dump(best, f) f.close() # Stops the simulation if best.fitness > self.config.max_fitness_threshold: if report: print('\nBest individual in epoch %s meets fitness threshold - complexity: %s' % ( self.generation, best.size())) break # Remove stagnated species and its members (except if it has the best genome) for s in self.__species[:]: if s.no_improvement_age > self.config.max_stagnation: if report: print("\n Species %2d (with %2d individuals) is stagnated: removing it" \ % (s.ID, len(s.members))) # removing species self.__species.remove(s) # removing all the species' members # TODO: can be optimized! for c in self.population[:]: if c.species_id == s.ID: self.population.remove(c) # Compute spawn levels for each remaining species self.diversity.compute_spawn_amount(self.__species) # Removing species with spawn amount = 0 for s in self.__species[:]: # This rarely happens if s.spawn_amount == 0: if report: print(' Species %2d age %2s removed: produced no offspring' % (s.ID, s.age)) for c in self.population[:]: if c.species_id == s.ID: self.population.remove(c) # self.remove(c) self.__species.remove(s) # Logging speciation stats self.__log_species() if report: if self.population: std_dev = stdev([c.fitness for c in self.population]) print('Population\'s average fitness: %3.5f stdev: %3.5f' % (self.avg_fitness_scores[-1], std_dev)) print('Best fitness: %2.12s - size: %s - species %s - id %s' \ % (best.fitness, best.size(), best.species_id, best.ID)) print('Species length: %d totaling %d individuals' \ % (len(self.__species), sum([len(s.members) for s in self.__species]))) print('Species ID : %s' % [s.ID for s in self.__species]) print('Each species size: %s' % [len(s.members) for s in self.__species]) print('Amount to spawn : %s' % [s.spawn_amount for s in self.__species]) print('Species age : %s' % [s.age for s in self.__species]) print('Species no improv: %s' % [s.no_improvement_age for s in self.__species]) else: print('All species extinct.') # -------------------------- Producing new offspring -------------------------- # new_population = [] # next generation's population # If no species are left, create a new population from scratch, otherwise top off # population by reproducing existing species. if self.__species: for s in self.__species: new_population.extend(s.reproduce(self.config)) # Controls under or overflow # fill = self.config.pop_size - len(new_population) if fill < 0: # overflow if report: print(' Removing %d excess individual(s) from the new population' % -fill) # TODO: This is dangerous! I can't remove a species' representative! new_population = new_population[:fill] # Removing the last added members if fill > 0: # underflow if report: print(' Producing %d more individual(s) to fill up the new population' % fill) # TODO: what about producing new individuals instead of reproducing? # increasing diversity from time to time might help while fill > 0: # Selects a random genome from population parent1 = random.choice(self.population) # Search for a mate within the same species found = False for c in self.population: # what if c is parent1 itself? if c.species_id == parent1.species_id: child = parent1.crossover(c) new_population.append(child.mutate()) found = True break if not found: # If no mate was found, just mutate it new_population.append(parent1.mutate()) # new_population.append(genome.FFGenome.create_fully_connected()) fill -= 1 assert self.config.pop_size == len(new_population), 'Different population sizes!' # Updates current population self.population = new_population[:] else: self.__create_population() if checkpoint_interval is not None and time.time() > t0 + 60 * checkpoint_interval: self.__create_checkpoint(report) t0 = time.time() # updates the counter elif checkpoint_generation is not None and self.generation % checkpoint_generation == 0: self.__create_checkpoint(report)
def epoch(self, fitness_function, n): """ Runs NEAT's genetic algorithm for n epochs. """ t0 = time.time() # for saving checkpoints for g in range(n): self.generation += 1 if self.config.report: print('\n ****** Running generation {0} ****** \n'.format(self.generation)) gen_start = time.time() # Collect a list of all members from all species. population = [] for s in self.species: population.extend(s.members) # Evaluate individuals fitness_function(population) self.total_evaluations += len(population) # Gather statistics. self._log_stats(population) # Print some statistics best = self.most_fit_genomes[-1] if self.config.report: fit_mean = mean([c.fitness for c in population]) fit_std = stdev([c.fitness for c in population]) print('Population\'s average fitness: {0:3.5f} stdev: {1:3.5f}'.format(fit_mean, fit_std)) print('Best fitness: {0:3.5f} - size: {1!r} - species {2} - id {3}'.format(best.fitness, best.size(), best.species_id, best.ID)) print('Species length: {0:d} totaling {1:d} individuals'.format(len(self.species), sum( [len(s.members) for s in self.species]))) print('Species ID : {0!s}'.format([s.ID for s in self.species])) print('Species size : {0!s}'.format([len(s.members) for s in self.species])) print('Amount to spawn : {0!s}'.format([s.spawn_amount for s in self.species])) print('Species age : {0}'.format([s.age for s in self.species])) print('Species fitness : {0!r}'.format([s.get_average_fitness() for s in self.species])) print('Species no improv: {0!r}'.format([s.no_improvement_age for s in self.species])) # Saves the best genome from the current generation if requested. if self.config.save_best: with open('best_genome_' + str(self.generation), 'wb') as f: pickle.dump(best, f) # End when the fitness threshold is reached. if best.fitness >= self.config.max_fitness_threshold: if self.config.report: print('\nBest individual in epoch {0} meets fitness threshold - complexity: {1!r}'.format( self.generation, best.size())) break # Remove stagnated species. # TODO: Log species removal for visualization purposes. # TODO: Provide some sort of optional cross-species performance criteria, which # are then used to control stagnation and possibly the mutation rate configuration. # This scheme should be adaptive so that species do not evolve to become "cautious" # and only make very slow progress. new_species = [] for s in self.species: s.update_stagnation() if s.no_improvement_age <= self.config.max_stagnation: new_species.append(s) else: if self.config.report: print("\n Species {0} with {1} members is stagnated: removing it".format(s.ID, len(s.members))) self.species = new_species # TODO: Break these out into user-configurable classes # 1. Species survival determination (currently hard-coded to be stagnation with a fixed number of generations). # 2. Species spawn allotment (currently provided in the diversity object). # Check for complete extinction. new_population = [] if not self.species: if self.config.report: print('All species extinct.') # If requested by the user, create a completely new population, # otherwise raise an exception. if self.config.reset_on_extinction: new_population = self._create_population() else: raise MassExtinctionException() else: # Compute spawn levels for all current species and then reproduce. self.diversity.compute_spawn_amount(self.species) for s in self.species: # Verify that all species received non-zero spawn counts, as the speciation mechanism # is intended to allow initially less fit species time to improve before making them # extinct via the stagnation mechanism. assert s.spawn_amount > 0 # The Species.reproduce keeps one random child as its new representative, and # returns the rest as a list, which must be sorted into species. new_population.extend(s.reproduce(self.config, self.genome_indexer)) self._speciate(new_population) if self.config.checkpoint_interval is not None and time.time() > t0 + 60 * self.config.checkpoint_interval: if self.config.report: print('Creating timed checkpoint file at generation: {0}'.format(self.generation)) self.save_checkpoint() # Update the checkpoint time. t0 = time.time() elif self.config.checkpoint_generation is not None and self.generation % self.config.checkpoint_generation == 0: if self.config.report: print('Creating generation checkpoint file at generation: {0}'.format(self.generation)) self.save_checkpoint() if self.config.report: print("Generation time: {0:.3f} sec".format(time.time() - gen_start))
def report(): print "\nNumber of runs: {0!s}\n".format(sys.argv[2]) print "\t Gen. \t Nodes \t Conn. \t Evals. \t Score \n" print "average {0:3.2f} \t {1:2.2f} \t {2:2.2f} \t {3:2.2f} \t {4:2.2f}".format(mean(total_gens), mean(total_nodes), mean(total_conns), mean(total_evals), mean(total_score)) print "stdev {0:3.2f} \t {1:2.2f} \t {2:2.2f} \t {3:2.2f} \t {4:2.2f}".format(stdev(total_gens), stdev(total_nodes), stdev(total_conns), stdev(total_evals), stdev(total_score))