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 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 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 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): # 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): 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 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 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): # 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 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): # 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 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): 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, 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) 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): # 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 post_evaluate(self, config, population, species, best_genome): # pylint: disable=no-self-use self.dict['Population_size'].append(len(population)) self.dict['Num_species'].append('--') self.dict['list_of_[ID,age,size,fitness,adj_fit,stag]'].append([]) self.dict['Total_extinctions'].append('--') self.dict['Generation_time'].append('--') self.dict['Average_time'].append('--') 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)) self.dict['Average_fitness'].append(fit_mean) self.dict['Stdev_fitness'].append(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)) self.dict['Best_genome_fitness'].append(best_genome.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 post_evaluate(self, config, population, species, best_genome): body = [] fitnesses = [c.fitness for c in itervalues(population)] fit_mean = mean(fitnesses) fit_std = stdev(fitnesses) fit_median = median(fitnesses) best_species_id = species.get_species_id(best_genome.key) with open('fitness_population', 'a') as f: f.write('{},{},{},{}\n'.format(fit_mean, fit_std, best_genome.fitness, fit_median)) with open('fitness_generation_{}'.format(self.generation), 'a') as g: for c in itervalues(population): g.write('{0},{1},{2}\n'.format(self.generation, c.key, c.fitness)) print( 'Population\'s average fitness: {0:3.5f} stdev: {1:3.5f} median: {2:3.5f}' .format(fit_mean, fit_std, fit_median)) print( 'Best fitness: {0:3.5f} - complexity: {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} median: {2:3.5f}\n' .format(fit_mean, fit_std, fit_median)) body.append( 'Best fitness: {0:3.5f} - complexity: {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('fitness_population', 'fitness_population.png') report(body, img)
def speciate(self, config: Config, population: Dict[int, DefaultGenome], generation: int): """ Place genomes into species by genetic similarity. Note that this method assumes the current representatives of the species are from the old generation, and that after speciation has been performed, the old representatives should be dropped and replaced with representatives from the new generation. If you violate this assumption, you should make sure other necessary parts of the code are updated to reflect the new behavior. ゲノムを遺伝的類似度によって種に配置する。 この方法は、現在の種の代表者が旧世代のものであると仮定しており、種分化が行われた後、旧世代の代表者は削除され、新世代の代表者と入れ替わるべきであることに注意してください。 この仮定に違反した場合は、コードの他の必要な部分が新しい動作を反映するように更新されていることを確認してください。 """ assert isinstance(population, dict) compatibility_threshold: float = self.species_set_config.compatibility_threshold # Find the best representatives for each existing species. # k+1世代の個体をこれから新しい種に振り分けていく unspeciated: Set[int] = set(population) distances: GenomeDistanceCache = GenomeDistanceCache( config.genome_config) # 種sidの新しい代表者ゲノムのID new_representatives: Dict[int, int] = {} # 種sidに含まれる個体たちのID new_members: Dict[int, List[int]] = {} # 1世代前であるk世代の種族ごと # このforでは1世代前の種族の代表に最も近い新しい代表者を取り出しているだけ(他のメンバは取り出していない) for sid, s in self.species.items(): candidates: List[Tuple[float, DefaultGenome]] = [] for gid in unspeciated: g = population[gid] # 前の世代のある種の代表s.representativeとgenome gの距離を計算 d = distances(s.representative, g) candidates.append((d, g)) # The new representative is the genome closest to the current representative. # sの代表者と最も距離が近いgenomeを取り出す rdistが距離 repが新しいk+1の代表者genome ignored_rdist, new_rep = min(candidates, key=lambda x: x[0]) new_rid: int = new_rep.key new_representatives[sid] = new_rid new_members[sid] = [new_rid] unspeciated.remove(new_rid) # Partition population into species based on genetic similarity. # まだ分類していないgenomeたちを類似度を用いて 代表者に近いものに割り振っていく # ただし似ていないものは新しいものにする while unspeciated: gid: int = unspeciated.pop() g: DefaultGenome = population[gid] # Find the species with the most similar representative. # 個体gと、新しい代表者たちと比較して 似ているものをcandidatesへ candidates: List[Tuple[float, int]] = [] for sid, rid in new_representatives.items(): rep: DefaultGenome = population[rid] d: float = distances(rep, g) if d < compatibility_threshold: candidates.append((d, sid)) # 最も似ている代表のグループに入れる if candidates: ignored_sdist, sid = min(candidates, key=lambda x: x[0]) new_members[sid].append(gid) else: # No species is similar enough, create a new species, using # this genome as its representative. # 新しく代表を作る sid: int = next(self.indexer) new_representatives[sid] = gid new_members[sid] = [gid] # Update species collection based on new speciation. # 新しくできたSp self.genome_to_species: Dict[int, int] = {} for sid, rid in new_representatives.items(): # 今のk+1世代の種族のID=sidとして、もし前k世代にもあるならその種族s=speciesとする # 各種族のSpeciesインスタンスを SpeciesSetのspecies辞書に入れる(単語が似ていて厄介) s: Optional[Species] = self.species.get(sid) if s is None: s = Species(sid, generation) self.species[sid] = s # k+1世代目の種sidに含まれる個体たち members: List[int] = new_members[sid] for gid in members: self.genome_to_species[gid] = sid # 種族s=sidの代表者とメンバーを更新する member_dict: Dict[int, DefaultGenome] = dict( (gid, population[gid]) for gid in members) s.update(population[rid], member_dict) gdmean: float = mean(distances.distances.values()) gdstdev: float = stdev(distances.distances.values()) self.reporters.info( "Mean genetic distance {0:.3f}, standard deviation {1:.3f}".format( gdmean, gdstdev))
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 speciate(self, config, population, generation): """ Place genomes into species by genetic similarity. Note that this method assumes the current representatives of the species are from the old generation, and that after speciation has been performed, the old representatives should be dropped and replaced with representatives from the new generation. If you violate this assumption, you should make sure other necessary parts of the code are updated to reflect the new behavior. """ ########################### ########################### ########################### #Gut this entire thing and put it into a list #what is being returned? #While Population: #member_dict = dict((GenomeID, population[GenomeID]) for GenomeID in Population) assert isinstance(population, dict) compatibility_threshold = self.species_set_config.compatibility_threshold # Find the best representatives for each existing species. unspeciated = set(population) distances = GenomeDistanceCache(config.genome_config) new_representatives = {} new_members = {} for sid, s in self.species.items(): candidates = [] for gid in unspeciated: g = population[gid] d = distances(s.representative, g) candidates.append((d, g)) # The new representative is the genome closest to the current representative. ignored_rdist, new_rep = min(candidates, key=lambda x: x[0]) new_rid = new_rep.key new_representatives[sid] = new_rid new_members[sid] = [new_rid] unspeciated.remove(new_rid) # Partition population into species based on genetic similarity. while unspeciated: gid = unspeciated.pop() g = population[gid] # Find the species with the most similar representative. candidates = [] for sid, rid in new_representatives.items(): rep = population[rid] d = distances(rep, g) if d < compatibility_threshold: candidates.append((d, sid)) if candidates: ignored_sdist, sid = min(candidates, key=lambda x: x[0]) new_members[sid].append(gid) else: # No species is similar enough, create a new species, using # this genome as its representative. sid = next(self.indexer) new_representatives[sid] = gid new_members[sid] = [gid] # Update species collection based on new speciation. self.genome_to_species = {} for sid, rid in new_representatives.items(): print(sid) s = self.species.get(sid) if s is None: s = Species(sid, generation) self.species[sid] = s members = new_members[sid] for gid in members: self.genome_to_species[gid] = sid ##################################### ##################################### ##################################### #These two lines are important because because they update population with the new species #Basically this is putting the populations representitive(RID Representitive ID) with member dict #member dict is a dictionary with genome ids and the genome for members. members is equal to new members #and represents the amount of members per population #all you need to do is set members equal to the population #Then you need to need to set the representitive id to 1 to represent the only population member_dict = dict((gid, population[gid]) for gid in members) s.update(population[rid], member_dict) ##################################### ##################################### ##################################### gdmean = mean(distances.distances.values()) gdstdev = stdev(distances.distances.values()) self.reporters.info( 'Mean genetic distance {0:.3f}, standard deviation {1:.3f}'.format( gdmean, gdstdev))
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 speciate(self, config, population, generation): """ ゲノムを遺伝的類似度によって種に配置する。 この方法は、現在の種の代表者が旧世代のものであると仮定しており、種分化が行われた後、旧世代の代表者は削除され、新世代の代表者と入れ替わるべきであることに注意してください。 この仮定に違反した場合は、コードの他の必要な部分が新しい動作を反映するように更新されていることを確認してください。 """ assert isinstance(population, dict) compatibility_threshold = self.species_set_config.compatibility_threshold # Find the best representatives for each existing species. unspeciated = set(population) distances = GenomeDistanceCache(config.genome_config) new_representatives = {} new_members = {} # 1世代前の種族ごと # このforでは1世代前の種族の代表に最も近い新しい代表者を取り出しているだけ(他のメンバは取り出していない) for sid, s in self.species.items(): # sid = 種族のキー 種族クラス (Species) candidates = [] # genomeのID=gid for gid in unspeciated: g = population[gid] # sの代表者とgenome gの距離を計算 d = distances(s.representative, g) candidates.append((d, g)) # The new representative is the genome closest to the current representative. # sの代表者と最も距離が近いgenomeを取り出す rdistが距離 repが新しい代表者genome ignored_rdist, new_rep = min(candidates, key=lambda x: x[0]) new_rid = new_rep.key new_representatives[sid] = new_rid new_members[sid] = [new_rid] unspeciated.remove(new_rid) # Partition population into species based on genetic similarity. # まだ分類していないgenomeたちを類似度を用いて 代表者に近いものに割り振っていく # ただし似ていないものは新しいものにする while unspeciated: gid = unspeciated.pop() g = population[gid] # Find the species with the most similar representative. candidates = [] for sid, rid in new_representatives.items(): rep = population[rid] d = distances(rep, g) # もしある種族の代表者repと gの類似度が似ているなら候補にいれる if d < compatibility_threshold: candidates.append((d, sid)) # 複数の種族に入ることができるときは最も近い代表のグループに入れる if candidates: ignored_sdist, sid = min(candidates, key=lambda x: x[0]) new_members[sid].append(gid) else: # No species is similar enough, create a new species, using # this genome as its representative. # 新しく代表を作る sid = next(self.indexer) new_representatives[sid] = gid new_members[sid] = [gid] # Update species collection based on new speciation. # 種族コレクションを新しく出来たSpeciationをもとに更新する self.genome_to_species = {} for sid, rid in new_representatives.items(): # 今の世代の種族のID=sidとして もし前世代にもあるならその種族s=speciesとする # 各種族のSpeciesインスタンスを SpeciesSetのspecies辞書に入れる(単語が似ていて厄介) s = self.species.get(sid) if s is None: s = Species(sid, generation) self.species[sid] = s members = new_members[sid] for gid in members: self.genome_to_species[gid] = sid member_dict = dict((gid, population[gid]) for gid in members) # 新しい種族sの代表者とそのメンバーをsに更新する s.update(population[rid], member_dict) gdmean = mean(distances.distances.values()) gdstdev = stdev(distances.distances.values()) self.reporters.info( 'Mean genetic distance {0:.3f}, standard deviation {1:.3f}'.format(gdmean, gdstdev))
def speciate(self, config, population): """ Place genomes into species by genetic similarity. Note that this method assumes the current representatives of the species are from the old generation, and that after speciation has been performed, the old representatives should be dropped and replaced with representatives from the new generation. If you violate this assumption, you should make sure other necessary parts of the code are updated to reflect the new behavior. """ assert type(population) is dict compatibility_threshold = config.species_set_config[ 'compatibility_threshold'] # Reset all species member lists. for s in itervalues(self.species): s.members.clear() self.to_species.clear() # Partition population into species based on genetic similarity. distances = [] for key, individual in iteritems(population): # Find the species with the most similar representative. min_distance = sys.float_info.max closest_species = None closest_species_id = None for sid, s in iteritems(self.species): rep = s.representative distance = individual.distance(rep, config.genome_config) distances.append(distance) compatible = distance < compatibility_threshold if compatible and distance < min_distance: closest_species = s closest_species_id = sid min_distance = distance if closest_species is not None: closest_species.add(key, individual) self.to_species[key] = closest_species_id else: # No species is similar enough, create a new species for this individual. sid = self.indexer.get_next() self.species[sid] = Species(sid, key, individual) self.to_species[key] = sid self.reporters.info('Mean genetic distance {0}, std dev {1}'.format( mean(distances), stdev(distances))) # Only keep non-empty species. empty_species_ids = [] for sid, s in iteritems(self.species): if not s.members: empty_species_ids.append(sid) for sid in empty_species_ids: del self.species[sid] # Select a random current member as the new representative. for s in itervalues(self.species): s.representative = random.choice(list(s.members.values()))
def speciate(self, config, population, generation): """ Place genomes into species by genetic similarity. Note that this method assumes the current representatives of the species are from the old generation, and that after speciation has been performed, the old representatives should be dropped and replaced with representatives from the new generation. If you violate this assumption, you should make sure other necessary parts of the code are updated to reflect the new behavior. """ assert isinstance(population, dict) compatibility_threshold = self.species_set_config.compatibility_threshold # Find the best representatives for each existing species. unspeciated = set(iterkeys(population)) distances = GenomeDistanceCache(config.genome_config) new_representatives = {} new_members = {} for sid, s in iteritems(self.species): candidates = [] for gid in unspeciated: g = population[gid] d = distances(s.representative, g) candidates.append((d, g)) # The new representative is the genome closest to the current representative. ignored_rdist, new_rep = min(candidates, key=lambda x: x[0]) new_rid = new_rep.key new_representatives[sid] = new_rid new_members[sid] = [new_rid] unspeciated.remove(new_rid) # Partition population into species based on genetic similarity. while unspeciated: gid = unspeciated.pop() g = population[gid] # Find the species with the most similar representative. candidates = [] for sid, rid in iteritems(new_representatives): rep = population[rid] d = distances(rep, g) if d < compatibility_threshold: candidates.append((d, sid)) if candidates: ignored_sdist, sid = min(candidates, key=lambda x: x[0]) new_members[sid].append(gid) else: # No species is similar enough, create a new species, using # this genome as its representative. sid = next(self.indexer) new_representatives[sid] = gid new_members[sid] = [gid] # Update species collection based on new speciation. self.genome_to_species = {} for sid, rid in iteritems(new_representatives): s = self.species.get(sid) if s is None: s = Species(sid, generation) self.species[sid] = s members = new_members[sid] for gid in members: self.genome_to_species[gid] = sid member_dict = dict((gid, population[gid]) for gid in members) s.update(population[rid], member_dict) gdmean = mean(itervalues(distances.distances)) gdstdev = stdev(itervalues(distances.distances)) self.reporters.info( 'Mean genetic distance {0:.3f}, standard deviation {1:.3f}'.format( gdmean, gdstdev))
def post_evaluate(self, config, population, species, best_genome): fitnesses = [c.fitness for c in itervalues(population)] self.__fit_mean = mean(fitnesses) self.__fit_stddev = stdev(fitnesses) self.__fit_best = best_genome.fitness