Skip to content

Commit 1e51607

Browse files
committed
add generation-based termination
1 parent d569050 commit 1e51607

File tree

5 files changed

+59
-7
lines changed

5 files changed

+59
-7
lines changed

lib/genetic.ex

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,26 @@ defmodule Genetic do
5555

5656
def run(problem, opts \\ []) do
5757
population = initialize(&problem.genotype/0)
58+
first_generation = 0
59+
5860
population
59-
|> evolve(problem, opts)
61+
|> evolve(problem, first_generation, opts)
6062
end
6163

62-
def evolve(population, problem, opts \\ []) do
64+
def evolve(population, problem, generation, opts \\ []) do
6365
population = evaluate(population, &problem.fitness_function/1, opts)
6466
best = hd(population)
6567
IO.write("\rCurrent Best: #{problem.fitness_function(best)}")
66-
if problem.terminate?(population) do
68+
if problem.terminate?(population, generation) do
6769
best
6870
else
71+
generation = generation + 1
72+
6973
population
7074
|> select(opts)
7175
|> crossover(opts)
7276
|> mutation(opts)
73-
|> evolve(problem, opts)
77+
|> evolve(problem, generation, opts)
7478
end
7579
end
7680
end

lib/problem.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ defmodule Problem do
33

44
@callback genotype :: Chromosome.t
55
@callback fitness_function(Chromosome.t) :: number()
6-
@callback terminate?(Enum.t) :: boolean()
6+
@callback terminate?(Enum.t(), integer()) :: boolean()
77
end

scripts/cargo.exs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
defmodule Cargo do
2+
@behaviour Problem
3+
alias Types.Chromosome
4+
5+
@impl true
6+
def genotype do
7+
genes = for _ <- 1..10, do: Enum.random(0..1)
8+
%Chromosome{genes: genes, size: length(genes)}
9+
end
10+
11+
@impl true
12+
def fitness_function(chromosome) do
13+
profits = [6, 5, 8, 9, 6, 7, 3, 1, 2, 6]
14+
weights = [10, 6, 8, 7, 10, 9, 7, 11, 6, 8]
15+
weight_limit = 40
16+
17+
potential_profits =
18+
profits
19+
|> Enum.zip(chromosome.genes)
20+
|> Enum.map(fn {profit, on_off} -> profit * on_off end)
21+
|> Enum.sum()
22+
23+
over_limit? =
24+
weights
25+
|> Enum.zip(chromosome.genes)
26+
|> Enum.map(fn {weight, on_off} -> weight * on_off end)
27+
|> Enum.sum()
28+
|> Kernel.>(weight_limit)
29+
30+
profits = if over_limit?, do: 0, else: potential_profits
31+
profits
32+
end
33+
34+
@impl true
35+
def terminate?(_population, generation), do: generation == 100
36+
end
37+
38+
solution = Genetic.run(Cargo, population_size: 50)
39+
IO.write("\n")
40+
IO.inspect(solution)
41+
42+
weight =
43+
solution.genes
44+
|> Enum.zip([10, 6, 8, 7, 10, 9, 7, 11, 6, 8])
45+
|> Enum.map(fn {on_off, weight} -> weight * on_off end)
46+
|> Enum.sum()
47+
48+
IO.write("\nWeight is: #{weight}\n")

scripts/one_max.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ defmodule OneMax do
1212
def fitness_function(chromosome), do: Enum.sum(chromosome.genes)
1313

1414
@impl true
15-
def terminate?([best | _]), do: best.fitness == 42
15+
def terminate?(_population, generation), do: generation == 100
1616
end
1717

1818
solution = Genetic.run(OneMax)

scripts/speller.ex renamed to scripts/speller.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ defmodule Speller do
1818
end
1919

2020
@impl true
21-
def terminate?([best | _]), do: best.fitness == 1
21+
def terminate?(_population, generation), do: generation == 100
2222
end
2323

2424
solution = Genetic.run(Speller)

0 commit comments

Comments
 (0)