Skip to content

Instantly share code, notes, and snippets.

@mikewl
Created August 8, 2017 22:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikewl/94089ef411e8d6925efa6376888e455a to your computer and use it in GitHub Desktop.
Save mikewl/94089ef411e8d6925efa6376888e455a to your computer and use it in GitHub Desktop.
Genetic Algorithm
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