Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Finished basic GA
  • Loading branch information
Stephen committed Feb 6, 2018
1 parent 19d3157 commit 1bb94ac
Showing 1 changed file with 82 additions and 20 deletions.
102 changes: 82 additions & 20 deletions GA.jl
@@ -1,3 +1,4 @@
using StatsBase
#= #=
Parents <— {randomly generated population} Parents <— {randomly generated population}
While not (termination criterion) While not (termination criterion)
Expand All @@ -20,7 +21,7 @@ include array of independent variables along with associated range


function initialize_population(populationSize::Int, chromosomeSize::Int, bounds::Array{Tuple{Float64, Float64},1}) function initialize_population(populationSize::Int, chromosomeSize::Int, bounds::Array{Tuple{Float64, Float64},1})
""" """
Initializes the population based on the given population and chromosome size Initializes the population based on the given population size and chromosome size
Values will be from lb to ub (lower to upper bound) Values will be from lb to ub (lower to upper bound)
""" """


Expand All @@ -31,7 +32,7 @@ function initialize_population(populationSize::Int, chromosomeSize::Int, bounds:
end end


# Init population # Init population
population = Array{Float64}(0,chromosomeSize+1) population = Array{Array{Float64}}(0)


# Foreach member in population # Foreach member in population
for i = 1:populationSize for i = 1:populationSize
Expand All @@ -45,14 +46,13 @@ function initialize_population(populationSize::Int, chromosomeSize::Int, bounds:
push!(row, 1.0) push!(row, 1.0)


# hcat row, append to 2D population matrix # hcat row, append to 2D population matrix
population = cat(1, population, hcat(row...)) population = push!(population, row)
end end

return population return population


end end


function score_population(population::Array{Float64}, fitness_function::Function, populationSize::Int, chromosomeSize::Int) function score_sort_population(population::Array{Array{Float64}}, fitness_function::Function)
""" """
Args Args
population: The population to score. Must be 2D array of Float64 elements population: The population to score. Must be 2D array of Float64 elements
Expand All @@ -62,17 +62,71 @@ function score_population(population::Array{Float64}, fitness_function::Function
Returns scored population. Score is the last element of each chromosome (row) Returns scored population. Score is the last element of each chromosome (row)
in population in population
""" """
#= 1-3, 4-6, 7-9, 10-12 # Enumerate through population, set last element of each chromosome to score
1 2 3 4 for (index,member) in enumerate(population)
=# population[index][end] = fitness_function(member)
population = population'
for i in 0:populationSize-1
println(i)
member = population[(chromosomeSize+1)*i+1:(chromosomeSize+1)*(i+1)]
println(member)
population[(chromosomeSize+1)*(i+1)] = fitness_function(member)
end end
println(population) sort!(population, by = x -> x[end])
return population
end

function create_next_generation(population::Array{Array{Float64}}, recombRate::Float64)
"""
Creates children given a population and recombination rate
Uses an elite selection of 0.10 (rounded up)
Creates random chance
TODO: Implement ranking
"""

popSize = length(population)
memberSize = length(population[1])
# Init children array
children = Array{Array{Float64}}(0)
# Elite selection
for i in 1:Int(ceil(popSize*0.10))
push!(children, population[i])
end

# Generate rest of population
while length(children) < popSize
# Two random children
choices = sample(1:popSize, 2, replace=false)
# Check for crossover
if rand() < recombRate
# Choose xover point
# Use -2 since last one is score, and last actual element cant be crossedover since that means there is none
xover = rand(1:memberSize-2)
child1 = cat(1,population[choices[1]][1:xover],population[choices[2]][xover+1:end])
child2 = cat(1,population[choices[2]][1:xover],population[choices[1]][xover+1:end])
else
# Else no crossover, just copy
child1 = population[choices[1]]
child2 = population[choices[2]]
end
# Push child 1 and 2 to children array
push!(children, child1, child2)
end

# We might have one extra due to rounding in the elite selection, let's check
if length(children) != popSize
pop!(children)
end
return children
end

function mutate(population::Array{Array{Float64}}, mutateRate::Float64, bounds::Array{Tuple{Float64, Float64},1})
"""
Iterates through each chromosome and mutates if needed
"""

for member in population
for i = 1:length(member)-1
if rand() < mutateRate
member[i] = rand(bounds[i][1]:0.10:bounds[i][2])
end
end
end

return population return population
end end


Expand All @@ -96,20 +150,28 @@ function GA(populationSize::Int, chromosomeSize::Int, fitness_function::Function
# Set recombination and mutation rate, lower and upper bound # Set recombination and mutation rate, lower and upper bound
recombRate = 0.7 recombRate = 0.7
mutateRate = 0.05 mutateRate = 0.05
maxIterations = 1 maxIterations = 1000
# First initialize the population # First initialize the population
population = initialize_population(populationSize, chromosomeSize, bounds) population = initialize_population(populationSize, chromosomeSize, bounds)

# Then loop for the required iterations
bestScores = Array{Float64}(0)
i = 0 i = 0
while i < maxIterations while i < maxIterations
scoredPopulation = score_population(population, fitness_function, populationSize, chromosomeSize) # Score and sort the population

population = score_sort_population(population, fitness_function)
push!(bestScores,population[1][end])
population = create_next_generation(population, recombRate)
population = mutate(population, mutateRate, bounds)
i += 1 i += 1

end end
println(bestScores)
println(population)
end end


function ackley(X) function ackley(X)
return e - 20*exp(-0.2*sqrt((X[1]^2 + X[2]^2)/2) - exp((cos(2*pi*X[1]) + cos(2*pi*X[2]))/2)) return e - 20*exp(-0.2*sqrt((X[1]^2 + X[2]^2)/2)) - exp((cos(2*pi*X[1]) + cos(2*pi*X[2]))/2)
end end

bounds = [(-2.0,2.0), (-2.0,2.0)] bounds = [(-2.0,2.0), (-2.0,2.0)]
GA(25,2,ackley,bounds) GA(25,2,ackley,bounds)

0 comments on commit 1bb94ac

Please sign in to comment.