basic.exs (1418B)
1 defmodule Basic do 2 defp combination do 3 genes = Enum.map(0..4, fn _ -> Enum.random(0..1) end) 4 %{genes: genes} 5 end 6 7 def fitness(c) do 8 gains = [6, -5, 8, 9, 7] 9 10 frequency = 11 gains 12 |> Enum.zip(c.genes) 13 |> Enum.map(fn {g, c} -> g * c end) 14 |> Enum.sum() 15 16 frequency 17 end 18 19 def terminate?(population, _generation) do 20 best = hd(population) 21 best.fitness == 30 22 end 23 24 def population do 25 Enum.map(0..4, fn _ -> combination() end) 26 end 27 28 def evaluate(population, fitness_func) do 29 population 30 |> Enum.map(fn c -> 31 fitness = fitness_func.(c) 32 %{genes: c.genes, fitness: fitness} 33 end) 34 |> Enum.sort_by(& &1.fitness, :desc) 35 end 36 37 def selection(population) do 38 population 39 |> Enum.chunk_every(2) 40 end 41 42 def crossover(population) do 43 population 44 |> Enum.reduce([], fn {c1, c2}, acc -> [c1, c2 | acc] end) 45 end 46 47 def algorithm(population, generation) do 48 population = evaluate(population, &Basic.fitness/1) 49 best = hd(population) 50 fit_str = best.fitness 51 IO.write("\rcurrent best: #{fit_str}\t generation: #{generation}") 52 53 if terminate?(population, generation) do 54 {best, generation} 55 else 56 population 57 |> selection() 58 |> crossover() 59 |> algorithm(generation + 1) 60 end 61 end 62 end 63 64 population = Basic.population() 65 {best, _generation} = Basic.algorithm(population, 1) 66 IO.inspect(best)