Coverage for moptipy / algorithms / restarts.py: 83%
42 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-24 08:49 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-24 08:49 +0000
1"""Perform restarts of an algorithm that terminates too early."""
2from typing import Callable, Final, TypeVar, cast
4from pycommons.types import type_error
6from moptipy.api.algorithm import Algorithm
7from moptipy.api.mo_algorithm import MOAlgorithm
8from moptipy.api.mo_process import MOProcess
9from moptipy.api.process import Process
10from moptipy.utils.logger import KeyValueLogSection
13class __RestartAlgorithm(Algorithm):
14 """A wrapper around an existing algorithm."""
16 def __init__(self, algorithm: Algorithm) -> None:
17 """
18 Create the algorithm wrapper.
20 :param algorithm: the algorithm to wrap
21 """
22 super().__init__()
23 #: the algorithm
24 self._algo: Final[Algorithm] = algorithm
25 self.initialize = algorithm.initialize # type: ignore # fast call
27 def __str__(self) -> str:
28 """
29 Get the string representation of this algorithm.
31 :returns: `rs_` + sub-algorithm name
32 """
33 return f"rs_{self._algo}"
35 def solve(self, process: Process) -> None:
36 """
37 Solve a single-objective problem.
39 :param process: the process
40 """
41 st: Final[Callable[[], bool]] = process.should_terminate
42 rst: Final[Callable[[], None]] = self._algo.initialize
43 sv: Final[Callable[[Process], None]] = self._algo.solve
44 while not st():
45 rst()
46 sv(process)
48 def log_parameters_to(self, logger: KeyValueLogSection) -> None:
49 """
50 Store the parameters of this algorithm wrapper to the logger.
52 :param logger: the logger
53 """
54 super().log_parameters_to(logger)
55 with logger.scope("a") as scope:
56 self._algo.log_parameters_to(scope)
59class __RestartMOAlgorithm(__RestartAlgorithm, MOAlgorithm):
60 """A wrapper around an existing multi-objective algorithm."""
62 def solve_mo(self, process: MOProcess) -> None:
63 """
64 Solve a multi-objective problem.
66 :param process: the process
67 """
68 st: Final[Callable[[], bool]] = process.should_terminate
69 rst: Final[Callable[[], None]] = self.initialize
70 sv: Final[Callable[[MOProcess], None]] = cast(
71 "MOAlgorithm", self._algo).solve_mo
72 while not st():
73 rst()
74 sv(process)
76 def __str__(self) -> str:
77 """
78 Get the string representation of this algorithm.
80 :returns: `mors_` + sub-algorithm name
81 """
82 return f"mors_{self._algo}"
85#: the type variable for single- and multi-objective algorithms.
86T = TypeVar("T", Algorithm, MOAlgorithm)
89def restarts(algorithm: T) -> T:
90 """
91 Perform restarts of an algorithm until the termination criterion is met.
93 :param algorithm: the algorithm
94 """
95 if isinstance(algorithm, MOAlgorithm):
96 return __RestartMOAlgorithm(algorithm)
97 if isinstance(algorithm, Algorithm):
98 return __RestartAlgorithm(algorithm)
99 raise type_error(algorithm, "algorithm", (Algorithm, MOAlgorithm))