jmejia8 / Metaheuristics.jl

High-performance metaheuristics for optimization coded purely in Julia.
https://jmejia8.github.io/Metaheuristics.jl/stable/
Other
253 stars 27 forks source link

How to access non-dominated points in multiobjective optimization? #85

Closed licheng0794 closed 1 year ago

licheng0794 commented 1 year ago

I know using positions(result) can return the population of each iteration. But I do not know which function can help to access the current non-dominated points (for both X and f(X)) after each iteration? Thank you.

jmejia8 commented 1 year ago

Use the logger argument in optimize method.

function logger(status)
    @info "Iteration $(status.iteration)"
    # get non-dominated solutions
    P = Metaheuristics.get_non_dominated_solutions(status.population)
    X = positions(P) # decisions variables
    FX = fvals(P) # objective function values
    display(FX)
end

f, bounds, _ = Metaheuristics.TestProblems.ZDT1();
res = optimize(f, bounds, NSGA2(), logger=logger)

See optimize, Metaheuristics.get_non_dominated_solutions, and the API References for more details.

licheng0794 commented 1 year ago

Use the logger argument in optimize method.

function logger(status)
    @info "Iteration $(status.iteration)"
    # get non-dominated solutions
    P = Metaheuristics.get_non_dominated_solutions(status.population)
    X = positions(P) # decisions variables
    FX = fvals(P) # objective function values
    display(FX)
end

f, bounds, _ = Metaheuristics.TestProblems.ZDT1();
res = optimize(f, bounds, NSGA2(), logger=logger)

See optimize, Metaheuristics.get_non_dominated_solutions, and the API References for more details.

Thank you.

Metaheuristics.get_non_dominated_solutions(status.population) returns the current non dominated points from the current population. How if I want all of the non dominated points so far?

fval requires a repeat evaluation. If the function is expensive, fval takes very long. Is there an alternative which directly access the function values of the non-dominated points saved?

jmejia8 commented 1 year ago

How if I want all of the non dominated points so far?

Depending on the algorithm, get_non_dominated_solutions will return all the non-dominated solutions found so far (until density estimator is used to removing solutions). Try using (assuming you're using NSGA2) NSGA2(options=Options(store_convergence=true)), which will save (in res.convergence) the status at each iteration.

Another option is to use an external archive to save the results using the logger function.

archive = []
logger(status) = push!(archive, status.population)
res = optimize(f, bounds, NSGA2(), logger=logger)
iteration = 1
display(fvals(archive[iteration]))

fval requires a repeat evaluation

Actually fval and fvals do not require re-evaluating solutions due to function values are stored in status.population.

licheng0794 commented 1 year ago

Actually fval and fvals do not require re-evaluating solutions due to function values are stored in status.population.

I indeed tested the function 'fval' and found that it took much long so I supposed it did re-evaluate the function. Can you please confirm that? Thank you.

jmejia8 commented 1 year ago

I'm pretty sure that Metaheuristics.fval(sol) is not re-evaluating sol to provide an output. You can see the function definition by typing:

@edit fval(res.population[1])

I'm assuming you did not overwrite the fval method.