Skip to content

Commit

Permalink
Merge 9ad8b40 into 7523459
Browse files Browse the repository at this point in the history
  • Loading branch information
MilesCranmer committed Feb 12, 2022
2 parents 7523459 + 9ad8b40 commit 8848316
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 14 deletions.
25 changes: 13 additions & 12 deletions src/Population.jl
@@ -1,3 +1,4 @@
using Random
using FromFile
@from "Core.jl" import Options, Dataset, RecordType, stringTree
@from "EquationUtils.jl" import countNodes
Expand Down Expand Up @@ -41,30 +42,30 @@ Population(X::AbstractMatrix{T}, y::AbstractVector{T}, baseline::T;

# Sample 10 random members of the population, and make a new one
function samplePop(pop::Population, options::Options)::Population
idx = rand(1:pop.n, options.ns)
idx = randperm(pop.n)[1:options.ns]
return Population(pop.members[idx])
end

# Sample the population, and get the best member from that sample
function bestOfSample(pop::Population, options::Options)::PopMember
sample = samplePop(pop, options)
if options.probPickFirst == 1.0
best_idx = argmin([sample.members[member].score for member=1:options.ns])
return sample.members[best_idx]

scores = [sample.members[member].score for member=1:options.ns]
p = options.probPickFirst

if p == 1.0
chosen_idx = argmin(scores)
else
sort_idx = sortperm([sample.members[member].score for member=1:options.ns])
# Lowest comes first
k = range(0.0, stop=options.ns-1, step=1.0) |> collect
p = options.probPickFirst
sort_idx = sortperm(scores)
# scores[sort_idx] would put smallest first.

# Weighted choice:
k = collect(0:(options.ns - 1))
prob_each = p * (1 - p) .^ k
prob_each /= sum(prob_each)
cumprob = cumsum(prob_each)
chosen_idx = findfirst(cumprob .> rand(Float32))

return sample.members[chosen_idx]
chosen_idx = sort_idx[findfirst(cumprob .> rand())]
end
return sample.members[chosen_idx]
end

function finalizeScores(dataset::Dataset{T},
Expand Down
2 changes: 1 addition & 1 deletion src/SymbolicRegression.jl
Expand Up @@ -68,7 +68,7 @@ using Reexport
@from "MutationFunctions.jl" import genRandomTree, genRandomTreeFixedSize
@from "LossFunctions.jl" import EvalLoss, Loss, scoreFunc
@from "PopMember.jl" import PopMember, copyPopMember
@from "Population.jl" import Population, bestSubPop, record_population
@from "Population.jl" import Population, bestSubPop, record_population, bestOfSample
@from "HallOfFame.jl" import HallOfFame, calculateParetoFrontier, string_dominating_pareto_curve
@from "SingleIteration.jl" import SRCycle, OptimizeAndSimplifyPopulation
@from "InterfaceSymbolicUtils.jl" import node_to_symbolic, symbolic_to_node
Expand Down
35 changes: 35 additions & 0 deletions test/test_prob_pick_first.jl
@@ -0,0 +1,35 @@
using SymbolicRegression, Test

n = 10

options = Options(
binary_operators=(+, -, *, /),
unary_operators=(cos, sin),
probPickFirst=0.999,
)

for reverse in [false, true]
members = PopMember{Float32}[]

# Generate members with scores from 0 to 1:
for i=1:n
tree = Node("x1") * 3.2f0
score = Float32(i-1)/(n-1)
if reverse
score = 1 - score
end
push!(members, PopMember(tree, score))
end

pop = Population(members, n)

best_pop_member = [
SymbolicRegression.bestOfSample(pop, options).score
for j=1:100
]

mean_value = sum(best_pop_member)/length(best_pop_member)

# Make sure average score is small
@test mean_value < 0.1
end
7 changes: 6 additions & 1 deletion test/unittest.jl
Expand Up @@ -227,4 +227,9 @@ for fnc in [

zero_tolerance = 1e-6
@test all(abs.(test_y .- true_y)/N .< zero_tolerance)
end
end


println("Testing whether probPickFirst works.")
include("test_prob_pick_first.jl")
println("Passed.")

0 comments on commit 8848316

Please sign in to comment.