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:
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)}")