sin.exs (1511B)
1 defmodule Sin do 2 alias Types.Chromosome 3 @behaviour Problem 4 5 @impl true 6 def genotype do 7 genes = :rand.uniform(10) 8 %Chromosome{genes: [genes], size: 1} 9 end 10 11 @impl true 12 def fitness_function(chromosome) do 13 x = hd(chromosome.genes) 14 Math.sin(x) - 0.2 * abs(x) 15 end 16 17 @impl true 18 def terminate?(population, generation) do 19 plot_generation(population, generation) 20 generation == 10 21 end 22 23 defp plot_generation(population, generation) do 24 curve = 25 Enum.map(-100..100, fn x -> 26 x = x / 10.0 27 [x, :math.sin(x) - 0.2 * abs(x)] 28 end) 29 30 points = 31 Enum.map(population, fn c -> 32 [hd(c.genes), c.fitness] 33 end) 34 35 best = hd(population) 36 best_point = [[hd(best.genes), best.fitness]] 37 38 {:ok, _} = 39 Gnuplot.plot( 40 [ 41 [:set, :title, "Generation #{generation}"], 42 Gnuplot.plots([ 43 ["-", :with, :lines, :lt, 2, :title, "sin(x) - 0.2|x|"], 44 ["-", :with, :points, :pt, 7, :ps, 1.5, :lc, "orange", :title, "Population"], 45 ["-", :with, :points, :pt, 5, :ps, 2, :lc, "green", :title, "Best"] 46 ]) 47 ], 48 [curve, points, best_point] 49 ) 50 end 51 end 52 53 {_soln, _gen} = 54 Genetic.run( 55 Sin, 56 population_size: 10, 57 selection_rate: 0.8, 58 mutation_rate: 0.1, 59 alpha: 1, 60 min: -10, 61 max: 10, 62 selection_type: &Toolbox.Selection.tournament/2, 63 crossover_type: &Toolbox.Crossover.blend/3, 64 mutation_type: &Toolbox.Mutation.gaussian/2 65 )