anyoptimization / pymoo

NSGA2, NSGA3, R-NSGA3, MOEAD, Genetic Algorithms (GA), Differential Evolution (DE), CMAES, PSO
https://pymoo.org
Apache License 2.0
2.28k stars 392 forks source link

'RobustTerminaton' object has no attribute 'n_max_gen' #535

Closed KyleYoung1997 closed 9 months ago

KyleYoung1997 commented 10 months ago

Hi when attempting to follow along the example to introduce objective space tolerance termination i.e.

termination = RobustTermination( MultiObjectiveSpaceTermination(tol=0.005, n_skip=5), period=20)

I am getting the following error:

if algorithm.termination.n_max_gen == algorithm.n_gen:
AttributeError: 'RobustTermination' object has no attribute 'n_max_gen'

I attempted to set this when initialising both MultiObjectiveSpaceTermination and RobustTermination as well as inspecting both classes (and DeltaToleranceTermination) but it doesn't appear as if there is any class variable for n_max_gen.

Any guidance here would be appreciated!

Cheers

blankjul commented 10 months ago

Can you provide an example where this code fails?

from pymoo.algorithms.moo.nsga2 import NSGA2
from pymoo.optimize import minimize
from pymoo.problems import get_problem
from pymoo.termination.ftol import MultiObjectiveSpaceTermination
from pymoo.termination.robust import RobustTermination
from pymoo.visualization.scatter import Scatter

problem = get_problem("zdt1")

algorithm = NSGA2(pop_size=100)

termination = RobustTermination(MultiObjectiveSpaceTermination(tol=0.005, n_skip=5), period=20)

res = minimize(problem,
               algorithm,
               termination=termination,
               seed=1,
               verbose=False)

plot = Scatter()
plot.add(problem.pareto_front(), plot_type="line", color="black", alpha=0.7)
plot.add(res.F, facecolor="none", edgecolor="red")
plot.show()

Seems to run without any issue for me.

oli-hall commented 9 months ago

@KyleYoung1997 I also came across this same issue. As the discussion here highlights, the documentation for this Termination appears to be out of date. However, what you can do to get a max generations termination in there as well, is to use a TerminateIfAny to combine the two termination conditions:

from pymoo.core.termination import TerminateIfAny
from pymoo.termination import get_termination
from pymoo.termination.ftol import MultiObjectiveSpaceTermination
from pymoo.termination.robust import RobustTermination

termination = TerminateIfAny(
    RobustTermination(
        MultiObjectiveSpaceTermination(tol=0.005, n_skip=5), 
        period=20
    ),
    get_termination("n_gen", 200)
)
blankjul commented 9 months ago

Ahh yes now I understand what is going wrong even without a code sample. Yes the code snipped above is the correct one. @oli-hall can you send me the link where the documentation needs to be updated?

oli-hall commented 9 months ago

Sure thing @blankjul – I got the tip about the documentation being out of date from this discussion – the documentation page itself is here – the main page that looks at Termination, in particular the section called 'Objective Space Tolerance'. Thanks!

KyleYoung1997 commented 9 months ago

Apologies for the delayed response @blankjul. The fix from @oli-hall works perfectly. Thank you for the assistance.