selection.ex (1376B)
1 defmodule Toolbox.Selection do 2 @dialyzer :no_opaque 3 def elite(population, n) do 4 population 5 |> Enum.take(n) 6 end 7 8 def random(population, n) do 9 population 10 |> Enum.take_random(n) 11 end 12 13 def tournament(population, n) do 14 tournsize = :rand.uniform(n) 15 16 0..(n - 1) 17 |> Enum.map(fn _ -> 18 population 19 |> Enum.take_random(tournsize) 20 |> Enum.max_by(& &1.fitness) 21 end) 22 end 23 24 def tournament_no_dup(population, n) do 25 tournsize = :rand.uniform(n) 26 selected = MapSet.new() 27 tournament_helper(population, n, tournsize, selected) 28 end 29 30 defp tournament_helper(population, n, tournsize, selected) do 31 if MapSet.size(selected) == n do 32 MapSet.to_list(selected) 33 else 34 chosen = 35 population 36 |> Enum.take_random(tournsize) 37 |> Enum.max_by(& &1.fitness) 38 39 tournament_helper(population, n, tournsize, MapSet.put(selected, chosen)) 40 end 41 end 42 43 def roulette(population, n) do 44 sum_fitness = 45 population 46 |> Enum.map(& &1.fitness) 47 |> Enum.sum() 48 49 0..(n - 1) 50 |> Enum.map(fn _ -> 51 u = :rand.uniform() * sum_fitness 52 53 population 54 |> Enum.reduce_while( 55 0, 56 fn x, sum -> 57 if x.fitness + sum > u do 58 {:halt, x} 59 else 60 {:cont, x.fitness + sum} 61 end 62 end 63 ) 64 end) 65 end 66 end