Skill Tracer
Skills › Scientific Agent Skills › pymoo › lifecycle.md

lifecycle.md

106 lines · skills/pymoo/references/lifecycle.md at 5f2bc03

Open on GitHub
1# Execution, termination, and reproducibility (pymoo 0.6.2)
2

Execution, termination, and reproducibility (pymoo 0.6.2)

Raw lines 1 to 2
3## Bounded runs and callbacks
4
5`minimize` deep-copies the algorithm and termination by default. Inspect the state
6at `result.algorithm`, not the original object. For fresh runs use a fresh
7algorithm or the default copy behavior; reusing an already initialized algorithm
8can resume it instead of starting over.
9
10```python
11import numpy as np
12from pymoo.algorithms.soo.nonconvex.ga import GA
13from pymoo.core.callback import Callback
14from pymoo.optimize import minimize
15from pymoo.problems import get_problem
16from pymoo.termination.default import DefaultSingleObjectiveTermination
18class Progress(Callback):
19 def __init__(self):
20 super().__init__()
21 self.data["trace"] = []
23 def notify(self, algorithm):
24 self.data["trace"].append((algorithm.n_gen,
25 algorithm.evaluator.n_eval, float(algorithm.opt.get("F").min())))
27problem = get_problem("sphere", n_var=3)
28termination = DefaultSingleObjectiveTermination(
29 xtol=1e-8, cvtol=1e-6, ftol=1e-6, period=10,
30 n_max_gen=20, n_max_evals=400)
31result = minimize(problem, GA(pop_size=20), termination,
32 seed=7, callback=Progress(), save_history=False)
33trace = result.algorithm.callback.data["trace"]
34assert trace[-1][1] == result.algorithm.evaluator.n_eval
35assert result.algorithm.n_gen == trace[-1][0] + 1
36```
38`n_gen` counts the initialization as the first generation. After a completed run
39the algorithm's counter has advanced to the next iteration; callback/history
40entries contain the completed generation numbers. `save_history=True` stores deep
41copies and can be costly; callbacks can retain only scalar diagnostics.
43Valid `get_termination` names include `n_gen`, `n_eval`/`n_evals`, `time`, `fmin`,
44`soo`, and `moo`. `get_termination("f_tol", ...)` is obsolete. For multi-objective
45tolerance stopping use `DefaultMultiObjectiveTermination(ftol=..., period=...,
46n_max_gen=..., n_max_evals=...)` or compose the explicit termination classes.
48Termination is checked at iteration boundaries: evaluation/time limits may be
49exceeded by a generation or a slow objective call. They do not interrupt a running
50external simulator. The default combined criteria use OR logic. Larger tolerance
51values make convergence stopping easier; they do **not** disable a criterion,
52despite conflicting prose on the current upstream termination page. For a pure
53budget use `("n_gen", N)` or `("n_eval", N)` directly. MOO objective termination
54tracks normalized ideal/nadir changes and inter-generation IGD; it is not an HV
55or global-optimality test.

Bounded runs and callbacks

minimize deep-copies the algorithm and termination by default. Inspect the state at result.algorithm, not the original object. For fresh runs use a fresh algorithm or the default copy behavior; reusing an already initialized algorithm can resume it instead of starting over.

import numpy as np
from pymoo.algorithms.soo.nonconvex.ga import GA
from pymoo.core.callback import Callback
from pymoo.optimize import minimize
from pymoo.problems import get_problem
from pymoo.termination.default import DefaultSingleObjectiveTermination

class Progress(Callback):
    def __init__(self):
        super().__init__()
        self.data["trace"] = []

    def notify(self, algorithm):
        self.data["trace"].append((algorithm.n_gen,
            algorithm.evaluator.n_eval, float(algorithm.opt.get("F").min())))

problem = get_problem("sphere", n_var=3)
termination = DefaultSingleObjectiveTermination(
    xtol=1e-8, cvtol=1e-6, ftol=1e-6, period=10,
    n_max_gen=20, n_max_evals=400)
result = minimize(problem, GA(pop_size=20), termination,
                  seed=7, callback=Progress(), save_history=False)
trace = result.algorithm.callback.data["trace"]
assert trace[-1][1] == result.algorithm.evaluator.n_eval
assert result.algorithm.n_gen == trace[-1][0] + 1

n_gen counts the initialization as the first generation. After a completed run the algorithm's counter has advanced to the next iteration; callback/history entries contain the completed generation numbers. save_history=True stores deep copies and can be costly; callbacks can retain only scalar diagnostics.

Valid get_termination names include n_gen, n_eval/n_evals, time, fmin, soo, and moo. get_termination("f_tol", ...) is obsolete. For multi-objective tolerance stopping use DefaultMultiObjectiveTermination(ftol=..., period=..., n_max_gen=..., n_max_evals=...) or compose the explicit termination classes.

Termination is checked at iteration boundaries: evaluation/time limits may be exceeded by a generation or a slow objective call. They do not interrupt a running external simulator. The default combined criteria use OR logic. Larger tolerance values make convergence stopping easier; they do not disable a criterion, despite conflicting prose on the current upstream termination page. For a pure budget use ("n_gen", N) or ("n_eval", N) directly. MOO objective termination tracks normalized ideal/nadir changes and inter-generation IGD; it is not an HV or global-optimality test.

