desdeo 1.2__py3-none-any.whl → 2.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. desdeo/__init__.py +8 -8
  2. desdeo/adm/ADMAfsar.py +551 -0
  3. desdeo/adm/ADMChen.py +414 -0
  4. desdeo/adm/BaseADM.py +119 -0
  5. desdeo/adm/__init__.py +11 -0
  6. desdeo/api/README.md +73 -0
  7. desdeo/api/__init__.py +15 -0
  8. desdeo/api/app.py +50 -0
  9. desdeo/api/config.py +90 -0
  10. desdeo/api/config.toml +64 -0
  11. desdeo/api/db.py +27 -0
  12. desdeo/api/db_init.py +85 -0
  13. desdeo/api/db_models.py +164 -0
  14. desdeo/api/malaga_db_init.py +27 -0
  15. desdeo/api/models/__init__.py +266 -0
  16. desdeo/api/models/archive.py +23 -0
  17. desdeo/api/models/emo.py +128 -0
  18. desdeo/api/models/enautilus.py +69 -0
  19. desdeo/api/models/gdm/gdm_aggregate.py +139 -0
  20. desdeo/api/models/gdm/gdm_base.py +69 -0
  21. desdeo/api/models/gdm/gdm_score_bands.py +114 -0
  22. desdeo/api/models/gdm/gnimbus.py +138 -0
  23. desdeo/api/models/generic.py +104 -0
  24. desdeo/api/models/generic_states.py +401 -0
  25. desdeo/api/models/nimbus.py +158 -0
  26. desdeo/api/models/preference.py +128 -0
  27. desdeo/api/models/problem.py +717 -0
  28. desdeo/api/models/reference_point_method.py +18 -0
  29. desdeo/api/models/session.py +49 -0
  30. desdeo/api/models/state.py +463 -0
  31. desdeo/api/models/user.py +52 -0
  32. desdeo/api/models/utopia.py +25 -0
  33. desdeo/api/routers/_EMO.backup +309 -0
  34. desdeo/api/routers/_NAUTILUS.py +245 -0
  35. desdeo/api/routers/_NAUTILUS_navigator.py +233 -0
  36. desdeo/api/routers/_NIMBUS.py +765 -0
  37. desdeo/api/routers/__init__.py +5 -0
  38. desdeo/api/routers/emo.py +497 -0
  39. desdeo/api/routers/enautilus.py +237 -0
  40. desdeo/api/routers/gdm/gdm_aggregate.py +234 -0
  41. desdeo/api/routers/gdm/gdm_base.py +420 -0
  42. desdeo/api/routers/gdm/gdm_score_bands/gdm_score_bands_manager.py +398 -0
  43. desdeo/api/routers/gdm/gdm_score_bands/gdm_score_bands_routers.py +377 -0
  44. desdeo/api/routers/gdm/gnimbus/gnimbus_manager.py +698 -0
  45. desdeo/api/routers/gdm/gnimbus/gnimbus_routers.py +591 -0
  46. desdeo/api/routers/generic.py +233 -0
  47. desdeo/api/routers/nimbus.py +705 -0
  48. desdeo/api/routers/problem.py +307 -0
  49. desdeo/api/routers/reference_point_method.py +93 -0
  50. desdeo/api/routers/session.py +100 -0
  51. desdeo/api/routers/test.py +16 -0
  52. desdeo/api/routers/user_authentication.py +520 -0
  53. desdeo/api/routers/utils.py +187 -0
  54. desdeo/api/routers/utopia.py +230 -0
  55. desdeo/api/schema.py +100 -0
  56. desdeo/api/tests/__init__.py +0 -0
  57. desdeo/api/tests/conftest.py +151 -0
  58. desdeo/api/tests/test_enautilus.py +330 -0
  59. desdeo/api/tests/test_models.py +1179 -0
  60. desdeo/api/tests/test_routes.py +1075 -0
  61. desdeo/api/utils/_database.py +263 -0
  62. desdeo/api/utils/_logger.py +29 -0
  63. desdeo/api/utils/database.py +36 -0
  64. desdeo/api/utils/emo_database.py +40 -0
  65. desdeo/core.py +34 -0
  66. desdeo/emo/__init__.py +159 -0
  67. desdeo/emo/hooks/archivers.py +188 -0
  68. desdeo/emo/methods/EAs.py +541 -0
  69. desdeo/emo/methods/__init__.py +0 -0
  70. desdeo/emo/methods/bases.py +12 -0
  71. desdeo/emo/methods/templates.py +111 -0
  72. desdeo/emo/operators/__init__.py +1 -0
  73. desdeo/emo/operators/crossover.py +1282 -0
  74. desdeo/emo/operators/evaluator.py +114 -0
  75. desdeo/emo/operators/generator.py +459 -0
  76. desdeo/emo/operators/mutation.py +1224 -0
  77. desdeo/emo/operators/scalar_selection.py +202 -0
  78. desdeo/emo/operators/selection.py +1778 -0
  79. desdeo/emo/operators/termination.py +286 -0
  80. desdeo/emo/options/__init__.py +108 -0
  81. desdeo/emo/options/algorithms.py +435 -0
  82. desdeo/emo/options/crossover.py +164 -0
  83. desdeo/emo/options/generator.py +131 -0
  84. desdeo/emo/options/mutation.py +260 -0
  85. desdeo/emo/options/repair.py +61 -0
  86. desdeo/emo/options/scalar_selection.py +66 -0
  87. desdeo/emo/options/selection.py +127 -0
  88. desdeo/emo/options/templates.py +383 -0
  89. desdeo/emo/options/termination.py +143 -0
  90. desdeo/explanations/__init__.py +6 -0
  91. desdeo/explanations/explainer.py +100 -0
  92. desdeo/explanations/utils.py +90 -0
  93. desdeo/gdm/__init__.py +22 -0
  94. desdeo/gdm/gdmtools.py +45 -0
  95. desdeo/gdm/score_bands.py +114 -0
  96. desdeo/gdm/voting_rules.py +50 -0
  97. desdeo/mcdm/__init__.py +41 -0
  98. desdeo/mcdm/enautilus.py +338 -0
  99. desdeo/mcdm/gnimbus.py +484 -0
  100. desdeo/mcdm/nautili.py +345 -0
  101. desdeo/mcdm/nautilus.py +477 -0
  102. desdeo/mcdm/nautilus_navigator.py +656 -0
  103. desdeo/mcdm/nimbus.py +417 -0
  104. desdeo/mcdm/pareto_navigator.py +269 -0
  105. desdeo/mcdm/reference_point_method.py +186 -0
  106. desdeo/problem/__init__.py +83 -0
  107. desdeo/problem/evaluator.py +561 -0
  108. desdeo/problem/external/__init__.py +18 -0
  109. desdeo/problem/external/core.py +356 -0
  110. desdeo/problem/external/pymoo_provider.py +266 -0
  111. desdeo/problem/external/runtime.py +44 -0
  112. desdeo/problem/gurobipy_evaluator.py +562 -0
  113. desdeo/problem/infix_parser.py +341 -0
  114. desdeo/problem/json_parser.py +944 -0
  115. desdeo/problem/pyomo_evaluator.py +487 -0
  116. desdeo/problem/schema.py +1829 -0
  117. desdeo/problem/simulator_evaluator.py +348 -0
  118. desdeo/problem/sympy_evaluator.py +244 -0
  119. desdeo/problem/testproblems/__init__.py +88 -0
  120. desdeo/problem/testproblems/benchmarks_server.py +120 -0
  121. desdeo/problem/testproblems/binh_and_korn_problem.py +88 -0
  122. desdeo/problem/testproblems/cake_problem.py +185 -0
  123. desdeo/problem/testproblems/dmitry_forest_problem_discrete.py +71 -0
  124. desdeo/problem/testproblems/dtlz2_problem.py +102 -0
  125. desdeo/problem/testproblems/forest_problem.py +283 -0
  126. desdeo/problem/testproblems/knapsack_problem.py +163 -0
  127. desdeo/problem/testproblems/mcwb_problem.py +831 -0
  128. desdeo/problem/testproblems/mixed_variable_dimenrions_problem.py +83 -0
  129. desdeo/problem/testproblems/momip_problem.py +172 -0
  130. desdeo/problem/testproblems/multi_valued_constraints.py +119 -0
  131. desdeo/problem/testproblems/nimbus_problem.py +143 -0
  132. desdeo/problem/testproblems/pareto_navigator_problem.py +89 -0
  133. desdeo/problem/testproblems/re_problem.py +492 -0
  134. desdeo/problem/testproblems/river_pollution_problems.py +440 -0
  135. desdeo/problem/testproblems/rocket_injector_design_problem.py +140 -0
  136. desdeo/problem/testproblems/simple_problem.py +351 -0
  137. desdeo/problem/testproblems/simulator_problem.py +92 -0
  138. desdeo/problem/testproblems/single_objective.py +289 -0
  139. desdeo/problem/testproblems/spanish_sustainability_problem.py +945 -0
  140. desdeo/problem/testproblems/zdt_problem.py +274 -0
  141. desdeo/problem/utils.py +245 -0
  142. desdeo/tools/GenerateReferencePoints.py +181 -0
  143. desdeo/tools/__init__.py +120 -0
  144. desdeo/tools/desc_gen.py +22 -0
  145. desdeo/tools/generics.py +165 -0
  146. desdeo/tools/group_scalarization.py +3090 -0
  147. desdeo/tools/gurobipy_solver_interfaces.py +258 -0
  148. desdeo/tools/indicators_binary.py +117 -0
  149. desdeo/tools/indicators_unary.py +362 -0
  150. desdeo/tools/interaction_schema.py +38 -0
  151. desdeo/tools/intersection.py +54 -0
  152. desdeo/tools/iterative_pareto_representer.py +99 -0
  153. desdeo/tools/message.py +265 -0
  154. desdeo/tools/ng_solver_interfaces.py +199 -0
  155. desdeo/tools/non_dominated_sorting.py +134 -0
  156. desdeo/tools/patterns.py +283 -0
  157. desdeo/tools/proximal_solver.py +99 -0
  158. desdeo/tools/pyomo_solver_interfaces.py +477 -0
  159. desdeo/tools/reference_vectors.py +229 -0
  160. desdeo/tools/scalarization.py +2065 -0
  161. desdeo/tools/scipy_solver_interfaces.py +454 -0
  162. desdeo/tools/score_bands.py +627 -0
  163. desdeo/tools/utils.py +388 -0
  164. desdeo/tools/visualizations.py +67 -0
  165. desdeo/utopia_stuff/__init__.py +0 -0
  166. desdeo/utopia_stuff/data/1.json +15 -0
  167. desdeo/utopia_stuff/data/2.json +13 -0
  168. desdeo/utopia_stuff/data/3.json +15 -0
  169. desdeo/utopia_stuff/data/4.json +17 -0
  170. desdeo/utopia_stuff/data/5.json +15 -0
  171. desdeo/utopia_stuff/from_json.py +40 -0
  172. desdeo/utopia_stuff/reinit_user.py +38 -0
  173. desdeo/utopia_stuff/utopia_db_init.py +212 -0
  174. desdeo/utopia_stuff/utopia_problem.py +403 -0
  175. desdeo/utopia_stuff/utopia_problem_old.py +415 -0
  176. desdeo/utopia_stuff/utopia_reference_solutions.py +79 -0
  177. desdeo-2.1.0.dist-info/METADATA +186 -0
  178. desdeo-2.1.0.dist-info/RECORD +180 -0
  179. {desdeo-1.2.dist-info → desdeo-2.1.0.dist-info}/WHEEL +1 -1
  180. desdeo-2.1.0.dist-info/licenses/LICENSE +21 -0
  181. desdeo-1.2.dist-info/METADATA +0 -16
  182. desdeo-1.2.dist-info/RECORD +0 -4
