seanmor5 / genex Goto Github PK
View Code? Open in Web Editor NEWGenetic Algorithms in Elixir!
License: Apache License 2.0
Genetic Algorithms in Elixir!
License: Apache License 2.0
With addition of 2 children per crossover, alg runs insanely slow. Looking into issue now
Prepackage a basic statistics module, but include the option to utilize a third-party. Then statistics will be included in the population struct.
Similar to Issue 8
Selection refers to Parent Selection moreso than survivor selection. Perhaps there's a better way to implement this - giving the user more freedom to determine how they want to persist between generations.
To use Genex today, a user builds a module and defines three functions. If the problem has parameters that impact how these functions should work, they can define functions to hold that data. That is the approach taken in the knapsack problem example.
But then what happens if the user wants to solve different versions of the same problem? Like solving the knapsack problem with other weights/profits/weight limits. Currently, they would have to either rewrite the module every time or duplicate it for each version. While working through Genetic Algorithms in Elixir, I opted for protocols when implementing the book's framework. I found the result easier to customise. Again, taking the knapsack problem as an example, the code would look something like this:
defmodule Knapsack do
@enforce_keys [:profits, :weigths, :weight_limit]
defstruct [:profits, :weights, :weight_limit, bound_breached: 0]
defimpl Genex.Solvable do
def genotype(knapsack), do: Genex.Tools.Genotype.binary(Enum.count(knapsack.weights))
def fitness_function(knapsack, chromosome) do
profit =
chromosome.genes
|> Enum.zip(knapsack.profits)
|> Enum.reduce(0, fn {g, p}, acc -> acc + g * p end)
weight_carried =
chromosome.genes
|> Enum.zip(knapsack.weights)
|> Enum.reduce(0, fn {g, w}, acc -> acc + g * w end)
weight_allowed? = weight_carried <= knapsack.weight_limit
if weight_allowed? do
profit
else
knapsack.bound_breached
end
end
def terminate?(_knapsack, population), do: population.generation == 1000
end
end
solution =
%Knapsack{profits: [6, 5, 8, 9, 6, 7, 3], weights: [2, 3, 6, 7, 5, 9, 4], weight_limit: 12}
|> Genex.run(
title: "Knapsack",
crossover_type: Genex.Tools.Crossover.two_point(),
selection_type: Genex.Tools.Selection.roulette(),
population_size: 50
)
IO.inspect(solution.strongest.genes)
That would be a breaking change, but since 1.0
was not yet released, I thought this could be an appropriate time to suggest such a change.
Would a PR introducing this be welcome?
== Compilation error in file test/genex_test.exs ==
** (CompileError) test/genex_test.exs:10: def init/0 already defined as defp
test/genex_test.exs:10: (module)
test/genex_test.exs:7: (module)
(stdlib) erl_eval.erl:680: :erl_eval.do_apply/6
(elixir) lib/kernel/parallel_compiler.ex:237: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7
elixir 1.9.0
This is related to checking mutation rates.
Need to sanitize input. Check nil fields on crossover, survival, etc. Check rates.
Currently, every crossover function operates on the entire population struct. The logic for each is the same EXCEPT the actual crossover. In order to simplify the functions, we will have each operate ONLY on two parents.
Crossover Rate and Mutation Rate can be implemented as a function of some factors in the population. Perhaps introduce some decay rate or a function which dynamically generates Crossover, Mutation, etc.
Rates can be changed from attributes to methods.
Some Chromosomes end up with no length, :rand.uniform doesn't like 0. Fix with check of chromosome length before executing crossover.
As of right now, parents are paired in the order they are selected in 2s. This means in something like natural selection, the fittest mates with the second fittest, the third with the fourth, and so on. This implementation is rigid - perhaps giving the user more freedom to determine who crosses with who is a more suitable alternative.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.