genetic

genetic algorithm framework
git clone [email protected]:dracuxan/genetic.git
Log | Files | Refs | README

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