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