Xavier Nayrac

Rubyiste accro au TDD, serial blogger, apprenti data scientist, 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