Xavier Nayrac

Accro au TDD, rubyiste mais pas que, maker, heureux utilisateur de Vim, accordéoniste.
Si vous vous sentez particulièrement généreux, suivez moi sur Twitter.

Un algorithme génétique en Julia - partie 14

| Comments

Niveau : intermédiaire

Ça y est ! J’ai enfin un algorithme génétique écrit en Julia. Le programme est certainement maladroit par endroit, mais il fonctionne.

main.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
type Chromosome
  genes
end

create_genes(size) = rand(0:1, size)

function create_population(size, chromosome_size)
  [ Chromosome(create_genes(chromosome_size)) for _ in 1:size ]
end

score(population) = map(x -> sum(x.genes), population)

function fight(scores, index1, index2)
  if rand() < 0.8
    scores[index1] > scores[index2] ? index1 : index2
  else
    scores[index1] > scores[index2] ? index2 : index1
  end
end

function tournament(scores)
  population_size = length(scores)
  selection_size = population_size * 2
  [ fight(scores, rand(1:population_size), rand(1:population_size))
    for _ in 1:selection_size ]
end

function crossover(chromosome1, chromosome2)
  cut_point = rand(1:length(chromosome1.genes))
  first_part = chromosome1.genes[1:cut_point]
  second_part = chromosome2.genes[cut_point + 1:end]
  mutate(Chromosome([ first_part, second_part]))
end

function reproduction(new_population, current_population, selection)
  if selection == []
    return new_population
  else
    father = current_population[selection[1]]
    mother = current_population[selection[2]]
    child = crossover(father, mother)
    reproduction([new_population, child], current_population, selection[3:end])
  end
end

function mutate(ch)
  mutator(g) = if rand(1:400) == 1
    g == 1 ? 0 : 1
  else
    g
  end
  Chromosome([ mutator(x)::Int for x in ch.genes ])
end

function run()
  current = create_population(400, 20)
  for i in 1:50
    scores = score(current)
    best = maximum(scores)
    println("Generation $i Best $best")
    selection = tournament(scores)
    current = reproduction([], current, selection)
  end
end

Voici un exemple d’utilisation:

julia> include("main.jl")
run (generic function with 1 method)

julia> run()
Generation 1 Best 18
Generation 2 Best 18
Generation 3 Best 17
Generation 4 Best 17
Generation 5 Best 18
Generation 6 Best 17
Generation 7 Best 18
Generation 8 Best 19
Generation 9 Best 19
Generation 10 Best 19
Generation 11 Best 20
...

Il me reste encore pas mal de choses à faire pour améliorer ce programme, mais c’était un bon début pour apprendre le langage Julia.

À demain.

Articles connexes

Commentaires