diff --git a/Experiment.jl b/Experiment.jl index cb2e3cf..bfac6ab 100644 --- a/Experiment.jl +++ b/Experiment.jl @@ -4,6 +4,8 @@ import DataFrames POPSIZE = 5 mu = 1 lambda = 4 +GENLIMIT = 20 +TARGETCALORIES = 1000 data = ExcelReaders.readxlsheet("./data/nutrional_information_5917.xlsx", "Sheet2", skipstartrows=1) header = ExcelReaders.readxlsheet("./data/nutrional_information_5917.xlsx", "Sheet2", nrows=1) @@ -22,20 +24,21 @@ for i = 1:length(header) df[header[i]] = data[2:end, i] end -function breeder(parent) +function mutate(parent) + randomCandidate(4) end +""" + fitness(candidate::DataFrames.DataFrame) + +Calculate the fitness of the candidate, which is the +absolute value of the difference of TARGETCALORIES and the sum +of all calories in the meal. +""" function fitness(candidate::DataFrames.DataFrame) - sum(+, candidate[:Calories]) + abs(TARGETCALORIES - sum(+, candidate[:Calories])) end -function breed(candidates::Array{DataFrames.DataFrame}) - # Truncation selection, top 3 as parents. - # First, check everyone's fitness. - # Then, generate new solutions by selecting parents and breeding - sort!(candidates, by = x -> fitness(x)) - parents = candidates[1:3] -end function randRow() # Generate a random row index @@ -48,8 +51,43 @@ function randomCandidate(n::Integer) df[rows, :] end -function generateInitialPopulation() - [randomCandidate(5) for i = 1:POPSIZE] +function generateInitialPopulation(lambda::Integer, candidateSize::Integer) + [randomCandidate(candidateSize) for i = 1:lambda] end +function main() + # Generate the initial population. + pop = generateInitialPopulation(lambda, 4) + best = nothing + generationNum = 0 + fit = nothing + parents = nothing + + while generationNum != GENLIMIT || (best != nothing && fitness(best) != 0) + + # Assess the fitness of parents + for parent in pop + fit = fitness(parent) + if best === nothing || fit < fitness(best) + best = parent + end + end + + bestFitness = fitness(best) + + sort!(pop, by = x -> fitness(x)) + parents = pop[1:mu] + pop = parents + + for p in parents + for i = 1:(lambda/mu) + push!(pop, mutate(p)) + end + end + + println("Generation $generationNum, best $best, fitness $bestFitness") + generationNum += 1 + end + +end # search(generateInitialPopulation()) \ No newline at end of file