Skip to content

Commit

Permalink
Add 'iterative_first_improvement'.
Browse files Browse the repository at this point in the history
Add 'first_improvement' building block.
  • Loading branch information
phrb committed Sep 4, 2015
1 parent 0867d97 commit be88c64
Show file tree
Hide file tree
Showing 13 changed files with 245 additions and 14 deletions.
24 changes: 24 additions & 0 deletions examples/iterative_first_improvement/rosenbrock.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@everywhere using StochasticSearch

@everywhere function rosenbrock(x::Configuration)
return (1.0 - x["i0"].value)^2 + 100.0 * (x["i1"].value - x["i0"].value^2)^2
end

configuration = Configuration([NumberParameter(-2.0, 2.0, 0.0,"i0"),
NumberParameter(-2.0, 2.0, 0.0,"i1")],
"rosenbrock_config")

iterations = 1_000
report_after = 1_00

result = @task optimize(rosenbrock,
configuration,
[:iterative_first_improvement],
iterations = iterations,
report_after = report_after,
evaluations = 1,
instances = [1])
partial = None
for i = 0:iterations
partial = consume(result)
end
73 changes: 73 additions & 0 deletions examples/iterative_first_improvement/sorting.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
@everywhere using StochasticSearch

@everywhere function insertionsort!(A, i, j)
for m = i + 1:j
value = A[m]
n = m - 1
while n >= i && A[n] > value
A[n + 1] = A[n]
n = n - 1
end
A[n + 1] = value
end
end

@everywhere function quicksort!(A,cutoff,i=1,j=length(A))
if j > i
pivot = A[rand(i:j)]
left, right = i, j
while left <= right
while A[left] < pivot
left += 1
end
while A[right] > pivot
right -= 1
end
if left <= right
A[left], A[right] = A[right], A[left]
left += 1
right -= 1
end
end
if j - i <= cutoff
insertionsort!(A, i, j)
else
quicksort!(A,cutoff,i,right)
quicksort!(A,cutoff,left,j)
end
end
return A
end

@everywhere function sorting_cutoff(config::Configuration, args::Dict{ASCIIString, Any})
A = copy(args["array"])
cutoff = config.value["cutoff"]
@elapsed quicksort!(A, cutoff)
end

array_size = 100_000
cutoff = 15
iterations = 2_00
report_after = 4

args = Dict{ASCIIString, Any}()
args["array"] = rand(array_size)

# Making sure code is already compiled.
@elapsed quicksort!(rand(10), 5)

configuration = Configuration([NumberParameter(0, array_size, cutoff, "cutoff")],
"Sorting Cutoff")

result = @task optimize(sorting_cutoff,
configuration,
[:iterative_first_improvement, :simulated_annealing],
args = args,
iterations = iterations,
report_after = report_after,
evaluations = 6,
instances = [1, 1])
partial = None
for i = 0:iterations
partial = consume(result)
end
1 change: 1 addition & 0 deletions examples/rosenbrock.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ report_after = 1_00

