class GA::Zoo
Attributes
after_select_callback[R]
before_fitness_callback[R]
unit_cls[R]
Public Class Methods
new(unit_cls)
click to toggle source
# File lib/ga/zoo.rb, line 5 def initialize(unit_cls) @unit_cls = unit_cls @debug = false @before_fitness_callback = nil @after_select_callback = nil @elite_policy = false @select_sample = 2 end
Public Instance Methods
after_select(&block)
click to toggle source
# File lib/ga/zoo.rb, line 48 def after_select(&block) @after_select_callback = block end
before_init_fitness(&block)
click to toggle source
# File lib/ga/zoo.rb, line 44 def before_init_fitness(&block) @before_fitness_callback = block end
debug!()
click to toggle source
# File lib/ga/zoo.rb, line 32 def debug! @debug = true end
elite_policy!()
click to toggle source
# File lib/ga/zoo.rb, line 40 def elite_policy! @elite_policy = true end
evolve(units = 32, generations = 100, crossover_rate = 0.8, mutation_rate = 0.15)
click to toggle source
# File lib/ga/zoo.rb, line 14 def evolve(units = 32, generations = 100, crossover_rate = 0.8, mutation_rate = 0.15) units = units.times.map { unit_cls.random_new } if units.is_a?(Fixnum) @start_at = Time.now generations.times do |i| @before_fitness_callback.call(units, i + 1) if @before_fitness_callback output_debug_info(units, generations, i + 1) if @debug units = select_units(units) @after_select_callback.call(units, i + 1) if @after_select_callback cross(units, crossover_rate) mutate(units, mutation_rate) end return units end
set_select_sample(val)
click to toggle source
# File lib/ga/zoo.rb, line 36 def set_select_sample(val) @select_sample = val end
Private Instance Methods
cross(units, rate)
click to toggle source
# File lib/ga/zoo.rb, line 73 def cross(units, rate) last_index = nil units.each_with_index do |unit, index| next if @elite_policy && index == 0 next if rand() >= rate if last_index units[last_index].cross!(unit) # recalculate fitness units[last_index].fitness = unit.fitness = nil last_index = nil else last_index = index end end end
mutate(units, rate)
click to toggle source
# File lib/ga/zoo.rb, line 91 def mutate(units, rate) units.each_with_index do |unit, index| next if @elite_policy && index == 0 next if rand() >= rate unit.mutate! # recalculate fitness unit.fitness = nil end end
output_debug_info(units, generations, generation)
click to toggle source
# File lib/ga/zoo.rb, line 101 def output_debug_info(units, generations, generation) units.sort! info = [ "[#{(Time.now - @start_at).to_f}]", "GA-#{generation}/#{generations} #{units.count}-#{units[-1].genome.length}", ' fitness: ' ] if units.length <= 7 then info << units.map(&:fitness).join(', ') else info << "#{units[0..2].map(&:fitness).join(', ')}" info << " ... #{units[units.length / 2].fitness}" info << " ... #{units[-5..-1].map(&:fitness).join(', ')}" end puts info.join end
select_units(units)
click to toggle source
# File lib/ga/zoo.rb, line 55 def select_units(units) new_units = units.map do ou = units.sample(@select_sample).max unit_cls.new(ou.genome).tap {|u| u.fitness = ou.fitness } end if @elite_policy min_index = new_units.index(new_units.min) if min_index != 0 then new_units[min_index], new_units[0] = new_units[0], new_units[min_index] end max_unit = units.max new_units[0] = unit_cls.new(max_unit.genome) end new_units end