Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update __loss function for MOO using OptimizationMetaheuristics.jl #805

Merged
merged 8 commits into from
Aug 30, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,14 @@ function SciMLBase.__solve(cache::OptimizationCache{
maxiters = Optimization._check_and_convert_maxiters(cache.solver_args.maxiters)
maxtime = Optimization._check_and_convert_maxtime(cache.solver_args.maxtime)

f=cache.f
_loss = function (θ)
x = cache.f(θ, cache.p)
return first(x)
if isa(f,MultiObjectiveOptimizationFunction)
return cache.f(θ, cache.p)
else
x = cache.f(θ, cache.p)
return first(x)
end
end

if !isnothing(cache.lb) & !isnothing(cache.ub)
Expand Down
143 changes: 142 additions & 1 deletion lib/OptimizationMetaheuristics/test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using OptimizationMetaheuristics, Optimization
using OptimizationMetaheuristics, Optimization, Random
using Test

Random.seed!(42)
@testset "OptimizationMetaheuristics.jl" begin
rosenbrock(x, p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
x0 = zeros(2)
Expand Down Expand Up @@ -50,4 +51,144 @@ using Test

sol = solve(prob, WOA(), use_initial = true)
@test 10 * sol.objective < l1

# Define the benchmark functions as multi-objective problems
function sphere(x)
f1 = sum(x .^ 2)
f2 = sum((x .- 2.0) .^ 2)
gx = [0.0]
hx = [0.0]
return [f1, f2], gx, hx
end

function rastrigin(x)
f1 = sum(x .^ 2 .- 10 .* cos.(2 .* π .* x) .+ 10)
f2 = sum((x .- 2.0) .^ 2 .- 10 .* cos.(2 .* π .* (x .- 2.0)) .+ 10)
gx = [0.0]
hx = [0.0]
return [f1, f2], gx, hx
end

function rosenbrock(x)
f1 = sum(100 .* (x[2:end] .- x[1:end-1] .^ 2) .^ 2 .+ (x[1:end-1] .- 1) .^ 2)
f2 = sum(100 .* ((x[2:end] .- 2.0) .- (x[1:end-1] .^ 2)) .^ 2 .+ ((x[1:end-1] .- 1.0) .^ 2))
gx = [0.0]
hx = [0.0]
return [f1, f2], gx, hx
end

function ackley(x)
f1 = -20 * exp(-0.2 * sqrt(sum(x .^ 2) / length(x))) - exp(sum(cos.(2 * π .* x)) / length(x)) + 20 + ℯ
f2 = -20 * exp(-0.2 * sqrt(sum((x .- 2.0) .^ 2) / length(x))) - exp(sum(cos.(2 * π .* (x .- 2.0))) / length(x)) + 20 + ℯ
gx = [0.0]
hx = [0.0]
return [f1, f2], gx, hx
end


function dtlz2(x)
g = sum((x[3:end] .- 0.5) .^ 2)
f1 = (1 + g) * cos(x[1] * π / 2) * cos(x[2] * π / 2)
f2 = (1 + g) * cos(x[1] * π / 2) * sin(x[2] * π / 2)
gx = [0.0]
hx = [0.0]
return [f1, f2], gx, hx
end

function schaffer_n2(x)
f1 = x[1]^2
f2 = (x[1] - 2.0)^2
gx = [0.0]
hx = [0.0]
return [f1, f2], gx, hx
end
OBJECTIVES = Dict(
"Metaheuristics.Algorithm{NSGA2} for sphere"=> [2.1903011284699687, 3.9825426762781477],
"Metaheuristics.Algorithm{NSGA3} for sphere"=> [0.36916068436590516, 8.256797942777018],
"Metaheuristics.Algorithm{SPEA2} for sphere"=> [0.6866588142724173, 7.18284015333389],
"Metaheuristics.Algorithm{CCMO{NSGA2}} for sphere"=> [1.6659983952552437, 4.731690734657798],
"Metaheuristics.Algorithm{MOEAD_DE} for sphere"=> [1.3118335977331483, 5.478715622895562],
"Metaheuristics.Algorithm{SMS_EMOA} for sphere"=> [0.5003293369817386, 7.837151299208113],
"Metaheuristics.Algorithm{NSGA2} for rastrigin"=> [0.0, 12.0],
"Metaheuristics.Algorithm{NSGA3} for rastrigin"=> [9.754810555001253, 11.123569741993528],
"Metaheuristics.Algorithm{SPEA2} for rastrigin"=> [0.0, 12.0],
"Metaheuristics.Algorithm{CCMO{NSGA2}} for rastrigin"=> [2.600961284360525, 3.4282466721631755],
"Metaheuristics.Algorithm{MOEAD_DE} for rastrigin"=> [2.4963842982482607, 10.377445766099369],
"Metaheuristics.Algorithm{SMS_EMOA} for rastrigin"=> [0.0, 12.0],
"Metaheuristics.Algorithm{NSGA2} for rosenbrock"=> [17.500214034475118, 586.5039366722865],
"Metaheuristics.Algorithm{NSGA3} for rosenbrock"=> [60.58413196101549, 427.34913230512063] ,
"Metaheuristics.Algorithm{SPEA2} for rosenbrock"=> [37.42314302223994, 498.8799375425481],
"Metaheuristics.Algorithm{CCMO{NSGA2}} for rosenbrock"=> [2.600961284360525, 3.4282466721631755],
"Metaheuristics.Algorithm{MOEAD_DE} for rosenbrock"=> [12.969698120217537, 642.4135236259822],
"Metaheuristics.Algorithm{SMS_EMOA} for rosenbrock"=> [61.6898556398449, 450.62433057243777],
"Metaheuristics.Algorithm{NSGA2} for ackley"=> [2.240787163704834, 5.990002878952371],
"Metaheuristics.Algorithm{NSGA3} for ackley"=> [3.408535107623966, 5.459538604033934],
"Metaheuristics.Algorithm{SPEA2} for ackley"=> [4.440892098500626e-16, 6.593599079287213],
"Metaheuristics.Algorithm{CCMO{NSGA2}} for ackley"=> [2.600961284360525, 3.4282466721631755],
"Metaheuristics.Algorithm{MOEAD_DE} for ackley"=> [4.440892098500626e-16, 6.593599079287213],
"Metaheuristics.Algorithm{SMS_EMOA} for ackley"=> [3.370770500897429, 5.510527199861947],
"Metaheuristics.Algorithm{NSGA2} for dtlz2"=> [0.013283104966270814, 0.010808186786590583],
"Metaheuristics.Algorithm{NSGA3} for dtlz2"=> [0.013428265441897881, 0.03589930489326534],
"Metaheuristics.Algorithm{SPEA2} for dtlz2"=> [0.019006068021099495, 0.0009905093731377751],
"Metaheuristics.Algorithm{CCMO{NSGA2}} for dtlz2"=> [2.600961284360525, 3.4282466721631755],
"Metaheuristics.Algorithm{MOEAD_DE} for dtlz2"=> [0.027075258566241527, 0.00973958317460759],
"Metaheuristics.Algorithm{SMS_EMOA} for dtlz2"=> [0.056304481489060705, 0.026075248436234502],
"Metaheuristics.Algorithm{NSGA2} for schaffer_n2"=> [1.4034569322987955, 0.6647534264038837],
"Metaheuristics.Algorithm{NSGA3} for schaffer_n2"=> [2.7987535368174363, 0.10696329884083178],
"Metaheuristics.Algorithm{SPEA2} for schaffer_n2"=> [0.0007534237111212252, 3.8909591643988075],
"Metaheuristics.Algorithm{CCMO{NSGA2}} for schaffer_n2"=> [3.632401400816196e-17, 4.9294679997494206e-17],
"Metaheuristics.Algorithm{MOEAD_DE} for schaffer_n2"=> [2.50317097527324, 0.17460592430221922],
"Metaheuristics.Algorithm{SMS_EMOA} for schaffer_n2"=> [0.4978888767998813, 1.67543922644328],
)
# Define the testset
@testset "Multi-Objective Optimization with Various Functions and Metaheuristics" begin
# Define the problems and their bounds
problems = [
(sphere, [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]),
(rastrigin, [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]),
(rosenbrock, [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]),
(ackley, [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]),
(dtlz2, [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]),
(schaffer_n2, [0.0, 0.0, 0.0], [2.0, 0.0, 0.0])
]

nobjectives = 2
npartitions = 100

# Define the different algorithms
algs = [
NSGA2(),
NSGA3(),
SPEA2(),
CCMO(NSGA2(N=100, p_m=0.001)),
MOEAD_DE(gen_ref_dirs(nobjectives, npartitions), options=Options(debug=false, iterations = 250)),
SMS_EMOA()
]

# Run tests for each problem and algorithm
for (prob_func, lb, ub) in problems
prob_name = string(prob_func)
for alg in algs
alg_name = string(typeof(alg))
@testset "$alg_name on $prob_name" begin
multi_obj_fun = MultiObjectiveOptimizationFunction((x, p) -> prob_func(x))
prob = OptimizationProblem(multi_obj_fun, lb; lb = lb, ub = ub)
if (alg_name=="Metaheuristics.Algorithm{CCMO{NSGA2}}")
sol = solve(prob, alg)
else
sol = solve(prob, alg; maxiters = 100, use_initial = true)
end

# Tests
@test !isempty(sol.minimizer) # Check that a solution was found

# Use sol.objective to get the objective values
key = "$alg_name for $prob_name"
value = OBJECTIVES[key]
objectives = sol.objective
@test value ≈ objectives atol=1e-1
end
end
end
end
end
Loading