result = @task optimize(rosenbrock,
configuration,
[:simulated_annealing],
iterations = iterations,
report_after = report_after,
evaluations = 1,
Expand Down
3 changes: 2 additions & 1 deletion examples/sorting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,12 @@ configuration = Configuration([NumberParameter(0, array_size, cutoff, "cutoff")]

result = @task optimize(sorting_cutoff,
configuration,
[:simulated_annealing],
args = args,
iterations = iterations,
report_after = report_after,
evaluations = 6,
instances = [4])
instances = [1])
partial = None
for i = 0:iterations
partial = consume(result)
Expand Down
16 changes: 13 additions & 3 deletions src/StochasticSearch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ module StochasticSearch
export perturb!, perturb_elements!, neighbor!,
optimize!, optimize, initialize_cost,
initialize_search_tasks!, get_new_best,
measure_mean!, simulated_annealing, update!,
optimize, unit_value, unit_value!
measure_mean!, update!,
optimize, unit_value, unit_value!,
simulated_annealing, first_improvement,
iterative_first_improvement

# New Methods for Base Functions
import Base.convert, Base.show, Base.getindex,
Expand All @@ -31,11 +33,19 @@ module StochasticSearch
include("core/measurement/measure.jl")
include("core/measurement/results.jl")

# Search
# Search Blocks
include("core/search/blocks/first_improvement.jl")

# Techniques
include("core/search/techniques/iterative_first_improvement.jl")
include("core/search/techniques/simulated_annealing.jl")

# Tools
include("core/search/tools/initialize_cost.jl")
include("core/search/tools/initialize_search_tasks!.jl")
include("core/search/tools/get_new_best.jl")

# Optimize
include("core/search/optimize.jl")

# Optim.jl Interface
Expand Down
44 changes: 44 additions & 0 deletions src/core/search/blocks/first_improvement.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
first_improvement(cost::Function,
args::Dict{ASCIIString, Any},
initial_x::Configuration,
initial_cost::Float64,
evaluations::Int,
f_xs::Array{Float64},
cutoff::Int) = begin
x = deepcopy(initial_x)
x_proposal = deepcopy(initial_x)
name = "First Improvement"
f_calls = 0
iteration = 0
f_x = initial_cost
while iteration <= cutoff
iteration += 1
neighbor!(x_proposal)
f_proposal = @fetch (measure_mean!(cost,
x_proposal,
args,
evaluations,
f_xs))
f_calls += evaluations
if f_proposal <= f_x
update!(x, x_proposal.parameters)
f_x = f_proposal
return Result(name,
initial_x,
x,
f_x,
iteration,
iteration,
f_calls,
false)
end
end
Result(name,
initial_x,
x,
f_x,
iteration,
iteration,
f_calls,
false)
end
4 changes: 2 additions & 2 deletions src/core/search/optimize.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
optimize(f::Function,
initial_x::Configuration;
methods::Array{Symbol} = [:simulated_annealing],
initial_x::Configuration,
methods::Array{Symbol};
args::Dict{ASCIIString, Any} = Dict{ASCIIString,Any}(),
instances::Array{Int} = [1],
iterations::Int = 1_000,
Expand Down
37 changes: 37 additions & 0 deletions src/core/search/techniques/iterative_first_improvement.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
iterative_first_improvement(cost::Function,
args::Dict{ASCIIString, Any},
initial_x::Configuration,
initial_cost::Float64;
cutoff::Int = 10,
evaluations::Int = 3,
iterations::Int = 100_000) = begin
x = deepcopy(initial_x)
name = "Iterative First Improvement"
f_calls = 0
iteration = 0
f_xs = Float64[]
for i = 1:evaluations
push!(f_xs, 0.0)
end
f_x = initial_cost
f_calls += evaluations
while iteration <= iterations
iteration += 1
neighbor!(x)
# First Improvement never produces a worse result.
result = first_improvement(cost,
args,
x,
f_x,
evaluations,
f_xs,
cutoff)
f_calls += result.cost_calls
result.cost_calls = f_calls
result.start = initial_x
result.technique = name
result.iterations = iteration
result.current_iteration = iteration
produce(result)
end
end
14 changes: 7 additions & 7 deletions src/core/search/techniques/simulated_annealing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
#
log_temperature(t::Real) = 1 / log(t)

simulated_annealing{T <: Configuration}(cost::Function,
args::Dict{ASCIIString, Any},
initial_x::T,
initial_cost::Float64;
temperature::Function = log_temperature,
evaluations::Int = 3,
iterations::Int = 100_000) = begin
simulated_annealing(cost::Function,
args::Dict{ASCIIString, Any},
initial_x::Configuration,
initial_cost::Float64;
temperature::Function = log_temperature,
evaluations::Int = 3,
iterations::Int = 100_000) = begin
x = deepcopy(initial_x)
x_proposal = deepcopy(initial_x)
name = "Simulated Annealing"
Expand Down
9 changes: 9 additions & 0 deletions src/core/search/tools/initialize_search_tasks!.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ initialize_search_tasks!(f::Function,
iterations = iterations,
evaluations = evaluations))
end
elseif methods[i] == :iterative_first_improvement
for j = 1:instances[i]
push!(task_list, @task iterative_first_improvement(f,
args,
initial_x,
initial_f_x,
iterations = iterations,
evaluations = evaluations))
end
else
error("Error: Unknown Method.")
end
Expand Down
30 changes: 30 additions & 0 deletions test/iterative_first_improvement.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using StochasticSearch, FactCheck, Base.Test

facts("[Search]") do
context("iterative_first_improvement") do
function rosenbrock(x::Configuration)
return (1.0 - x["i0"].value)^2 + 100.0 * (x["i1"].value - x["i0"].value^2)^2
end
configuration = Configuration([NumberParameter(-2.0,2.0,0.0,"i0"),
NumberParameter(-2.0,2.0,0.0,"i1")],
"rosenbrock_config")
iterations = 1_000
report_after = 333
run_task = @task optimize(rosenbrock,
configuration,
[:iterative_first_improvement],
iterations = iterations,
report_after = report_after)
result = None
for i = 1:iterations
result = consume(run_task)
end
rr = rosenbrock(result.minimum)
rc = result.cost_minimum
@test_approx_eq rc rr
@fact (configuration["i0"].value != result.minimum["i0"].value) --> true
@fact (rosenbrock(result.minimum) <= rosenbrock(configuration)) --> true
@fact_throws ErrorException optimize(rosenbrock, configuration, [:bozo_search])
println(rosenbrock(result.minimum))
end
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ include("parameter.jl")
include("configuration.jl")
include("optim_interface.jl")
include("simulated_annealing.jl")
include("iterative_first_improvement.jl")
include("unit_value.jl")

FactCheck.exitstatus()
3 changes: 2 additions & 1 deletion test/simulated_annealing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ facts("[Search]") do
report_after = 333
run_task = @task optimize(rosenbrock,
configuration,
[:simulated_annealing],
iterations = iterations,
report_after = report_after)
result = None
Expand All @@ -23,7 +24,7 @@ facts("[Search]") do
@test_approx_eq rc rr
@fact (configuration["i0"].value != result.minimum["i0"].value) --> true
@fact (rosenbrock(result.minimum) <= rosenbrock(configuration)) --> true
@fact_throws ErrorException optimize(rosenbrock, configuration, methods = [:bozo_search])
@fact_throws ErrorException optimize(rosenbrock, configuration, [:bozo_search])
println(rosenbrock(result.minimum))
end
end

0 comments on commit be88c64

Please sign in to comment.