File size: 3,304 Bytes
2a2a517
6e5f7ce
2a2a517
5e2a70f
 
1f1f9b0
5e2a70f
 
 
 
 
 
 
 
 
 
a369299
c3d240e
 
 
 
 
 
 
 
 
382662a
 
 
 
5e2a70f
 
382662a
 
 
c3d240e
382662a
2a2a517
382662a
 
5e2a70f
 
d3f2b30
 
 
 
 
5e2a70f
 
 
 
 
 
c862e70
5e2a70f
 
 
 
 
 
c862e70
5e2a70f
 
 
 
 
9c27796
382662a
5e2a70f
 
 
 
 
 
382662a
b364345
5e2a70f
 
 
 
 
 
 
 
 
 
 
6e5f7ce
9c27796
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
include("eureqa.jl")

const nthreads = Threads.nthreads()
const migration = true
const hofMigration = true
const fractionReplacedHof = 0.1f0

# List of the best members seen all time
mutable struct HallOfFame
    members::Array{PopMember, 1}
    exists::Array{Bool, 1}

    # 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,
               )
    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]
    # 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)
        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]))

        #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
            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