File size: 3,292 Bytes
2a2a517
6e5f7ce
2a2a517
5e2a70f
 
 
 
 
 
 
 
 
 
 
 
 
a369299
c3d240e
 
 
 
 
 
 
 
 
382662a
 
 
 
5e2a70f
 
382662a
 
 
c3d240e
382662a
2a2a517
382662a
 
5e2a70f
 
d3f2b30
 
 
 
 
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.05f0

# 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 Score \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) \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