genetic

genetic algorithm framework
git clone igris.git:dracuxan/genetic.git
Log | Files | Refs | README

commit ba76f5047ee8ec89459d35ff65622e1188a305b0
parent 734900580f9b151a2050eb45433d09ffe10c8ffb
Author: dracuxan <[email protected]>
Date:   Wed,  8 Apr 2026 14:03:56 +0530

new: whole arithmetic crossover and demo of multi parent crossover

Diffstat:
Mgenetic/lib/toolbox/crossover.ex | 65+++++++++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 51 insertions(+), 14 deletions(-)

diff --git a/genetic/lib/toolbox/crossover.ex b/genetic/lib/toolbox/crossover.ex @@ -24,16 +24,10 @@ defmodule Toolbox.Crossover do # create and return {c1, c2} = {head1 ++ slice1 ++ tail1, head2 ++ slice2 ++ tail2} - {%Chromosome{ - genes: c1, - size: p1.size, - age: 0 - }, - %Chromosome{ - genes: c2, - size: p2.size, - age: 0 - }} + { + %Chromosome{genes: c1, size: length(c1), age: 0}, + %Chromosome{genes: c2, size: length(c2), age: 0} + } end def single_point(p1, p2, _opts \\ []) do @@ -45,8 +39,8 @@ defmodule Toolbox.Crossover do {c1, c2} = {head1 ++ tail2, head2 ++ tail1} { - %Chromosome{genes: c1, size: p1.size, age: 0}, - %Chromosome{genes: c2, size: p2.size, age: 0} + %Chromosome{genes: c1, size: length(c1), age: 0}, + %Chromosome{genes: c2, size: length(c2), age: 0} } end @@ -66,8 +60,51 @@ defmodule Toolbox.Crossover do |> Enum.unzip() { - %Chromosome{genes: c1, size: p1.size, age: 0}, - %Chromosome{genes: c2, size: p2.size, age: 0} + %Chromosome{genes: c1, size: length(c1), age: 0}, + %Chromosome{genes: c2, size: length(c2), age: 0} + } + end + + def whole_arethmetic(p1, p2, opts \\ []) do + alpha = Keyword.get(opts, :alpha, 0.5) + + {c1, c2} = + p1.genes + |> Enum.zip(p2.genes) + |> Enum.map(fn {x, y} -> + { + x * alpha + y * (1 - alpha), + x * (alpha - 1) + y * alpha + } + end) + |> Enum.unzip() + + { + %Chromosome{genes: c1, size: length(c1), age: 0}, + %Chromosome{genes: c2, size: length(c2), age: 0} } end + + # demo of how crossover can be performed on mulitple parents at once + def single_point_multi(parents, opts \\ []) + def single_point_multi([], _opts), do: raise("more than one parent needed!") + def single_point_multi([p1 | []], _opts), do: p1 + + def single_point_multi(parents, _opts) do + p1 = hd(parents) + cx_point = :rand.uniform(p1.size) + + parents + |> Enum.chunk_every(2, 1, [hd(parents)]) + |> Enum.map(&List.to_tuple(&1)) + |> Enum.reduce( + [], + fn {p1, p2}, chd -> + {front, _} = Enum.split(p1.genes, cx_point) + {_, back} = Enum.split(p2.genes, cx_point) + c = %Chromosome{genes: front ++ back, size: length(p1)} + [c | chd] + end + ) + end end