Created
August 8, 2017 22:03
-
-
Save mikewl/94089ef411e8d6925efa6376888e455a to your computer and use it in GitHub Desktop.
Genetic Algorithm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Base: <,>,== | |
const MR = 0.3 | |
const MA = 0.2 | |
const XR = 0.5 | |
const T_SIZE = 20 | |
const L = 30 | |
const S = 200 | |
const G = 100 | |
const best = minimum | |
const absMax = 10 | |
const SILENT = true | |
function sprintln(args...) | |
if !SILENT | |
println(args...) | |
end | |
end | |
mutable struct Individual | |
chromosome | |
fitness::Float32 | |
function Individual(size::Int, fitness) | |
this = new() | |
this.chromosome = rand(size) * absMax*2 - absMax | |
this.fitness = fitness(this) | |
return this | |
end | |
function Individual(data) | |
this = new() | |
this.chromosome = data | |
this.fitness = 0.0 | |
return this | |
end | |
end | |
<(x::Individual, y::Individual) = x.fitness < y.fitness | |
>(x::Individual, y::Individual) = x.fitness > y.fitness | |
==(x::Individual, y::Individual) = x.fitness == y.fitness | |
function mutate!(input::Individual) | |
mut_amp = MA | |
mut_rate = MR | |
# mutator = () -> rand(Float32) < mut_rate ? rand(Float32)*mut_amp*2 - mut_amp : 0 | |
# input.chromosome .+= mutator.() | |
for i = 1:length(input.chromosome) | |
input.chromosome[i] += rand(Float32) < mut_rate ? rand(Float32)*mut_amp*2 - mut_amp : 0 | |
end | |
end | |
function crossover(parent1::Individual, parent2::Individual) | |
xover_chance = XR | |
if rand() < xover_chance | |
newChromosome = zeros(Float32, length(parent1.chromosome)) | |
for i = 1:length(newChromosome) | |
@inbounds newChromosome[i] = (rand() < 0.5)? parent1.chromosome[i]:parent2.chromosome[i] | |
end | |
return Individual(newChromosome) | |
else | |
return parent1 | |
end | |
end | |
function select(pop) | |
tournament = pop[rand(1:length(pop),T_SIZE)] | |
return best(tournament) | |
end | |
function genIndividual(pop) | |
newInd = crossover(select(pop), select(pop)) | |
mutate!(newInd) | |
newInd.fitness = sphereFitness(newInd) | |
return newInd | |
end | |
# sphereFitness(input::Individual) = sum(input.chromosome .* input.chromosome) | |
function sphereFitness(input::Individual) | |
total = 0.0f0 | |
for gene in input.chromosome | |
total += gene*gene | |
end | |
return total | |
end | |
function main() | |
length = L | |
size = S | |
gen = G | |
pop = [Individual(length,sphereFitness) for _ in 1:size] | |
for i = 1:gen | |
newpop = Array{Individual}(size) | |
newpop[1] = minimum(pop) | |
for j = 2:size | |
newpop[j] = genIndividual(pop) | |
end | |
pop = newpop | |
sprintln(minimum(pop).fitness) | |
end | |
println(minimum(pop).fitness) | |
return minimum(pop) | |
end | |
main() | |
@time main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment