More changes
This commit is contained in:
		| @@ -6,7 +6,7 @@ defmodule Genetic do | |||||||
|         for _ <- 1..population_size, do: genotype.() |         for _ <- 1..population_size, do: genotype.() | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     def evaluate(population, fitness_function, opts \\ []) do |     def evaluate(population, fitness_function, _opts \\ []) do | ||||||
|         population |         population | ||||||
|         |> Enum.map( |         |> Enum.map( | ||||||
|             fn chromosome -> |             fn chromosome -> | ||||||
| @@ -18,13 +18,13 @@ defmodule Genetic do | |||||||
|         |> Enum.sort_by(& &1.fitness, &>=/2) |         |> Enum.sort_by(& &1.fitness, &>=/2) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     def select(population, opts \\ []) do |     def select(population, _opts \\ []) do | ||||||
|         population |         population | ||||||
|         |> Enum.chunk_every(2) |         |> Enum.chunk_every(2) | ||||||
|         |> Enum.map(&List.to_tuple(&1)) |         |> Enum.map(&List.to_tuple(&1)) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     def crossover(population, opts \\ []) do |     def crossover(population, _opts \\ []) do | ||||||
|         population |         population | ||||||
|         |> Enum.reduce([], |         |> Enum.reduce([], | ||||||
|             fn {p1, p2}, acc -> |             fn {p1, p2}, acc -> | ||||||
| @@ -38,12 +38,12 @@ defmodule Genetic do | |||||||
|         ) |         ) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     def mutation(population, opts \\ []) do  |     def mutation(population, _opts \\ []) do  | ||||||
|         population |         population | ||||||
|         |> Enum.map( |         |> Enum.map( | ||||||
|             fn chromosome -> |             fn chromosome -> | ||||||
|                 if :rand.uniform() < 0.05 do |                 if :rand.uniform() < 0.05 do | ||||||
|                     %Chromosome{chromosome | genes: Enum.shuffle(chromosome)} |                     %Chromosome{chromosome | genes: Enum.shuffle(chromosome.genes)} | ||||||
|                 else |                 else | ||||||
|                     chromosome |                     chromosome | ||||||
|                 end |                 end | ||||||
| @@ -53,22 +53,24 @@ defmodule Genetic do | |||||||
|  |  | ||||||
|     def run(problem, opts \\ []) do |     def run(problem, opts \\ []) do | ||||||
|         population = initialize(&problem.genotype/0) |         population = initialize(&problem.genotype/0) | ||||||
|  |         first_generation = 0 | ||||||
|  |  | ||||||
|         population  |         population  | ||||||
|         |> evolve(problem, opts) |         |> evolve(problem, first_generation, opts) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     def evolve(population, problem, opts \\ []) do |     def evolve(population, problem, generation, opts \\ []) do | ||||||
|         population = evaluate(population, &problem.fitness_function/1, opts) |         population = evaluate(population, &problem.fitness_function/1, opts) | ||||||
|         best = hd(population) |         best = hd(population) | ||||||
|         IO.write("\rCurrent Best: #{best.fitness}") |         IO.write("\rCurrent Best: #{best.fitness}") | ||||||
|         if problem.terminate?(population) do |         if problem.terminate?(population, generation) do | ||||||
|             best |             best | ||||||
|         else |         else | ||||||
|             population |             population | ||||||
|             |> select(opts) |             |> select(opts) | ||||||
|             |> crossover(opts) |             |> crossover(opts) | ||||||
|             |> mutation(opts) |             |> mutation(opts) | ||||||
|             |> evolve(problem, opts) |             |> evolve(problem, generation+1, opts) | ||||||
|         end |         end | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,5 +5,5 @@ defmodule Problem do | |||||||
| 
 | 
 | ||||||
|     @callback fitness_function(Chromosome.t) :: number() |     @callback fitness_function(Chromosome.t) :: number() | ||||||
| 
 | 
 | ||||||
|     @callback terminate?(Enum.t) :: boolean() |     @callback terminate?(Enum.t, integer()) :: boolean() | ||||||
| end | end | ||||||
							
								
								
									
										50
									
								
								scripts/cargo.exs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								scripts/cargo.exs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | |||||||
|  | defmodule Cargo do | ||||||
|  |     @behaviour Problem | ||||||
|  |     alias Types.Chromosome | ||||||
|  |  | ||||||
|  |     @impl true | ||||||
|  |     def genotype do | ||||||
|  |         genes = for _ <- 1..10, do: Enum.random(0..1) | ||||||
|  |         %Chromosome{genes: genes, size: 10} | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     @impl true | ||||||
|  |     def fitness_function(chromosome) do | ||||||
|  |         profits = [6, 5, 8, 9, 6, 7, 3, 1, 2, 6] | ||||||
|  |         weights = [10, 6, 8, 7, 10, 9, 7, 11, 6, 8] | ||||||
|  |         weight_limit = 40 | ||||||
|  |  | ||||||
|  |         potential_profits = | ||||||
|  |             chromosome.genes | ||||||
|  |             |> Enum.zip(profits) | ||||||
|  |             |> Enum.map(fn {g, p} -> g * p end) | ||||||
|  |             |> Enum.sum() | ||||||
|  |  | ||||||
|  |         over_limit? = | ||||||
|  |             chromosome.genes | ||||||
|  |             |> Enum.zip(weights) | ||||||
|  |             |> Enum.map(fn {c, w} -> c * w end) | ||||||
|  |             |> Enum.sum() | ||||||
|  |             |> Kernel.>(weight_limit) | ||||||
|  |  | ||||||
|  |         profits = if over_limit?, do: 0, else: potential_profits | ||||||
|  |         profits | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     @impl true | ||||||
|  |     def terminate?(population, _generation) do | ||||||
|  |         Enum.max_by(population, &Cargo.fitness_function/1).fitness == 53 | ||||||
|  |     end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | soln = Genetic.run(Cargo, population_size: 50) | ||||||
|  |  | ||||||
|  | IO.write("\n") | ||||||
|  | IO.inspect(soln) | ||||||
|  |  | ||||||
|  | weight = soln.genes | ||||||
|  |     |> Enum.zip([10, 6, 8, 7, 10, 9, 7, 11, 6, 8]) | ||||||
|  |     |> Enum.map(fn {g, w} -> w*g end) | ||||||
|  |     |> Enum.sum() | ||||||
|  |  | ||||||
|  | IO.write("\nWeight is: #{weight}\n") | ||||||
| @@ -1,23 +1,24 @@ | |||||||
| genotype = fn -> for _ <- 1..1000, do: Enum.random(0..1) end |  | ||||||
|  |  | ||||||
| fitness_function = fn chromosome -> Enum.sum(chromosome) end |  | ||||||
| max_fitness = 1000 |  | ||||||
|  |  | ||||||
| defmodule OneMax do | defmodule OneMax do | ||||||
|  |     alias Types.Chromosome | ||||||
|  |  | ||||||
|     @behaviour Problem |     @behaviour Problem | ||||||
|  |  | ||||||
|     @impl Problem |     @impl true | ||||||
|     def genotype() do |     def genotype() do | ||||||
|         for _ <- 1..1000, do: Enum.random(0.. |         genes = for _ <- 1..1000, do: Enum.random(0..1) | ||||||
|  |         %Chromosome{genes: genes} | ||||||
|     end |     end | ||||||
|      |      | ||||||
|     @impl Problem |     @impl true | ||||||
|     def fitness_function(chromosome) do |     def fitness_function(chromosome) do | ||||||
|         Enum.sum(chromosome.genes) |         Enum.sum(chromosome.genes) | ||||||
|     end |     end | ||||||
|  |      | ||||||
|  |     @impl true | ||||||
|  |     def terminate?(_population, generation), do: generation == 100 | ||||||
| end | end | ||||||
|   |   | ||||||
| soln = Genetic.run(fitness_function, genotype, max_fitness) | soln = Genetic.run(OneMax) | ||||||
|  |  | ||||||
| IO.write("\n") | IO.write("\n") | ||||||
| IO.inspect(soln) | IO.inspect(soln.genes) | ||||||
|   | |||||||
							
								
								
									
										31
									
								
								scripts/portfolio.exs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								scripts/portfolio.exs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | defmodule Portfolio do | ||||||
|  |     @behaviour Problem | ||||||
|  |     alias Types.Chromosome | ||||||
|  |  | ||||||
|  |     @target_fitness 180 | ||||||
|  |  | ||||||
|  |     @impl true | ||||||
|  |     def genotype do | ||||||
|  |         genes = | ||||||
|  |             for _ <- 1..10, do: | ||||||
|  |                 {:rand.uniform(10), :rand.uniform(10)} | ||||||
|  |  | ||||||
|  |         %Chromosome{genes: genes, size: 10} | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     @impl true | ||||||
|  |     def fitness_function(chromosome) do | ||||||
|  |         chromosome.genes | ||||||
|  |         |> Enum.map(fn {roi, risk} -> 2 * roi - risk end) | ||||||
|  |         |> Enum.sum() | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     @impl true | ||||||
|  |     def terminate?(population, _generation) do | ||||||
|  |         max_value = Enum.max_by(population, &Portfolio.fitness_function/1) | ||||||
|  |         max_value > @target_fitness | ||||||
|  |     end | ||||||
|  | end | ||||||
|  |  | ||||||
|  |  | ||||||
|  | soln = Genetic.run(Portfolio) | ||||||
							
								
								
									
										25
									
								
								scripts/speller.exs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								scripts/speller.exs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | defmodule Speller do | ||||||
|  |     @behaviour Problem | ||||||
|  |     alias Types.Chromosome | ||||||
|  |  | ||||||
|  |     def genotype do | ||||||
|  |         genes = | ||||||
|  |             Stream.repeatedly(fn -> Enum.random(?a..?z) end) | ||||||
|  |             |> Enum.take(34) | ||||||
|  |         %Chromosome{genes: genes, size: 34} | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def fitness_function(chromosome) do | ||||||
|  |         target = "supercalifragilisticexpialidocious" | ||||||
|  |         guess = List.to_string(chromosome.genes) | ||||||
|  |         String.jaro_distance(target, guess) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def terminate?([best | _]), do: best.fitness == 1 | ||||||
|  |  | ||||||
|  | end | ||||||
|  |  | ||||||
|  | soln = Genetic.run(Speller) | ||||||
|  |  | ||||||
|  | IO.write("\n") | ||||||
|  | IO.inspect(soln) | ||||||
		Reference in New Issue
	
	Block a user