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.

Methods

Constants

DEFAULT_MAX_GENS = 100
DEFAULT_POP_SIZE = 20

External Aliases

max -> best
replace -> population=
  backwards compatibility, replaces population array
evolve_multiple_until_best -> evolve_multiple_until

Attributes

genotype_class  [R] 

Public Class methods

Effectively runs Population#evolve_block n_runs times. Returns the entire population of all results (n_runs * population_size elements)

[Source]

    # 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.

[Source]

    # 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.

  • genotype_class,population_size are arguments for Population.new
  • max_tries is the maximum number of restarts.
  • Returns [population, generations needed] on success where population is the population of the successful run.
  • Returns [population_all, nil] on failure, where population_all is the combined population of all runs.

[Source]

     # 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

[Source]

    # 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

Public Instance methods

evolve(generations=DEFAULT_MAX_GENS)

Alias for evolve_on_console

Yields the population and the generation number to block for each generation at a maximum of max_generations times.

[Source]

    # 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.

[Source]

    # 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).

[Source]

    # 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
evolve_until(generations=DEFAULT_MAX_GENS,check_every=10)

Alias for evolve_until_best

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.

[Source]

    # 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.

[Source]

    # 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

backwards compatibility, returns self

[Source]

    # File lib/charlie/population.rb, line 78
78:   def population; self; end

[Validate]