Class: NEAT::Population
Overview
Population of NEAT Critters.
The Population In ourselves we have the pool of neurons the critters all use. the pool of neurons are indirects, of course, as during phenotype expression, all the phenotypes shall be created individually.
Instance Attribute Summary (collapse)
-
- (Object) critters
list of critter in this population.
-
- (Object) fitness
readonly
Overall population fitness and novelty.
-
- (Object) hidden_neurons
List of possible neuron classes for hidden neurons.
-
- (Object) input_neurons
Ordered list or hash of input neuron classes (all critters generated here shall have this).
-
- (Object) novelty
readonly
Overall population fitness and novelty.
-
- (Object) output_neurons
Ordered list or hash of output neuron classes (all critters generated here shall have this).
-
- (Object) species
readonly
Hash list of species lists.
-
- (Object) traits
Returns the value of attribute traits.
Attributes inherited from NeatOb
Class Method Summary (collapse)
- + (Object) compactify!(parm)
- + (Object) evaluate!
-
+ (Boolean) member?(crit)
lists keyed by representative critter.
Instance Method Summary (collapse)
-
- (Object) analyze!
Alalyze evaluation results.
-
- (Object) best_critter
The “best critter” is the critter with the lowest (closet to zero) fitness rating.
- - (Object) dump_s
-
- (Object) evaluate!
Called for each sequence.
-
- (Object) evolve
Call this after evaluation.
-
- (Object) express!
Express the entire population.
-
- (Population) initialize(c, &block)
constructor
Create initial (ramdom) population of critters.
-
- (Object) initialize_for_recurrence!
Make sure all critters are reset and prepared for recurrent network evaluation.
-
- (Object) mutate!
Mutate the genes and neurons.
-
- (Object) report
Generate a report on the state of this population.
-
- (Object) speciate!
Group critters into species Note that the @species objects have useful singleton methods: * @species.member? – checks all of the lists for membership, not just the hash * @species.fitness – fitness of the entire species.
-
- (Object) worst_critter
The “worst critter” is the critter with the highest (away from zero) fitness rating.
Methods inherited from NeatOb
Constructor Details
- (Population) initialize(c, &block)
Create initial (ramdom) population of critters
37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/rubyneat/population.rb', line 37 def initialize(c, &block) super @input_neurons = c.neural_inputs.clone @output_neurons = c.neural_outputs.clone @hidden_neurons = unless c.neural_hidden.nil? c.neural_hidden else c.neuron_catalog.keep_if {|n| not n.input?} end @critters = (0 ... c.parms.start_population_size || c.parms.population_size).map do Critter.new(self) end block.(self) unless block.nil? end |
Instance Attribute Details
- (Object) critters
list of critter in this population
25 26 27 |
# File 'lib/rubyneat/population.rb', line 25 def critters @critters end |
- (Object) fitness (readonly)
Overall population fitness and novelty
28 29 30 |
# File 'lib/rubyneat/population.rb', line 28 def fitness @fitness end |
- (Object) hidden_neurons
List of possible neuron classes for hidden neurons.
16 17 18 |
# File 'lib/rubyneat/population.rb', line 16 def hidden_neurons @hidden_neurons end |
- (Object) input_neurons
Ordered list or hash of input neuron classes (all critters generated here shall have this)
13 14 15 |
# File 'lib/rubyneat/population.rb', line 13 def input_neurons @input_neurons end |
- (Object) novelty (readonly)
Overall population fitness and novelty
28 29 30 |
# File 'lib/rubyneat/population.rb', line 28 def novelty @novelty end |
- (Object) output_neurons
Ordered list or hash of output neuron classes (all critters generated here shall have this)
20 21 22 |
# File 'lib/rubyneat/population.rb', line 20 def output_neurons @output_neurons end |
- (Object) species (readonly)
Hash list of species lists
31 32 33 |
# File 'lib/rubyneat/population.rb', line 31 def species @species end |
- (Object) traits
Returns the value of attribute traits
22 23 24 |
# File 'lib/rubyneat/population.rb', line 22 def traits @traits end |
Class Method Details
+ (Object) compactify!(parm)
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/rubyneat/population.rb', line 102 def @species.compactify!(parm) mutt = self[:mutt] = self.map { |k, splist| [k, splist]}.reject {|k, splist| splist.size >= parm.smallest_species }.map { |k, splist| self.delete k splist }.flatten # FIXME this code is not dry!!!! def mutt.fitness=(fit) @fitness = fit end def mutt.fitness @fitness end self.delete :mutt if self[:mutt].empty? end |
+ (Object) evaluate!
96 97 98 99 100 |
# File 'lib/rubyneat/population.rb', line 96 def @species.evaluate! self.each do |k, sp| sp.fitness = sp.map{|crit| crit.fitness}.reduce{|a,b| a+b} / sp.size end end |
+ (Boolean) member?(crit)
lists keyed by representative critter
92 93 94 |
# File 'lib/rubyneat/population.rb', line 92 def @species.member?(crit) super.member?(crit) or self.map{|k, li| li.member? crit}.reduce{|t1, t2| t1 or t2 } end |
Instance Method Details
- (Object) analyze!
Alalyze evaluation results.
74 75 76 |
# File 'lib/rubyneat/population.rb', line 74 def analyze! @critters.each { |critter| @controller.evaluator.analyze_for_fitness! critter } end |
- (Object) best_critter
The “best critter” is the critter with the lowest (closet to zero) fitness rating.
176 177 178 179 180 181 182 |
# File 'lib/rubyneat/population.rb', line 176 def best_critter unless @controller.compare_func.nil? @critters.min {|a, b| @controller.compare_func.(a.fitness, b.fitness) } else @critters.min {|a, b| a.fitness <=> b.fitness} end end |
- (Object) dump_s
194 195 196 |
# File 'lib/rubyneat/population.rb', line 194 def dump_s to_s + "\npopulation:\n" + @critters.map{|crit| crit.dump_s }.join("\n") end |
- (Object) evaluate!
Called for each sequence.
69 70 71 |
# File 'lib/rubyneat/population.rb', line 69 def evaluate! @critters.each { |critter| critter.evaluate! } end |
- (Object) evolve
Call this after evaluation. Returns a newly-evolved population.
80 81 82 |
# File 'lib/rubyneat/population.rb', line 80 def evolve @controller.evolver.evolve self end |
- (Object) express!
Express the entire population.
64 65 66 |
# File 'lib/rubyneat/population.rb', line 64 def express! @critters.each { |critter| critter.express! } end |
- (Object) initialize_for_recurrence!
Make sure all critters are reset and prepared for recurrent network evaluation.
54 55 56 |
# File 'lib/rubyneat/population.rb', line 54 def initialize_for_recurrence! @critters.each {|crit| crit.initialize_neurons!} end |
- (Object) mutate!
Mutate the genes and neurons.
59 60 61 |
# File 'lib/rubyneat/population.rb', line 59 def mutate! @controller.evolver.mutate! self end |
- (Object) report
Generate a report on the state of this population.
165 166 167 168 169 170 171 172 |
# File 'lib/rubyneat/population.rb', line 165 def report { fitness: report_fitness, fitness_species: report_fitness_species, best_critter: report_best_fit, worst_critter: report_worst_fit, } end |
- (Object) speciate!
Group critters into species Note that the @species objects have useful singleton methods:
-
@species.member? – checks all of the lists for membership, not just the hash
-
@species.fitness – fitness of the entire species
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/rubyneat/population.rb', line 89 def speciate! # We blow away existing species and create our own member? function @species = {} # lists keyed by representative critter def @species.member?(crit) super.member?(crit) or self.map{|k, li| li.member? crit}.reduce{|t1, t2| t1 or t2 } end def @species.evaluate! self.each do |k, sp| sp.fitness = sp.map{|crit| crit.fitness}.reduce{|a,b| a+b} / sp.size end end def @species.compactify!(parm) mutt = self[:mutt] = self.map { |k, splist| [k, splist]}.reject {|k, splist| splist.size >= parm.smallest_species }.map { |k, splist| self.delete k splist }.flatten # FIXME this code is not dry!!!! def mutt.fitness=(fit) @fitness = fit end def mutt.fitness @fitness end self.delete :mutt if self[:mutt].empty? end # Some convience parms parm = @controller.parms # And so now we iterate... @critters.each do |crit| wearein = false @species.each do |ck, list| delta = crit.compare(ck) #log.debug { "delta for #{crit} and #{ck} is #{delta}" } if delta < parm.compatibility_threshold list << crit wearein = true break end end # New species? unless wearein @species[crit] = species = [crit] def species.fitness=(fit) @fitness = fit end def species.fitness @fitness end end end # Compactify the species if less than smallest_species @species.compactify! parm # And now we evaluate all species for fitness... @species.evaluate! # Dump for debugging reasons @species.each do |k, sp| log.debug ">> Species #{k} has #{sp.size} members with a #{sp.fitness} fitness" end end |
- (Object) worst_critter
The “worst critter” is the critter with the highest (away from zero) fitness rating.
186 187 188 189 190 191 192 |
# File 'lib/rubyneat/population.rb', line 186 def worst_critter unless @controller.compare_func.nil? @critters.max {|a, b| @controller.compare_func.(a.fitness, b.fitness) } else @critters.max {|a, b| a.fitness <=> b.fitness} end end |