38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/genetic_algorithm.rb', line 38
def optimize(iterations, options = {}, &fitness)
GA.contract("You must pass the fitness function as a block") { fitness }
optimum = options[:optimum] || nil
GA.contract("Iterations must be more than 0") { iterations & iterations > 0 }
GA.contract("Optimum must be numeric (or nil)") { !optimum || optimum.is_a?(Numeric) }
population = @factory.population(@population_size)
elite = []
iterations.times do |i|
GA::Logger.info "Generation #{i}"
population.each { |chromosome| chromosome.fitness = fitness.call(chromosome) }
population = population - population.min(elite.size) { |chromosome| chromosome.fitness } + elite
elite = population.max(@elite * @population_size) { |chromosome| chromosome.fitness }
if optimum
return elite[0] if elite[0].fitness == optimum
end
population = @selection.apply(population)
population = @crossover.apply(population)
population = @mutation.apply(population)
@operators.each do |operator|
population = operator.apply(population)
end
GA::Logger.info { "Average fitness: #{population.map { |c| c.fitness }.sum.to_f / population.size}" }
end
return population.max { |chromosome| fitness.call(chromosome) }
end
|