Spaces:
Running
Running
include("eureqa.jl") | |
import Optim | |
const nthreads = Threads.nthreads() | |
# List of the best members seen all time | |
mutable struct HallOfFame | |
members::Array{PopMember, 1} | |
exists::Array{Bool, 1} #Whether it has been set | |
# Arranged by complexity - store one at each. | |
HallOfFame() = new([PopMember(Node(1f0), 1f9) for i=1:actualMaxsize], [false for i=1:actualMaxsize]) | |
end | |
function fullRun(niterations::Integer; | |
npop::Integer=300, | |
annealing::Bool=true, | |
ncyclesperiteration::Integer=3000, | |
fractionReplaced::Float32=0.1f0, | |
verbosity::Integer=0, | |
topn::Integer=10 | |
) | |
debug(verbosity, "Lets try to learn (x2^2 + cos(x3)) using regularized evolution from scratch") | |
debug(verbosity, "Running with $nthreads threads") | |
# Generate random initial populations | |
allPops = [Population(npop, 3) for j=1:nthreads] | |
bestSubPops = [Population(1) for j=1:nthreads] | |
# Repeat this many evolutions; we collect and migrate the best | |
# each time. | |
hallOfFame = HallOfFame() | |
for k=1:niterations | |
# Spawn threads to run indepdent evolutions, then gather them | |
@inbounds Threads.@threads for i=1:nthreads | |
allPops[i] = run(allPops[i], ncyclesperiteration, annealing, verbosity=verbosity) | |
bestSubPops[i] = bestSubPop(allPops[i], topn=topn) | |
if shouldOptimizeConstants | |
for j=1:bestSubPops[i].n | |
bestSubPops[i].members[j] = optimizeConstants(bestSubPops[i].members[j]) | |
end | |
end | |
end | |
# Get best 10 models from each evolution. Copy because we re-assign later. | |
# bestPops = deepcopy(Population([member for pop in allPops for member in bestSubPop(pop).members])) | |
bestPops = deepcopy(Population([member for pop in bestSubPops for member in pop.members])) | |
#Update hall of fame | |
for member in bestPops.members | |
size = countNodes(member.tree) | |
if member.score < hallOfFame.members[size].score | |
hallOfFame.members[size] = deepcopy(member) | |
hallOfFame.exists[size] = true | |
end | |
end | |
dominating = PopMember[] | |
debug(verbosity, "Hall of Fame:") | |
debug(verbosity, "-----------------------------------------") | |
debug(verbosity, "Complexity \t MSE \t Equation") | |
for size=1:maxsize | |
if hallOfFame.exists[size] | |
member = hallOfFame.members[size] | |
numberSmallerAndBetter = sum([member.score > hallOfFame.members[i].score for i=1:(size-1)]) | |
betterThanAllSmaller = (numberSmallerAndBetter == 0) | |
if betterThanAllSmaller | |
debug(verbosity, "$size \t $(member.score-parsimony*size) \t $(stringTree(member.tree))") | |
push!(dominating, member) | |
end | |
end | |
end | |
debug(verbosity, "") | |
# Migration | |
if migration | |
for j=1:nthreads | |
for k in rand(1:npop, Integer(npop*fractionReplaced)) | |
# Copy in case one gets used twice | |
allPops[j].members[k] = deepcopy(bestPops.members[rand(1:size(bestPops.members)[1])]) | |
end | |
end | |
end | |
# Hall of fame migration | |
if hofMigration && size(dominating)[1] > 0 | |
for j=1:nthreads | |
for k in rand(1:npop, Integer(npop*fractionReplacedHof)) | |
# Copy in case one gets used twice | |
allPops[j].members[k] = deepcopy(dominating[rand(1:size(dominating)[1])]) | |
end | |
end | |
end | |
end | |
end | |