Les algorithmes génétiques démystifiés 19
Suite et fin de la transformation en code orienté objet de l’algorithme génétique sur le paradoxe du singe savant.
Le rôle de la classe MatingPool
est de sélectionner les individus pour
la reproduction, suivant la méthode de la roue de la fortune:
class MatingPool
def initialize(population)
@mating_pool = []
population.each do |individual|
integer_part = individual.fitness.to_i
real_part = individual.fitness - integer_part
integer_part.times { @mating_pool << individual.dup }
@mating_pool << individual.dup if rand < real_part
end
@size = @mating_pool.size
end
def random
@mating_pool[rand(@size)]
end
end
Au passage, la méthode random
permettra de choisir un parent au hasard.
Les classes Crossover
et Mutator
s’occupent bien sûr de la partie
reproduction:
class Crossover
def initialize(chromosome_size, mutation_rate)
@size = chromosome_size
@rate = mutation_rate
@mutator = Mutator.new(@size, @rate)
end
def two_point(parent1, parent2)
child = assemble(parent1, parent2, two_cut_points)
child = @mutator.mutate(child)
Individual.from_chromosome(child)
end
private
def two_cut_points
point1 = cut_point
point2 = cut_point
point1, point2 = point2, point1 if point1 > point2
[point1, point2]
end
def cut_point
rand(@size)
end
def assemble(parent1, parent2, points)
point1, point2 = points
parent1.chromosome[0...point1] + parent2.chromosome[point1..point2] +
parent1.chromosome[point2+1..-1]
end
end
class Mutator
def initialize(chromosome_size, mutation_rate)
@size = chromosome_size
@rate = mutation_rate
end
def mutate(chromosome)
@size.times {|index| chromosome[index] = Gene.random if rand < @rate }
chromosome
end
end
Le code de ces trois classes reprends plus ou moins le code développé en style procédural dans les articles précédents et je ne vois pas tellement ce que je pourrais en dire de plus. Il reste donc à lancer la machine:
generations = 500
search = "Mon royaume pour un cheval"
population = Population.new(search.size, 1000)
mutation = 0.001
GeneticAlgorithm.new(generations, population, search, mutation).run
Voilà, c’est terminé pour le code objet. Quand j’aurais présenter 2 ou 3 algorithmes génétiques de plus, on verra quelles classes résistent et peuvent être réutilisées et lesquelles doivent être repensées. Ça nous conduira éventuellement vers la création d’un framework…
À demain