| Class | Population |
| In: |
lib/charlie/population.rb
|
| Parent: | Array |
The population class represents an array of genotypes. Create an instance of this, and call one of the evolve functions to run the genetic algorithm.
| DEFAULT_MAX_GENS | = | 100 |
| DEFAULT_POP_SIZE | = | 20 |
| max | -> | best |
| replace | -> | population= |
| backwards compatibility, replaces population array | ||
| evolve_multiple_until_best | -> | evolve_multiple_until |
| genotype_class | [R] |
Effectively runs Population#evolve_block n_runs times. Returns the entire population of all results (n_runs * population_size elements)
# File lib/charlie/population.rb, line 85
85: def self.evolve_multiple(genotype_class,population_size=DEFAULT_POP_SIZE,
86: n_runs=25,
87: generations=DEFAULT_MAX_GENS)
88: r = evolve_multiple_until_population(genotype_class,population_size, n_runs, generations, 10000) {|pop| false }
89: r.first
90: end
Effectively runs Population#evolve_until_best multiple times.
Aliased also as Population.evolve_multiple_until.
# File lib/charlie/population.rb, line 96
96: def self.evolve_multiple_until_best(*args,&b)
97: evolve_multiple_until_population(*args) {|pop| b.call(pop.max) }
98: end
Runs Population#evolve_until_population multiple times.
# File lib/charlie/population.rb, line 105
105: def self.evolve_multiple_until_population(genotype_class,population_size=DEFAULT_POP_SIZE,
106: max_tries=25,
107: generations=DEFAULT_MAX_GENS,check_every=10)
108: tot_gens = 0
109: all_pop = []
110: max_tries.times{
111: pop, gens = Population.new(genotype_class,population_size).evolve_until_population(generations,check_every){|p|
112: yield(p)
113: }
114: all_pop += pop
115: tot_gens += gens || generations
116: if gens
117: return [pop, tot_gens]
118: end
119: }
120: [all_pop, nil]
121: end
# File lib/charlie/population.rb, line 10
10: def initialize(genotype_class,population_size=DEFAULT_POP_SIZE)
11: @genotype_class = genotype_class
12: replace Array.new(population_size){ genotype_class.new }
13: end
Yields the population and the generation number to block for each generation at a maximum of max_generations times.
# File lib/charlie/population.rb, line 16
16: def evolve_block(max_generations=DEFAULT_MAX_GENS)
17: yield self, 0
18: (max_generations || DEFAULT_MAX_GENS).times {|generation|
19: self.population = @genotype_class.next_generation(self){|*parents|
20: ch = [*@genotype_class.cross(*parents)]
21: ch.each{|c| c.mutate! }
22: ch
23: }
24: yield self, generation+1
25: }
26: self
27: end
Runs the genetic algorithm with some stats on the console. Returns the population sorted by fitness.
# File lib/charlie/population.rb, line 37
37: def evolve_on_console(generations=DEFAULT_MAX_GENS)
38: puts "Generation\tBest Fitness\t\tBest Individual"
39: evolve_block(generations) {|p,g|
40: best = p.max
41: puts "#{g}\t\t#{best.fitness}\t\t#{best.to_s}"
42: }
43: self.population = self.sort_by{|x|x.fitness}
44: puts "Finished: Best fitness = #{self[-1].fitness}"
45: self
46: end
Runs the genetic algorithm without any output. Returns the population sorted by fitness (unsorted for co-evolution).
# File lib/charlie/population.rb, line 30
30: def evolve_silent(generations=DEFAULT_MAX_GENS)
31: evolve_block(generations){}
32: sort_by!{|x|x.fitness} rescue nil
33: self
34: end
breaks if the block (which is passed the best individual each "check_every" generations) returns true. returns an array [population, generations needed]. generations needed==nil for no convergence.
# File lib/charlie/population.rb, line 64
64: def evolve_until_best(generations=DEFAULT_MAX_GENS,check_every=10)
65: tot_gens = nil
66: evolve_block(generations) {|p,g|
67: if (g % check_every).zero? && yield(p.max)
68: tot_gens = g
69: break
70: end
71: }
72: [self, tot_gens]
73: end
breaks if the block (which is passed the population each "check_every" generations) returns true. returns an array [population, generations needed]. generations needed==nil for no convergence.
# File lib/charlie/population.rb, line 51
51: def evolve_until_population(generations=DEFAULT_MAX_GENS,check_every=10)
52: tot_gens = nil
53: evolve_block(generations) {|p,g|
54: if (g % check_every).zero? && yield(p)
55: tot_gens = g
56: break
57: end
58: }
59: [self, tot_gens]
60: end