Raw lines 3 to 56
57## Resume an algorithm checkpoint
59Install optional `dill` (`uv pip install dill`) for the upstream checkpoint recipe.
60The 0.6.2 algorithm contains decorated functions that failed standard-library
61`pickle` in the tested stack; the `dill` round trip below was tested against an
62uninterrupted run. Only load checkpoints you trust, and record the
63package versions, problem code, transforms, seed protocol, and objective inputs.
64Python object serialization is not a portable cross-version interchange format.
66```python
67import dill
68from pathlib import Path
69from pymoo.termination import get_termination
71first = minimize(problem, GA(pop_size=20), ("n_gen", 3), seed=7)
72checkpoint_path = Path("checkpoint.pkl")
73checkpoint_path.write_bytes(dill.dumps(first.algorithm))
74checkpoint = dill.loads(checkpoint_path.read_bytes())
75checkpoint.termination = get_termination("n_gen", 6) # new total generation limit
76resumed = minimize(problem, checkpoint, copy_algorithm=False)
77assert resumed.algorithm.evaluator.n_eval == 120
78```
80Save `result.algorithm` when default copying is enabled. Alternatively set
81`copy_algorithm=False` on the initial call and save that actual running object.
82Replace an already satisfied termination object before resuming. Preserve the
83algorithm's RNG state; do not reseed workers or regenerate stochastic objective
84outputs accidentally. A table of `X/F/G/H` is biased initialization, not a full
85checkpoint: it lacks algorithm and RNG state. Re-evaluate any imported table if
86its problem/units/constraints differ. Serial checkpoint equality was tested; live
87workers, remote solvers, and changes of dependency versions were not.

Resume an algorithm checkpoint

Install optional dill (uv pip install dill) for the upstream checkpoint recipe. The 0.6.2 algorithm contains decorated functions that failed standard-library pickle in the tested stack; the dill round trip below was tested against an uninterrupted run. Only load checkpoints you trust, and record the package versions, problem code, transforms, seed protocol, and objective inputs. Python object serialization is not a portable cross-version interchange format.

import dill
from pathlib import Path
from pymoo.termination import get_termination

first = minimize(problem, GA(pop_size=20), ("n_gen", 3), seed=7)
checkpoint_path = Path("checkpoint.pkl")
checkpoint_path.write_bytes(dill.dumps(first.algorithm))
checkpoint = dill.loads(checkpoint_path.read_bytes())
checkpoint.termination = get_termination("n_gen", 6)  # new total generation limit
resumed = minimize(problem, checkpoint, copy_algorithm=False)
assert resumed.algorithm.evaluator.n_eval == 120

Save result.algorithm when default copying is enabled. Alternatively set copy_algorithm=False on the initial call and save that actual running object. Replace an already satisfied termination object before resuming. Preserve the algorithm's RNG state; do not reseed workers or regenerate stochastic objective outputs accidentally. A table of X/F/G/H is biased initialization, not a full checkpoint: it lacks algorithm and RNG state. Re-evaluate any imported table if its problem/units/constraints differ. Serial checkpoint equality was tested; live workers, remote solvers, and changes of dependency versions were not.

Raw lines 57 to 88
89## Validation before scientific use
911. Evaluate known feasible/infeasible points and analytic objective values.
922. Check finite outputs, bounds, types, constraint signs, and shape contracts.
933. Inspect raw residuals and the feasible-run rate; failed or infeasible runs are
94 part of the result, not observations to discard silently.
954. For multi-objective output, verify nondominance within the returned set and
96 compare against a credible analytic/reference front if one exists.
975. Compare repeated seeds at equal evaluation budgets and common normalization.
98 Report spread, evaluation count, time, and indicator/reference-point choices.
99 Seed equality in one pinned environment does not imply cross-version or
100 parallel stochastic reproducibility.
102Sources reviewed 2026-10-01: [minimize](https://pymoo.org/interface/minimize.html),
103[callback](https://pymoo.org/interface/callback.html),
104[termination](https://pymoo.org/interface/termination.html),
105[checkpoint](https://pymoo.org/misc/checkpoint.html), and released source under
106`pymoo/core/algorithm.py`, `pymoo/termination/`, and `pymoo/optimize.py`.

Validation before scientific use

  1. Evaluate known feasible/infeasible points and analytic objective values.
  2. Check finite outputs, bounds, types, constraint signs, and shape contracts.
  3. Inspect raw residuals and the feasible-run rate; failed or infeasible runs are part of the result, not observations to discard silently.
  4. For multi-objective output, verify nondominance within the returned set and compare against a credible analytic/reference front if one exists.
  5. Compare repeated seeds at equal evaluation budgets and common normalization. Report spread, evaluation count, time, and indicator/reference-point choices. Seed equality in one pinned environment does not imply cross-version or parallel stochastic reproducibility.

Sources reviewed 2026-10-01: minimize, callback, termination, checkpoint, and released source under pymoo/core/algorithm.py, pymoo/termination/, and pymoo/optimize.py.

Raw lines 89 to 106