class GeneGenie::GenePool

Public Class Methods

build(template, fitness_evaluator) click to toggle source

build a GenePool with a reasonable set of defaults. You only need to specily the minimum no. of parameters

# File lib/gene_genie/gene_pool.rb, line 33
def self.build(template, fitness_evaluator)
  unless (template.instance_of? Array) && (template[0].instance_of? Hash)
    fail ArgumentError, 'template must be an array of hashes of ranges'
  end
  gene_mutator = SimpleGeneMutator.new(template)
  gene_factory = GeneFactory.new(template, fitness_evaluator)

  template_evaluator = TemplateEvaluator.new(template)
  size = template_evaluator.recommended_size
  GenePool.new(template: template,
               fitness_evaluator: fitness_evaluator,
               gene_factory: gene_factory,
               size: size,
               mutator: gene_mutator)
end
new(template:, fitness_evaluator:, gene_factory:, size: 10, mutator: NullMutator.new, selector: ProportionalSelector.new) click to toggle source
# File lib/gene_genie/gene_pool.rb, line 9
def initialize(template:,
               fitness_evaluator:,
               gene_factory:,
               size: 10,
               mutator: NullMutator.new,
               selector: ProportionalSelector.new)
  unless (template.instance_of? Array) && (template[0].instance_of? Hash)
    fail ArgumentError, 'template must be an array of hashes of ranges'
  end
  unless fitness_evaluator.respond_to?(:fitness)
    fail ArgumentError, 'fitness_evaluator must respond to fitness'
  end

  @template = template
  @fitness_evaluator = fitness_evaluator
  @mutator = mutator
  @selector = selector
  @pool = gene_factory.create(size)
  @generation = 0
  @listeners = []
end

Public Instance Methods

average_fitness() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 88
def average_fitness
  total_fitness / @pool.size
end
best() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 57
def best
  @pool.max_by(&:fitness)
end
best_ever() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 65
def best_ever
  @best_ever ||= best
end
best_fitness() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 61
def best_fitness
  best.fitness
end
evolve() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 69
def evolve
  old_best_fitness = best.fitness
  new_pool = []
  size.times do
    new_pool << select_genes_combine_and_mutate
  end
  @pool = new_pool
  check_best_ever
  @generation += 1

  @listeners.each { |l| l.call(self) }

  best.fitness > old_best_fitness
end
generation() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 84
def generation
  @generation
end
genes() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 96
def genes
  @pool
end
register_listener(listener) click to toggle source
# File lib/gene_genie/gene_pool.rb, line 49
def register_listener(listener)
  @listeners << listener
end
size() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 53
def size
  @pool.size
end
total_fitness() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 92
def total_fitness
  fitness_values.reduce(:+)
end
worst() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 100
def worst
  @pool.min_by(&:fitness)
end
worst_fitness() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 104
def worst_fitness
  worst.fitness
end

Private Instance Methods

check_best_ever() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 110
def check_best_ever
  @best_ever = best if best.fitness > best_ever.fitness
end
combine_genes(first, second) click to toggle source
# File lib/gene_genie/gene_pool.rb, line 118
def combine_genes(first, second)
  first.combine(second)
end
fitness_values() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 122
def fitness_values
  @pool.map(&:fitness)
end
select_genes() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 114
def select_genes
  @selector.call(self)
end
select_genes_combine_and_mutate() click to toggle source
# File lib/gene_genie/gene_pool.rb, line 126
def select_genes_combine_and_mutate
  first_gene, second_gene = select_genes
  new_gene = combine_genes(first_gene, second_gene)
  new_gene.mutate(@mutator)
end