genetic

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

commit 734900580f9b151a2050eb45433d09ffe10c8ffb
parent 769a197c7643656d34a52e4e938ecf23eb11b656
Author: dracuxan <[email protected]>
Date:   Wed,  8 Apr 2026 11:27:49 +0530

new: uniform crossover plus opts for crossover functions

Diffstat:
Mgenetic/lib/genetic.ex | 4++--
Mgenetic/lib/toolbox/crossover.ex | 39+++++++++++++++++++++++++++------------
Mgenetic/scripts/n_queens.exs | 4++--
Mgenetic/scripts/one_max.exs | 5+++--
Mgenetic/scripts/speller.exs | 7++++++-
5 files changed, 40 insertions(+), 19 deletions(-)

diff --git a/genetic/lib/genetic.ex b/genetic/lib/genetic.ex @@ -53,14 +53,14 @@ defmodule Genetic do Keyword.get( opts, :crossover_type, - &Toolbox.Crossover.order_one/2 + &Toolbox.Crossover.order_one/3 ) population |> Enum.reduce( [], fn {p1, p2}, acc -> - {c1, c2} = apply(crossover_fn, [p1, p2]) + {c1, c2} = apply(crossover_fn, [p1, p2, opts]) [c1, c2 | acc] end ) diff --git a/genetic/lib/toolbox/crossover.ex b/genetic/lib/toolbox/crossover.ex @@ -1,7 +1,7 @@ defmodule Toolbox.Crossover do alias Types.Chromosome - def order_one(p1, p2) do + def order_one(p1, p2, _opts \\ []) do lim = Enum.count(p1.genes) - 1 # random range {i1, i2} = @@ -36,7 +36,7 @@ defmodule Toolbox.Crossover do }} end - def single_point(p1, p2) do + def single_point(p1, p2, _opts \\ []) do cx_point = :rand.uniform(p1.size - 1) {{head1, tail1}, {head2, tail2}} = @@ -44,15 +44,30 @@ 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: p1.size, age: 0}, + %Chromosome{genes: c2, size: p2.size, age: 0} + } + end + + def uniform(p1, p2, opts \\ []) do + rate = Keyword.get(opts, :rate, 0.5) + + {c1, c2} = + p1.genes + |> Enum.zip(p2.genes) + |> Enum.map(fn {x, y} -> + if :rand.uniform() < rate do + {x, y} + else + {y, x} + end + end) + |> Enum.unzip() + + { + %Chromosome{genes: c1, size: p1.size, age: 0}, + %Chromosome{genes: c2, size: p2.size, age: 0} + } end end diff --git a/genetic/scripts/n_queens.exs b/genetic/scripts/n_queens.exs @@ -2,7 +2,7 @@ defmodule NQueens do alias Types.Chromosome @behaviour Problem - @max_queens 16 + @max_queens 7 @target_fitness @max_queens + 1 @size @target_fitness @@ -38,7 +38,7 @@ end {soln, generation} = Genetic.run( NQueens, - crossover_type: &Toolbox.Crossover.order_one_crossover/2 + crossover_type: &Toolbox.Crossover.order_one/3 ) IO.puts("\nfinal answer: #{inspect(soln)}\ngenrations passed: #{generation}") diff --git a/genetic/scripts/one_max.exs b/genetic/scripts/one_max.exs @@ -37,8 +37,9 @@ end {soln, generation} = Genetic.run(OneMax, selection_type: &Toolbox.Selection.elite/2, - crossover_type: &Toolbox.Crossover.single_point/2 + crossover_type: &Toolbox.Crossover.uniform/3, + rate: 0.5 ) -IO.puts("\nfinal answer: #{inspect(soln.genes)}") +IO.puts("\nfinal answer: #{inspect(soln)}") IO.puts("generations passed: #{generation}") diff --git a/genetic/scripts/speller.exs b/genetic/scripts/speller.exs @@ -25,5 +25,10 @@ defmodule Speller do end end -{soln, _} = Genetic.run(Speller, selection_type: &Toolbox.Selection.roulette/2) +{soln, _} = + Genetic.run(Speller, + selection_type: &Toolbox.Selection.elite/2, + crossover_type: &Toolbox.Crossover.uniform/3 + ) + IO.puts("\nfinal answer: #{inspect(soln)}")