MilesCranmer commited on
Commit
5e2a70f
1 Parent(s): d3ad40f

Add hall of fame and nicer printing

Browse files
Files changed (2) hide show
  1. eureqa.jl +5 -2
  2. paralleleureqa.jl +60 -7
eureqa.jl CHANGED
@@ -27,6 +27,8 @@ const parsimony = 1f-3
27
  # How much to scale temperature by (T between 0 and 1)
28
  const alpha = 10.0f0
29
  const maxsize = 20
 
 
30
  ##################
31
 
32
  id = (x,) -> x
@@ -388,8 +390,9 @@ mutable struct PopMember
388
  score::Float32
389
  birth::Int32
390
 
391
- PopMember(t) = new(t, scoreFunc(t, X, y, parsimony=parsimony), round(Int32, 1e3*(time()-1.6e9))
392
- )
 
393
  end
394
 
395
  # A list of members of the population, with easy constructors,
 
27
  # How much to scale temperature by (T between 0 and 1)
28
  const alpha = 10.0f0
29
  const maxsize = 20
30
+ const maxdegree = 2
31
+ const actualMaxsize = maxsize + maxdegree
32
  ##################
33
 
34
  id = (x,) -> x
 
390
  score::Float32
391
  birth::Int32
392
 
393
+ PopMember(t::Node) = new(t, scoreFunc(t, X, y, parsimony=parsimony), round(Int32, 1e3*(time()-1.6e9)))
394
+ PopMember(t::Node, score::Float32) = new(t, score, round(Int32, 1e3*(time()-1.6e9)))
395
+
396
  end
397
 
398
  # A list of members of the population, with easy constructors,
paralleleureqa.jl CHANGED
@@ -1,6 +1,19 @@
1
  include("eureqa.jl")
2
 
3
  const nthreads = Threads.nthreads()
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  function fullRun(niterations::Integer;
6
  npop::Integer=300,
@@ -15,6 +28,8 @@ function fullRun(niterations::Integer;
15
  allPops = [Population(npop, 3) for j=1:nthreads]
16
  # Repeat this many evolutions; we collect and migrate the best
17
  # each time.
 
 
18
  for k=1:niterations
19
  # Spawn threads to run indepdent evolutions, then gather them
20
  @inbounds Threads.@threads for i=1:nthreads
@@ -23,16 +38,54 @@ function fullRun(niterations::Integer;
23
 
24
  # Get best 10 models from each evolution. Copy because we re-assign later.
25
  bestPops = deepcopy(Population([member for pop in allPops for member in bestSubPop(pop).members]))
26
- bestCurScoreIdx = argmin([bestPops.members[member].score for member=1:bestPops.n])
27
- bestCurScore = bestPops.members[bestCurScoreIdx].score
28
- debug(verbosity, bestCurScore, " is the score for ", stringTree(bestPops.members[bestCurScoreIdx].tree))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
  # Migration
31
- for j=1:nthreads
32
- for k in rand(1:npop, Integer(npop*fractionReplaced))
33
- # Copy in case one gets used twice
34
- allPops[j].members[k] = deepcopy(bestPops.members[rand(1:size(bestPops.members)[1])])
 
 
35
  end
36
  end
 
 
 
 
 
 
 
 
 
 
 
37
  end
38
  end
 
1
  include("eureqa.jl")
2
 
3
  const nthreads = Threads.nthreads()
4
+ const migration = true
5
+ const hofMigration = true
6
+ const fractionReplacedHof = 0.05f0
7
+
8
+ # List of the best members seen all time
9
+ mutable struct HallOfFame
10
+ members::Array{PopMember, 1}
11
+ exists::Array{Bool, 1}
12
+
13
+ # Arranged by complexity - store one at each.
14
+ HallOfFame() = new([PopMember(Node(1f0), 1f9) for i=1:actualMaxsize], [false for i=1:actualMaxsize])
15
+ end
16
+
17
 
18
  function fullRun(niterations::Integer;
19
  npop::Integer=300,
 
28
  allPops = [Population(npop, 3) for j=1:nthreads]
29
  # Repeat this many evolutions; we collect and migrate the best
30
  # each time.
31
+ hallOfFame = HallOfFame()
32
+
33
  for k=1:niterations
34
  # Spawn threads to run indepdent evolutions, then gather them
35
  @inbounds Threads.@threads for i=1:nthreads
 
38
 
39
  # Get best 10 models from each evolution. Copy because we re-assign later.
40
  bestPops = deepcopy(Population([member for pop in allPops for member in bestSubPop(pop).members]))
41
+
42
+ #Update hall of fame
43
+ for pop in allPops
44
+ for member in pop.members
45
+ size = countNodes(member.tree)
46
+ if member.score < hallOfFame.members[size].score
47
+ hallOfFame.members[size] = deepcopy(member)
48
+ hallOfFame.exists[size] = true
49
+ end
50
+ end
51
+ end
52
+
53
+ dominating = PopMember[]
54
+ debug(verbosity, "Hall of Fame:")
55
+ debug(verbosity, "-----------------------------------------")
56
+ debug(verbosity, "Complexity \t Score \t Equation")
57
+ for size=1:maxsize
58
+ if hallOfFame.exists[size]
59
+ member = hallOfFame.members[size]
60
+ numberSmallerAndBetter = sum([member.score > hallOfFame.members[i].score for i=1:(size-1)])
61
+ betterThanAllSmaller = (numberSmallerAndBetter == 0)
62
+ if betterThanAllSmaller
63
+ debug(verbosity, "$size \t $(member.score) \t $(stringTree(member.tree))")
64
+ push!(dominating, member)
65
+ end
66
+ end
67
+ end
68
+ debug(verbosity, "")
69
 
70
  # Migration
71
+ if migration
72
+ for j=1:nthreads
73
+ for k in rand(1:npop, Integer(npop*fractionReplaced))
74
+ # Copy in case one gets used twice
75
+ allPops[j].members[k] = deepcopy(bestPops.members[rand(1:size(bestPops.members)[1])])
76
+ end
77
  end
78
  end
79
+
80
+ # Hall of fame migration
81
+ if hofMigration
82
+ for j=1:nthreads
83
+ for k in rand(1:npop, Integer(npop*fractionReplacedHof))
84
+ # Copy in case one gets used twice
85
+ allPops[j].members[k] = deepcopy(dominating[rand(1:size(dominating)[1])])
86
+ end
87
+ end
88
+ end
89
+
90
  end
91
  end