genetic

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

mutation.ex (1587B)


      1 defmodule Toolbox.Mutation do
      2   alias Types.Chromosome
      3 
      4   def flip(chromosome, _opts \\ []) do
      5     genes =
      6       chromosome.genes
      7       |> Enum.map(&Bitwise.bxor(&1, 1))
      8 
      9     %Chromosome{genes: genes, size: chromosome.size}
     10   end
     11 
     12   def flip_some(chromosome, opts \\ []) do
     13     p = Keyword.get(opts, :p, 0.5)
     14 
     15     genes =
     16       chromosome.genes
     17       |> Enum.map(fn g ->
     18         if :rand.uniform() < p do
     19           Bitwise.bxor(g, 1)
     20         else
     21           g
     22         end
     23       end)
     24 
     25     %Chromosome{genes: genes, size: chromosome.size}
     26   end
     27 
     28   def scramble(chromosome, _opts \\ []) do
     29     genes =
     30       chromosome.genes
     31       |> Enum.shuffle()
     32 
     33     %Chromosome{genes: genes, size: chromosome.size}
     34   end
     35 
     36   def scramble_n(chromosome, _opts \\ []) do
     37     n = 10
     38     start = :rand.uniform(n - 1)
     39 
     40     {lo, hi} =
     41       if start + n >= chromosome.size do
     42         {start - n, start}
     43       else
     44         {start, start + n}
     45       end
     46 
     47     head = Enum.slice(chromosome.genes, 0, lo)
     48     mid = Enum.slice(chromosome.genes, lo, hi) |> Enum.shuffle()
     49     tail = Enum.slice(chromosome.genes, hi, chromosome.size)
     50     %Chromosome{genes: head ++ mid ++ tail, size: chromosome.size}
     51   end
     52 
     53   def gaussian(chromosome, _opts \\ []) do
     54     mu = Enum.sum(chromosome.genes) / length(chromosome.genes)
     55 
     56     sigma =
     57       chromosome.genes
     58       |> Enum.map(fn x -> (mu - x) * (mu - x) end)
     59       |> Enum.sum()
     60       |> Kernel./(length(chromosome.genes))
     61 
     62     genes =
     63       chromosome.genes
     64       |> Enum.map(fn _ -> :rand.normal(mu, sigma) end)
     65 
     66     %Chromosome{genes: genes, size: chromosome.size}
     67   end
     68 end