@@ -0,0 +1,541 @@
1
+ """[Deprecated] Implements common evolutionary algorithms for multi-objective optimization.
2
+
3
+ Use desdeo.emo.options.algorithms instead.
4
+ """
5
+
6
+ from collections.abc import Callable
7
+ from functools import partial
8
+ from warnings import warn
9
+
10
+ import numpy as np
11
+
12
+ from desdeo.emo.methods.templates import EMOResult, template1, template2
13
+ from desdeo.emo.operators.crossover import SimulatedBinaryCrossover, UniformMixedIntegerCrossover
14
+ from desdeo.emo.operators.evaluator import EMOEvaluator
15
+ from desdeo.emo.operators.generator import LHSGenerator, RandomMixedIntegerGenerator
16
+ from desdeo.emo.operators.mutation import BoundedPolynomialMutation, MixedIntegerRandomMutation
17
+ from desdeo.emo.operators.scalar_selection import TournamentSelection
18
+ from desdeo.emo.operators.selection import IBEASelector, NSGA3Selector, ReferenceVectorOptions, RVEASelector
19
+ from desdeo.emo.operators.termination import MaxEvaluationsTerminator, MaxGenerationsTerminator
20
+ from desdeo.problem import Problem
21
+ from desdeo.tools.indicators_binary import self_epsilon
22
+ from desdeo.tools.patterns import Publisher
23
+
24
+ warn(
25
+ "desdeo.emo.methods.EAs is deprecated and will be removed in future versions. "
26
+ "Please use desdeo.emo.options.algorithms instead.",
27
+ category=DeprecationWarning,
28
+ stacklevel=1,
29
+ )
30
+
31
+
32
+ def rvea(
33
+ *,
34
+ problem: Problem,
35
+ seed: int = 0,
36
+ n_generations=100,
37
+ max_evaluations: int | None = None,
38
+ reference_vector_options: ReferenceVectorOptions = None,
39
+ forced_verbosity: int | None = None,
40
+ ) -> tuple[Callable[[], EMOResult], Publisher]:
41
+ """Implements the Reference Vector Guided Evolutionary Algorithm (RVEA), as well as its interactive version.
42
+
43
+ References:
44
+ R. Cheng, Y. Jin, M. Olhofer and B. Sendhoff, "A Reference Vector Guided Evolutionary Algorithm for Many-
45
+ Objective Optimization," in IEEE Transactions on Evolutionary Computation, vol. 20, no. 5, pp. 773-791,
46
+ Oct. 2016, doi: 10.1109/TEVC.2016.2519378.
47
+
48
+ J. Hakanen, T. Chugh, K. Sindhya, Y. Jin, and K. Miettinen, “Connections of reference vectors and different
49
+ types of preference information in interactive multiobjective evolutionary algorithms,” in 2016 IEEE Symposium
50
+ Series on Computational Intelligence (SSCI), Athens, Greece: IEEE, Dec. 2016, pp. 1-8.
51
+
52
+
53
+ Args:
54
+ problem (Problem): The problem to be solved.
55
+ seed (int, optional): The seed for the random number generator. Defaults to 0.
56
+ n_generations (int, optional): The number of generations to run the algorithm. Defaults to 100.
57
+ max_evaluations (int, optional): The maximum number of evaluations to run the algorithm. If None, the algorithm
58
+ will run for n_generations. Defaults to None. If both n_generations and max_evaluations are provided, the
59
+ algorithm will run until max_evaluations is reached.
60
+ reference_vector_options (ReferenceVectorOptions, optional): The options for the reference vectors. Defaults to
61
+ None. See the ReferenceVectorOptions class for the defaults. This option can be used to run an interactive
62
+ version of the algorithm, using preferences provided by the user.
63
+ forced_verbosity (int, optional): If not None, the verbosity of the algorithm is forced to this value. Defaults
64
+ to None.
65
+
66
+ Returns:
67
+ tuple[Callable[[], EMOResult], Publisher]: A tuple containing the function to run the algorithm and the
68
+ publisher object. The publisher object can be used to subscribe to the topics of the algorithm components,
69
+ as well as to inject additional functionality such as archiving the results.
70
+ """
71
+ publisher = Publisher()
72
+ evaluator = EMOEvaluator(
73
+ problem=problem,
74
+ publisher=publisher,
75
+ verbosity=forced_verbosity if forced_verbosity is not None else 2,
76
+ )
77
+
78
+ selector = RVEASelector(
79
+ problem=problem,
80
+ publisher=publisher,
81
+ reference_vector_options=reference_vector_options,
82
+ verbosity=forced_verbosity if forced_verbosity is not None else 2,
83
+ )
84
+
85
+ # Note that the initial population size is equal to the number of reference vectors
86
+ n_points = selector.reference_vectors.shape[0]
87
+
88
+ generator = LHSGenerator(
89
+ problem=problem,
90
+ evaluator=evaluator,
91
+ publisher=publisher,
92
+ n_points=n_points,
93
+ seed=seed,
94
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
95
+ )
96
+ crossover = SimulatedBinaryCrossover(
97
+ problem=problem,
98
+ publisher=publisher,
99
+ seed=seed,
100
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
101
+ )
102
+ mutation = BoundedPolynomialMutation(
103
+ problem=problem,
104
+ publisher=publisher,
105
+ seed=seed,
106
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
107
+ )
108
+
109
+ if max_evaluations is not None:
110
+ terminator = MaxEvaluationsTerminator(max_evaluations, publisher=publisher)
111
+ else:
112
+ terminator = MaxGenerationsTerminator(n_generations, publisher=publisher)
113
+
114
+ components = [evaluator, generator, crossover, mutation, selector, terminator]
115
+ [publisher.auto_subscribe(x) for x in components]
116
+ [publisher.register_topics(x.provided_topics[x.verbosity], x.__class__.__name__) for x in components]
117
+
118
+ return (
119
+ partial(
120
+ template1,
121
+ evaluator=evaluator,
122
+ crossover=crossover,
123
+ mutation=mutation,
124
+ generator=generator,
125
+ selection=selector,
126
+ terminator=terminator,
127
+ ),
128
+ publisher,
129
+ )
130
+
131
+
132
+ def nsga3(
133
+ *,
134
+ problem: Problem,
135
+ seed: int = 0,
136
+ n_generations: int = 100,
137
+ max_evaluations: int | None = None,
138
+ reference_vector_options: ReferenceVectorOptions = None,
139
+ forced_verbosity: int | None = None,
140
+ ) -> tuple[Callable[[], EMOResult], Publisher]:
141
+ """Implements the NSGA-III algorithm as well as its interactive version.
142
+
143
+ References:
144
+ K. Deb and H. Jain, “An Evolutionary Many-Objective Optimization Algorithm Using Reference-Point-Based
145
+ Nondominated Sorting Approach, Part I: Solving Problems With Box Constraints,” IEEE Transactions on Evolutionary
146
+ Computation, vol. 18, no. 4, pp. 577-601, Aug. 2014.
147
+
148
+ J. Hakanen, T. Chugh, K. Sindhya, Y. Jin, and K. Miettinen, “Connections of reference vectors and different
149
+ types of preference information in interactive multiobjective evolutionary algorithms,” in 2016 IEEE Symposium
150
+ Series on Computational Intelligence (SSCI), Athens, Greece: IEEE, Dec. 2016, pp. 1-8.
151
+
152
+ Args:
153
+ problem (Problem): The problem to be solved.
154
+ seed (int, optional): The seed for the random number generator. Defaults to 0.
155
+ n_generations (int, optional): The number of generations to run the algorithm. Defaults to 100.
156
+ max_evaluations (int, optional): The maximum number of evaluations to run the algorithm. If None, the algorithm
157
+ will run for n_generations. Defaults to None. If both n_generations and max_evaluations are provided, the
158
+ algorithm will run until max_evaluations is reached.
159
+ reference_vector_options (ReferenceVectorOptions, optional): The options for the reference vectors. Defaults to
160
+ None. See the ReferenceVectorOptions class for the defaults. This option can be used to run an interactive
161
+ version of the algorithm, using preferences provided by the user.
162
+ forced_verbosity (int, optional): If not None, the verbosity of the algorithm is forced to this value. Defaults
163
+ to None.
164
+
165
+ Returns:
166
+ tuple[Callable[[], EMOResult], Publisher]: A tuple containing the function to run the algorithm and the
167
+ publisher object. The publisher object can be used to subscribe to the topics of the algorithm components,
168
+ as well as to inject additional functionality such as archiving the results.
169
+ """
170
+ publisher = Publisher()
171
+ evaluator = EMOEvaluator(
172
+ problem=problem,
173
+ publisher=publisher,
174
+ verbosity=forced_verbosity if forced_verbosity is not None else 2,
175
+ )
176
+
177
+ selector = NSGA3Selector(
178
+ problem=problem,
179
+ publisher=publisher,
180
+ verbosity=forced_verbosity if forced_verbosity is not None else 2,
181
+ reference_vector_options=reference_vector_options,
182
+ )
183
+
184
+ # Note that the initial population size is equal to the number of reference vectors
185
+ n_points = selector.reference_vectors.shape[0]
186
+
187
+ generator = LHSGenerator(
188
+ problem=problem,
189
+ evaluator=evaluator,
190
+ publisher=publisher,
191
+ n_points=n_points,
192
+ seed=seed,
193
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
194
+ )
195
+ crossover = SimulatedBinaryCrossover(
196
+ problem=problem,
197
+ publisher=publisher,
198
+ seed=seed,
199
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
200
+ )
201
+ mutation = BoundedPolynomialMutation(
202
+ problem=problem,
203
+ publisher=publisher,
204
+ seed=seed,
205
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
206
+ )
207
+
208
+ if max_evaluations is not None:
209
+ terminator = MaxEvaluationsTerminator(max_evaluations, publisher=publisher)
210
+ else:
211
+ terminator = MaxGenerationsTerminator(
212
+ n_generations,
213
+ publisher=publisher,
214
+ )
215
+
216
+ components = [evaluator, generator, crossover, mutation, selector, terminator]
217
+ [publisher.auto_subscribe(x) for x in components]
218
+ [publisher.register_topics(x.provided_topics[x.verbosity], x.__class__.__name__) for x in components]
219
+
220
+ return (
221
+ partial(
222
+ template1,
223
+ evaluator=evaluator,
224
+ crossover=crossover,
225
+ mutation=mutation,
226
+ generator=generator,
227
+ selection=selector,
228
+ terminator=terminator,
229
+ ),
230
+ publisher,
231
+ )
232
+
233
+
234
+ def ibea(
235
+ *,
236
+ problem: Problem,
237
+ population_size: int = 100,
238
+ n_generations: int = 100,
239
+ max_evaluations: int | None = None,
240
+ kappa: float = 0.05,
241
+ binary_indicator: Callable[[np.ndarray], np.ndarray] = self_epsilon,
242
+ seed: int = 0,
243
+ forced_verbosity: int | None = None,
244
+ ) -> tuple[Callable[[], EMOResult], Publisher]:
245
+ """Implements the Indicator-Based Evolutionary Algorithm (IBEA).
246
+
247
+ References:
248
+ Zitzler, E., Künzli, S. (2004). Indicator-Based Selection in Multiobjective Search. In: Yao, X., et al.
249
+ Parallel Problem Solving from Nature - PPSN VIII. PPSN 2004. Lecture Notes in Computer Science, vol 3242.
250
+ Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-30217-9_84
251
+
252
+ Args:
253
+ problem (Problem): The problem to be solved.
254
+ population_size (int, optional): The size of the population. Defaults to 100.
255
+ n_generations (int, optional): The number of generations to run the algorithm. Defaults to 100.
256
+ max_evaluations (int | None, optional): The maximum number of evaluations to run the algorithm. If None, the
257
+ algorithm will run for n_generations. Defaults to None. If both n_generations and max_evaluations are
258
+ provided, the algorithm will run until max_evaluations is reached.
259
+ kappa (float, optional): The kappa value for the IBEA selection. Defaults to 0.05.
260
+ binary_indicator (Callable[[np.ndarray], np.ndarray], optional): A binary indicator function that takes the
261
+ target values and returns a binary indicator for each individual. Defaults to self_epsilon with uses
262
+ binary adaptive epsilon indicator.
263
+ seed (int, optional): The seed for the random number generator. Defaults to 0.
264
+ forced_verbosity (int | None, optional): If not None, the verbosity of the algorithm is forced to this value.
265
+ Defaults to None.
266
+
267
+ Returns:
268
+ tuple[Callable[[], EMOResult], Publisher]: A tuple containing the function to run the algorithm and the
269
+ publisher object. The publisher object can be used to subscribe to the topics of the algorithm components,
270
+ as well as to inject additional functionality such as archiving the results.
271
+ """
272
+ publisher = Publisher()
273
+ evaluator = EMOEvaluator(
274
+ problem=problem,
275
+ publisher=publisher,
276
+ verbosity=forced_verbosity if forced_verbosity is not None else 2,
277
+ )
278
+ selector = IBEASelector(
279
+ problem=problem,
280
+ verbosity=forced_verbosity if forced_verbosity is not None else 2,
281
+ publisher=publisher,
282
+ population_size=population_size,
283
+ kappa=kappa,
284
+ binary_indicator=binary_indicator,
285
+ )
286
+ generator = LHSGenerator(
287
+ problem=problem,
288
+ evaluator=evaluator,
289
+ publisher=publisher,
290
+ n_points=population_size,
291
+ seed=seed,
292
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
293
+ )
294
+ crossover = SimulatedBinaryCrossover(
295
+ problem=problem,
296
+ publisher=publisher,
297
+ seed=seed,
298
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
299
+ )
300
+ mutation = BoundedPolynomialMutation(
301
+ problem=problem,
302
+ publisher=publisher,
303
+ seed=seed,
304
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
305
+ )
306
+ if max_evaluations is not None:
307
+ terminator = MaxEvaluationsTerminator(max_evaluations, publisher=publisher)
308
+ else:
309
+ terminator = MaxGenerationsTerminator(
310
+ n_generations,
311
+ publisher=publisher,
312
+ )
313
+
314
+ scalar_selector = TournamentSelection(publisher=publisher, verbosity=0, winner_size=population_size, seed=seed)
315
+
316
+ components = [
317
+ evaluator,
318
+ generator,
319
+ crossover,
320
+ mutation,
321
+ selector,
322
+ terminator,
323
+ scalar_selector,
324
+ ]
325
+ [publisher.auto_subscribe(x) for x in components]
326
+ [publisher.register_topics(x.provided_topics[x.verbosity], x.__class__.__name__) for x in components]
327
+ return (
328
+ partial(
329
+ template2,
330
+ evaluator=evaluator,
331
+ crossover=crossover,
332
+ mutation=mutation,
333
+ generator=generator,
334
+ selection=selector,
335
+ terminator=terminator,
336
+ mate_selection=scalar_selector,
337
+ ),
338
+ publisher,
339
+ )
340
+
341
+
342
+ def nsga3_mixed_integer(
343
+ *,
344
+ problem: Problem,
345
+ seed: int = 0,
346
+ n_generations: int = 100,
347
+ max_evaluations: int | None = None,
348
+ reference_vector_options: ReferenceVectorOptions = None,
349
+ forced_verbosity: int | None = None,
350
+ ) -> tuple[Callable[[], EMOResult], Publisher]:
351
+ """Implements the NSGA-III algorithm as well as its interactive version for mixed-integer problems.
352
+
353
+ References:
354
+ K. Deb and H. Jain, “An Evolutionary Many-Objective Optimization Algorithm Using Reference-Point-Based
355
+ Nondominated Sorting Approach, Part I: Solving Problems With Box Constraints,” IEEE Transactions on Evolutionary
356
+ Computation, vol. 18, no. 4, pp. 577-601, Aug. 2014.
357
+
358
+ J. Hakanen, T. Chugh, K. Sindhya, Y. Jin, and K. Miettinen, “Connections of reference vectors and different
359
+ types of preference information in interactive multiobjective evolutionary algorithms,” in 2016 IEEE Symposium
360
+ Series on Computational Intelligence (SSCI), Athens, Greece: IEEE, Dec. 2016, pp. 1-8.
361
+
362
+ Args:
363
+ problem (Problem): The problem to be solved.
364
+ seed (int, optional): The seed for the random number generator. Defaults to 0.
365
+ n_generations (int, optional): The number of generations to run the algorithm. Defaults to 100.
366
+ max_evaluations (int, optional): The maximum number of evaluations to run the algorithm. If None, the algorithm
367
+ will run for n_generations. Defaults to None. If both n_generations and max_evaluations are provided, the
368
+ algorithm will run until max_evaluations is reached.
369
+ reference_vector_options (ReferenceVectorOptions, optional): The options for the reference vectors. Defaults to
370
+ None. See the ReferenceVectorOptions class for the defaults. This option can be used to run an interactive
371
+ version of the algorithm, using preferences provided by the user.
372
+ forced_verbosity (int, optional): If not None, the verbosity of the algorithm is forced to this value. Defaults
373
+ to None.
374
+
375
+ Returns:
376
+ tuple[Callable[[], EMOResult], Publisher]: A tuple containing the function to run the algorithm and the
377
+ publisher object. The publisher object can be used to subscribe to the topics of the algorithm components,
378
+ as well as to inject additional functionality such as archiving the results.
379
+ """
380
+ publisher = Publisher()
381
+ evaluator = EMOEvaluator(
382
+ problem=problem,
383
+ publisher=publisher,
384
+ verbosity=forced_verbosity if forced_verbosity is not None else 2,
385
+ )
386
+
387
+ selector = NSGA3Selector(
388
+ problem=problem,
389
+ publisher=publisher,
390
+ verbosity=forced_verbosity if forced_verbosity is not None else 2,
391
+ reference_vector_options=reference_vector_options,
392
+ )
393
+
394
+ # Note that the initial population size is equal to the number of reference vectors
395
+ n_points = selector.reference_vectors.shape[0]
396
+
397
+ generator = RandomMixedIntegerGenerator(
398
+ problem=problem,
399
+ evaluator=evaluator,
400
+ publisher=publisher,
401
+ n_points=n_points,
402
+ seed=seed,
403
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
404
+ )
405
+ crossover = UniformMixedIntegerCrossover(
406
+ problem=problem,
407
+ publisher=publisher,
408
+ seed=seed,
409
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
410
+ )
411
+ mutation = MixedIntegerRandomMutation(
412
+ problem=problem,
413
+ publisher=publisher,
414
+ seed=seed,
415
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
416
+ )
417
+
418
+ if max_evaluations is not None:
419
+ terminator = MaxEvaluationsTerminator(max_evaluations, publisher=publisher)
420
+ else:
421
+ terminator = MaxGenerationsTerminator(
422
+ n_generations,
423
+ publisher=publisher,
424
+ )
425
+
426
+ components = [evaluator, generator, crossover, mutation, selector, terminator]
427
+ [publisher.auto_subscribe(x) for x in components]
428
+ [publisher.register_topics(x.provided_topics[x.verbosity], x.__class__.__name__) for x in components]
429
+
430
+ return (
431
+ partial(
432
+ template1,
433
+ evaluator=evaluator,
434
+ crossover=crossover,
435
+ mutation=mutation,
436
+ generator=generator,
437
+ selection=selector,
438
+ terminator=terminator,
439
+ ),
440
+ publisher,
441
+ )
442
+
443
+
444
+ def rvea_mixed_integer(
445
+ *,
446
+ problem: Problem,
447
+ seed: int = 0,
448
+ n_generations=100,
449
+ max_evaluations: int | None = None,
450
+ reference_vector_options: ReferenceVectorOptions = None,
451
+ forced_verbosity: int | None = None,
452
+ ) -> tuple[Callable[[], EMOResult], Publisher]:
453
+ """Implements the mixed-integer variant of RVEA, as well as its interactive version.
454
+
455
+ References:
456
+ R. Cheng, Y. Jin, M. Olhofer and B. Sendhoff, "A Reference Vector Guided Evolutionary Algorithm for Many-
457
+ Objective Optimization," in IEEE Transactions on Evolutionary Computation, vol. 20, no. 5, pp. 773-791,
458
+ Oct. 2016, doi: 10.1109/TEVC.2016.2519378.
459
+
460
+ J. Hakanen, T. Chugh, K. Sindhya, Y. Jin, and K. Miettinen, “Connections of reference vectors and different
461
+ types of preference information in interactive multiobjective evolutionary algorithms,” in 2016 IEEE Symposium
462
+ Series on Computational Intelligence (SSCI), Athens, Greece: IEEE, Dec. 2016, pp. 1-8.
463
+
464
+
465
+ Args:
466
+ problem (Problem): The problem to be solved.
467
+ seed (int, optional): The seed for the random number generator. Defaults to 0.
468
+ n_generations (int, optional): The number of generations to run the algorithm. Defaults to 100.
469
+ max_evaluations (int, optional): The maximum number of evaluations to run the algorithm. If None, the algorithm
470
+ will run for n_generations. Defaults to None. If both n_generations and max_evaluations are provided, the
471
+ algorithm will run until max_evaluations is reached.
472
+ reference_vector_options (ReferenceVectorOptions, optional): The options for the reference vectors. Defaults to
473
+ None. See the ReferenceVectorOptions class for the defaults. This option can be used to run an interactive
474
+ version of the algorithm, using preferences provided by the user.
475
+ forced_verbosity (int, optional): If not None, the verbosity of the algorithm is forced to this value. Defaults
476
+ to None.
477
+
478
+ Returns:
479
+ tuple[Callable[[], EMOResult], Publisher]: A tuple containing the function to run the algorithm and the
480
+ publisher object. The publisher object can be used to subscribe to the topics of the algorithm components,
481
+ as well as to inject additional functionality such as archiving the results.
482
+ """
483
+ publisher = Publisher()
484
+ evaluator = EMOEvaluator(
485
+ problem=problem,
486
+ publisher=publisher,
487
+ verbosity=forced_verbosity if forced_verbosity is not None else 2,
488
+ )
489
+
490
+ selector = RVEASelector(
491
+ problem=problem,
492
+ publisher=publisher,
493
+ reference_vector_options=reference_vector_options,
494
+ verbosity=forced_verbosity if forced_verbosity is not None else 2,
495
+ )
496
+
497
+ # Note that the initial population size is equal to the number of reference vectors
498
+ n_points = selector.reference_vectors.shape[0]
499
+
500
+ generator = RandomMixedIntegerGenerator(
501
+ problem=problem,
502
+ evaluator=evaluator,
503
+ publisher=publisher,
504
+ n_points=n_points,
505
+ seed=seed,
506
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
507
+ )
508
+ crossover = UniformMixedIntegerCrossover(
509
+ problem=problem,
510
+ publisher=publisher,
511
+ seed=seed,
512
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
513
+ )
514
+ mutation = MixedIntegerRandomMutation(
515
+ problem=problem,
516
+ publisher=publisher,
517
+ seed=seed,
518
+ verbosity=forced_verbosity if forced_verbosity is not None else 1,
519
+ )
520
+
521
+ if max_evaluations is not None:
522
+ terminator = MaxEvaluationsTerminator(max_evaluations, publisher=publisher)
523
+ else:
524
+ terminator = MaxGenerationsTerminator(n_generations, publisher=publisher)
525
+
526
+ components = [evaluator, generator, crossover, mutation, selector, terminator]
527
+ [publisher.auto_subscribe(x) for x in components]
528
+ [publisher.register_topics(x.provided_topics[x.verbosity], x.__class__.__name__) for x in components]
529
+
530
+ return (
531
+ partial(
532
+ template1,
533
+ evaluator=evaluator,
534
+ crossover=crossover,
535
+ mutation=mutation,
536
+ generator=generator,
537
+ selection=selector,
538
+ terminator=terminator,
539
+ ),
540
+ publisher,
541
+ )
File without changes
@@ -0,0 +1,12 @@
1
+ """Deprecated module."""
2
+
3
+ import warnings
4
+
5
+ from desdeo.emo.methods.templates import EMOResult, template1, template2
6
+
7
+ warnings.warn(
8
+ "The EMO methods in this module are deprecated and will be removed in a future release. "
9
+ "Please use the methods in desdeo.emo.methods.templates instead.",
10
+ DeprecationWarning,
11
+ stacklevel=2,
12
+ )
@@ -0,0 +1,111 @@
1
+ """This module contains the basic functional implementations for the EMO methods.
2
+
3
+ This can be used as a template for the implementation of the EMO methods.
4
+ """
5
+
6
+ from collections.abc import Callable
7
+
8
+ import polars as pl
9
+ from pydantic import BaseModel, ConfigDict, Field
10
+
11
+ from desdeo.emo.operators.crossover import BaseCrossover
12
+ from desdeo.emo.operators.evaluator import EMOEvaluator
13
+ from desdeo.emo.operators.generator import BaseGenerator
14
+ from desdeo.emo.operators.mutation import BaseMutation
15
+ from desdeo.emo.operators.scalar_selection import BaseScalarSelector
16
+ from desdeo.emo.operators.selection import BaseSelector
17
+ from desdeo.emo.operators.termination import BaseTerminator
18
+ from desdeo.tools.generics import EMOResult
19
+
20
+
21
+ def template1(
22
+ evaluator: EMOEvaluator,
23
+ crossover: BaseCrossover,
24
+ mutation: BaseMutation,
25
+ generator: BaseGenerator,
26
+ selection: BaseSelector,
27
+ terminator: BaseTerminator,
28
+ repair: Callable[[pl.DataFrame], pl.DataFrame] = lambda x: x, # Default to identity function if no repair is needed
29
+ ) -> EMOResult:
30
+ """Implements a template that many EMO methods, such as RVEA and NSGA-III, follow.
31
+
32
+ Args:
33
+ evaluator (EMOEvaluator): A class that evaluates the solutions and provides the objective vectors, constraint
34
+ vectors, and targets.
35
+ crossover (BaseCrossover): The crossover operator.
36
+ mutation (BaseMutation): The mutation operator.
37
+ generator (BaseGenerator): A class that generates the initial population.
38
+ selection (BaseSelector): The selection operator.
39
+ terminator (BaseTerminator): The termination operator.
40
+ repair (Callable, optional): A function that repairs the offspring if they go out of bounds. Defaults to an
41
+ identity function, meaning no repair is done. See :py:func:`desdeo.tools.utils.repair` as an example of a
42
+ repair function.
43
+
44
+ Returns:
45
+ EMOResult: The final population and their objective vectors, constraint vectors, and targets
46
+ """
47
+ solutions, outputs = generator.do()
48
+
49
+ while not terminator.check():
50
+ offspring = crossover.do(population=solutions)
51
+ offspring = mutation.do(offspring, solutions)
52
+ # Repair offspring if they go out of bounds
53
+ offspring = repair(offspring)
54
+ offspring_outputs = evaluator.evaluate(offspring)
55
+ solutions, outputs = selection.do(parents=(solutions, outputs), offsprings=(offspring, offspring_outputs))
56
+
57
+ return EMOResult(optimal_variables=solutions, optimal_outputs=outputs)
58
+
59
+
60
+ def template2(
61
+ evaluator: EMOEvaluator,
62
+ crossover: BaseCrossover,
63
+ mutation: BaseMutation,
64
+ generator: BaseGenerator,
65
+ selection: BaseSelector,
66
+ mate_selection: BaseScalarSelector,
67
+ terminator: BaseTerminator,
68
+ repair: Callable[[pl.DataFrame], pl.DataFrame] = lambda x: x, # Default to identity function if no repair is needed
69
+ ) -> EMOResult:
70
+ """Implements a template that many EMO methods, such as IBEA, follow.
71
+
72
+ Args:
73
+ evaluator (EMOEvaluator): A class that evaluates the solutions and provides the objective vectors, constraint
74
+ vectors, and targets.
75
+ crossover (BaseCrossover): The crossover operator.
76
+ mutation (BaseMutation): The mutation operator.
77
+ generator (BaseGenerator): A class that generates the initial population.
78
+ selection (BaseSelector): The selection operator.
79
+ mate_selection (BaseScalarSelector): The mating selection operator, which selects parents for mating.
80
+ This is typically a scalar selector that selects parents based on their fitness.
81
+ terminator (BaseTerminator): The termination operator.
82
+ repair (Callable, optional): A function that repairs the offspring if they go out of bounds. Defaults to an
83
+ identity function, meaning no repair is done. See :py:func:`desdeo.tools.utils.repair` as an example of a
84
+ repair function.
85
+
86
+ Returns:
87
+ EMOResult: The final population and their objective vectors, constraint vectors, and targets
88
+ """
89
+ solutions, outputs = generator.do()
90
+ # This is just a hack to make all selection operators work (they require offsprings to be passed separately rn)
91
+ offspring = pl.DataFrame(
92
+ schema=solutions.schema,
93
+ )
94
+ offspring_outputs = pl.DataFrame(
95
+ schema=outputs.schema,
96
+ )
97
+
98
+ while True:
99
+ solutions, outputs = selection.do(parents=(solutions, outputs), offsprings=(offspring, offspring_outputs))
100
+ if terminator.check():
101
+ # Weird way to do looping, but IBEA does environmental selection before the loop check, and...
102
+ # does mating afterwards.
103
+ break
104
+ parents, _ = mate_selection.do((solutions, outputs))
105
+ offspring = crossover.do(population=parents)
106
+ offspring = mutation.do(offspring, solutions)
107
+ # Repair offspring if they go out of bounds
108
+ offspring = repair(offspring)
109
+ offspring_outputs = evaluator.evaluate(offspring)
110
+
111
+ return EMOResult(optimal_variables=solutions, optimal_outputs=outputs)
@@ -0,0 +1 @@
1
+