desdeo 2.0.0__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 (126) hide show
  1. desdeo/adm/ADMAfsar.py +551 -0
  2. desdeo/adm/ADMChen.py +414 -0
  3. desdeo/adm/BaseADM.py +119 -0
  4. desdeo/adm/__init__.py +11 -0
  5. desdeo/api/__init__.py +6 -6
  6. desdeo/api/app.py +38 -28
  7. desdeo/api/config.py +65 -44
  8. desdeo/api/config.toml +23 -12
  9. desdeo/api/db.py +10 -8
  10. desdeo/api/db_init.py +12 -6
  11. desdeo/api/models/__init__.py +220 -20
  12. desdeo/api/models/archive.py +16 -27
  13. desdeo/api/models/emo.py +128 -0
  14. desdeo/api/models/enautilus.py +69 -0
  15. desdeo/api/models/gdm/gdm_aggregate.py +139 -0
  16. desdeo/api/models/gdm/gdm_base.py +69 -0
  17. desdeo/api/models/gdm/gdm_score_bands.py +114 -0
  18. desdeo/api/models/gdm/gnimbus.py +138 -0
  19. desdeo/api/models/generic.py +104 -0
  20. desdeo/api/models/generic_states.py +401 -0
  21. desdeo/api/models/nimbus.py +158 -0
  22. desdeo/api/models/preference.py +44 -6
  23. desdeo/api/models/problem.py +274 -64
  24. desdeo/api/models/session.py +4 -1
  25. desdeo/api/models/state.py +419 -52
  26. desdeo/api/models/user.py +7 -6
  27. desdeo/api/models/utopia.py +25 -0
  28. desdeo/api/routers/_EMO.backup +309 -0
  29. desdeo/api/routers/_NIMBUS.py +6 -3
  30. desdeo/api/routers/emo.py +497 -0
  31. desdeo/api/routers/enautilus.py +237 -0
  32. desdeo/api/routers/gdm/gdm_aggregate.py +234 -0
  33. desdeo/api/routers/gdm/gdm_base.py +420 -0
  34. desdeo/api/routers/gdm/gdm_score_bands/gdm_score_bands_manager.py +398 -0
  35. desdeo/api/routers/gdm/gdm_score_bands/gdm_score_bands_routers.py +377 -0
  36. desdeo/api/routers/gdm/gnimbus/gnimbus_manager.py +698 -0
  37. desdeo/api/routers/gdm/gnimbus/gnimbus_routers.py +591 -0
  38. desdeo/api/routers/generic.py +233 -0
  39. desdeo/api/routers/nimbus.py +705 -0
  40. desdeo/api/routers/problem.py +201 -4
  41. desdeo/api/routers/reference_point_method.py +20 -44
  42. desdeo/api/routers/session.py +50 -26
  43. desdeo/api/routers/user_authentication.py +180 -26
  44. desdeo/api/routers/utils.py +187 -0
  45. desdeo/api/routers/utopia.py +230 -0
  46. desdeo/api/schema.py +10 -4
  47. desdeo/api/tests/conftest.py +94 -2
  48. desdeo/api/tests/test_enautilus.py +330 -0
  49. desdeo/api/tests/test_models.py +550 -72
  50. desdeo/api/tests/test_routes.py +902 -43
  51. desdeo/api/utils/_database.py +263 -0
  52. desdeo/api/utils/database.py +28 -266
  53. desdeo/api/utils/emo_database.py +40 -0
  54. desdeo/core.py +7 -0
  55. desdeo/emo/__init__.py +154 -24
  56. desdeo/emo/hooks/archivers.py +18 -2
  57. desdeo/emo/methods/EAs.py +128 -5
  58. desdeo/emo/methods/bases.py +9 -56
  59. desdeo/emo/methods/templates.py +111 -0
  60. desdeo/emo/operators/crossover.py +544 -42
  61. desdeo/emo/operators/evaluator.py +10 -14
  62. desdeo/emo/operators/generator.py +127 -24
  63. desdeo/emo/operators/mutation.py +212 -41
  64. desdeo/emo/operators/scalar_selection.py +202 -0
  65. desdeo/emo/operators/selection.py +956 -214
  66. desdeo/emo/operators/termination.py +124 -16
  67. desdeo/emo/options/__init__.py +108 -0
  68. desdeo/emo/options/algorithms.py +435 -0
  69. desdeo/emo/options/crossover.py +164 -0
  70. desdeo/emo/options/generator.py +131 -0
  71. desdeo/emo/options/mutation.py +260 -0
  72. desdeo/emo/options/repair.py +61 -0
  73. desdeo/emo/options/scalar_selection.py +66 -0
  74. desdeo/emo/options/selection.py +127 -0
  75. desdeo/emo/options/templates.py +383 -0
  76. desdeo/emo/options/termination.py +143 -0
  77. desdeo/gdm/__init__.py +22 -0
  78. desdeo/gdm/gdmtools.py +45 -0
  79. desdeo/gdm/score_bands.py +114 -0
  80. desdeo/gdm/voting_rules.py +50 -0
  81. desdeo/mcdm/__init__.py +23 -1
  82. desdeo/mcdm/enautilus.py +338 -0
  83. desdeo/mcdm/gnimbus.py +484 -0
  84. desdeo/mcdm/nautilus_navigator.py +7 -6
  85. desdeo/mcdm/reference_point_method.py +70 -0
  86. desdeo/problem/__init__.py +5 -1
  87. desdeo/problem/external/__init__.py +18 -0
  88. desdeo/problem/external/core.py +356 -0
  89. desdeo/problem/external/pymoo_provider.py +266 -0
  90. desdeo/problem/external/runtime.py +44 -0
  91. desdeo/problem/infix_parser.py +2 -2
  92. desdeo/problem/pyomo_evaluator.py +25 -6
  93. desdeo/problem/schema.py +69 -48
  94. desdeo/problem/simulator_evaluator.py +65 -15
  95. desdeo/problem/testproblems/__init__.py +26 -11
  96. desdeo/problem/testproblems/benchmarks_server.py +120 -0
  97. desdeo/problem/testproblems/cake_problem.py +185 -0
  98. desdeo/problem/testproblems/dmitry_forest_problem_discrete.py +71 -0
  99. desdeo/problem/testproblems/forest_problem.py +77 -69
  100. desdeo/problem/testproblems/multi_valued_constraints.py +119 -0
  101. desdeo/problem/testproblems/{river_pollution_problem.py → river_pollution_problems.py} +28 -22
  102. desdeo/problem/testproblems/single_objective.py +289 -0
  103. desdeo/problem/testproblems/zdt_problem.py +4 -1
  104. desdeo/tools/__init__.py +39 -21
  105. desdeo/tools/desc_gen.py +22 -0
  106. desdeo/tools/generics.py +22 -2
  107. desdeo/tools/group_scalarization.py +3090 -0
  108. desdeo/tools/indicators_binary.py +107 -1
  109. desdeo/tools/indicators_unary.py +3 -16
  110. desdeo/tools/message.py +33 -2
  111. desdeo/tools/non_dominated_sorting.py +4 -3
  112. desdeo/tools/patterns.py +9 -7
  113. desdeo/tools/pyomo_solver_interfaces.py +48 -35
  114. desdeo/tools/reference_vectors.py +118 -351
  115. desdeo/tools/scalarization.py +340 -1413
  116. desdeo/tools/score_bands.py +491 -328
  117. desdeo/tools/utils.py +117 -49
  118. desdeo/tools/visualizations.py +67 -0
  119. desdeo/utopia_stuff/utopia_problem.py +1 -1
  120. desdeo/utopia_stuff/utopia_problem_old.py +1 -1
  121. {desdeo-2.0.0.dist-info → desdeo-2.1.0.dist-info}/METADATA +46 -28
  122. desdeo-2.1.0.dist-info/RECORD +180 -0
  123. {desdeo-2.0.0.dist-info → desdeo-2.1.0.dist-info}/WHEEL +1 -1
  124. desdeo-2.0.0.dist-info/RECORD +0 -120
  125. /desdeo/api/utils/{logger.py → _logger.py} +0 -0
  126. {desdeo-2.0.0.dist-info → desdeo-2.1.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,435 @@
1
+ """Define popular MOEAs as Pydantic models."""
2
+
3
+ from collections.abc import Callable
4
+ from functools import partial
5
+
6
+ from desdeo.emo.options.crossover import SimulatedBinaryCrossoverOptions, UniformMixedIntegerCrossoverOptions
7
+ from desdeo.emo.options.generator import LHSGeneratorOptions, RandomMixedIntegerGeneratorOptions
8
+ from desdeo.emo.options.mutation import BoundedPolynomialMutationOptions, MixedIntegerRandomMutationOptions
9
+ from desdeo.emo.options.repair import NoRepairOptions
10
+ from desdeo.emo.options.scalar_selection import TournamentSelectionOptions
11
+ from desdeo.emo.options.selection import (
12
+ IBEASelectorOptions,
13
+ NSGA2SelectorOptions,
14
+ NSGA3SelectorOptions,
15
+ ParameterAdaptationStrategy,
16
+ ReferenceVectorOptions,
17
+ RVEASelectorOptions,
18
+ )
19
+ from desdeo.emo.options.templates import (
20
+ ConstructorExtras,
21
+ EMOOptions,
22
+ EMOResult,
23
+ Template1Options,
24
+ Template2Options,
25
+ emo_constructor,
26
+ )
27
+ from desdeo.emo.options.termination import MaxGenerationsTerminatorOptions
28
+ from desdeo.problem import Problem
29
+
30
+
31
+ def rvea_options() -> EMOOptions:
32
+ """Get default Reference Vector Guided Evolutionary Algorithm (RVEA) options as a Pydantic model.
33
+
34
+ References:
35
+ R. Cheng, Y. Jin, M. Olhofer and B. Sendhoff, "A Reference Vector Guided Evolutionary Algorithm for Many-
36
+ Objective Optimization," in IEEE Transactions on Evolutionary Computation, vol. 20, no. 5, pp. 773-791,
37
+ Oct. 2016, doi: 10.1109/TEVC.2016.2519378.
38
+
39
+ J. Hakanen, T. Chugh, K. Sindhya, Y. Jin, and K. Miettinen, “Connections of reference vectors and different
40
+ types of preference information in interactive multiobjective evolutionary algorithms,” in 2016 IEEE Symposium
41
+ Series on Computational Intelligence (SSCI), Athens, Greece: IEEE, Dec. 2016, pp. 1-8.
42
+
43
+ Returns:
44
+ EMOOptions: The default RVEA options as a Pydantic model.
45
+ """
46
+ return EMOOptions(
47
+ preference=None,
48
+ template=Template1Options(
49
+ algorithm_name="RVEA",
50
+ crossover=SimulatedBinaryCrossoverOptions(
51
+ name="SimulatedBinaryCrossover",
52
+ xover_distribution=30,
53
+ xover_probability=0.5,
54
+ ),
55
+ mutation=BoundedPolynomialMutationOptions(
56
+ name="BoundedPolynomialMutation",
57
+ distribution_index=20,
58
+ mutation_probability=None,
59
+ ),
60
+ selection=RVEASelectorOptions(
61
+ name="RVEASelector",
62
+ alpha=2,
63
+ parameter_adaptation_strategy=ParameterAdaptationStrategy.GENERATION_BASED,
64
+ reference_vector_options=ReferenceVectorOptions(
65
+ adaptation_frequency=100,
66
+ creation_type="simplex",
67
+ vector_type="spherical",
68
+ lattice_resolution=None,
69
+ number_of_vectors=100,
70
+ adaptation_distance=0.2,
71
+ reference_point=None,
72
+ preferred_solutions=None,
73
+ non_preferred_solutions=None,
74
+ preferred_ranges=None,
75
+ ),
76
+ ),
77
+ generator=LHSGeneratorOptions(
78
+ name="LHSGenerator",
79
+ n_points=100,
80
+ ),
81
+ repair=NoRepairOptions(
82
+ name="NoRepair",
83
+ ),
84
+ termination=MaxGenerationsTerminatorOptions(
85
+ name="MaxGenerationsTerminator",
86
+ max_generations=100,
87
+ ),
88
+ use_archive=True,
89
+ verbosity=2,
90
+ seed=42,
91
+ ),
92
+ )
93
+
94
+
95
+ def nsga3_options() -> EMOOptions:
96
+ """Get default NSGA-III options as a Pydantic model.
97
+
98
+ References:
99
+ K. Deb and H. Jain, “An Evolutionary Many-Objective Optimization Algorithm Using Reference-Point-Based
100
+ Nondominated Sorting Approach, Part I: Solving Problems With Box Constraints,” IEEE Transactions on Evolutionary
101
+ Computation, vol. 18, no. 4, pp. 577-601, Aug. 2014.
102
+
103
+ J. Hakanen, T. Chugh, K. Sindhya, Y. Jin, and K. Miettinen, “Connections of reference vectors and different
104
+ types of preference information in interactive multiobjective evolutionary algorithms,” in 2016 IEEE Symposium
105
+ Series on Computational Intelligence (SSCI), Athens, Greece: IEEE, Dec. 2016, pp. 1-8.
106
+
107
+ Returns:
108
+ EMOOptions: The default NSGA-III options as a Pydantic model.
109
+ """
110
+ return EMOOptions(
111
+ preference=None,
112
+ template=Template1Options(
113
+ algorithm_name="NSGA3",
114
+ crossover=SimulatedBinaryCrossoverOptions(
115
+ name="SimulatedBinaryCrossover",
116
+ xover_distribution=30,
117
+ xover_probability=0.5,
118
+ ),
119
+ mutation=BoundedPolynomialMutationOptions(
120
+ name="BoundedPolynomialMutation",
121
+ distribution_index=20,
122
+ mutation_probability=None,
123
+ ),
124
+ selection=NSGA3SelectorOptions(
125
+ name="NSGA3Selector",
126
+ reference_vector_options=ReferenceVectorOptions(
127
+ adaptation_frequency=0,
128
+ creation_type="simplex",
129
+ vector_type="planar",
130
+ lattice_resolution=None,
131
+ number_of_vectors=100,
132
+ adaptation_distance=0.2,
133
+ reference_point=None,
134
+ preferred_solutions=None,
135
+ non_preferred_solutions=None,
136
+ preferred_ranges=None,
137
+ ),
138
+ ),
139
+ generator=LHSGeneratorOptions(
140
+ name="LHSGenerator",
141
+ n_points=100,
142
+ ),
143
+ repair=NoRepairOptions(
144
+ name="NoRepair",
145
+ ),
146
+ termination=MaxGenerationsTerminatorOptions(
147
+ name="MaxGenerationsTerminator",
148
+ max_generations=100,
149
+ ),
150
+ use_archive=True,
151
+ verbosity=2,
152
+ seed=42,
153
+ ),
154
+ )
155
+
156
+
157
+ def ibea_options() -> EMOOptions:
158
+ """Get default IBEA options as a Pydantic model.
159
+
160
+ References:
161
+ Zitzler, E., Künzli, S. (2004). Indicator-Based Selection in Multiobjective Search. In: Yao, X., et al.
162
+ Parallel Problem Solving from Nature - PPSN VIII. PPSN 2004. Lecture Notes in Computer Science, vol 3242.
163
+ Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-30217-9_84
164
+
165
+ Returns:
166
+ EMOOptions: The default IBEA options as a Pydantic model.
167
+ """
168
+ return EMOOptions(
169
+ preference=None,
170
+ template=Template2Options(
171
+ algorithm_name="IBEA",
172
+ crossover=SimulatedBinaryCrossoverOptions(
173
+ name="SimulatedBinaryCrossover",
174
+ xover_distribution=20, # Note that the operator defaults are different in Template2
175
+ xover_probability=0.5,
176
+ ),
177
+ mutation=BoundedPolynomialMutationOptions(
178
+ name="BoundedPolynomialMutation",
179
+ distribution_index=20,
180
+ mutation_probability=0.01,
181
+ ),
182
+ selection=IBEASelectorOptions(
183
+ name="IBEASelector",
184
+ binary_indicator="eps",
185
+ kappa=0.05,
186
+ population_size=100,
187
+ ),
188
+ mate_selection=TournamentSelectionOptions(
189
+ name="TournamentSelection",
190
+ tournament_size=2,
191
+ winner_size=100,
192
+ ),
193
+ generator=LHSGeneratorOptions(
194
+ name="LHSGenerator",
195
+ n_points=100,
196
+ ),
197
+ repair=NoRepairOptions(
198
+ name="NoRepair",
199
+ ),
200
+ termination=MaxGenerationsTerminatorOptions(
201
+ name="MaxGenerationsTerminator",
202
+ max_generations=100,
203
+ ),
204
+ use_archive=True,
205
+ verbosity=2,
206
+ seed=42,
207
+ ),
208
+ )
209
+
210
+
211
+ def nsga2_options() -> EMOOptions:
212
+ """Get default NSGA-II options as a Pydantic model.
213
+
214
+ Reference: Deb, K., Pratap, A., Agarwal, S., & Meyarivan, T. A. M. T.
215
+ (2002). A fast and elitist multiobjective genetic algorithm: NSGA-II. IEEE
216
+ transactions on evolutionary computation, 6(2), 182-197.
217
+
218
+ Returns:
219
+ EMOOptions: The default NSGA-II options as a Pydantic model.
220
+ """
221
+ return EMOOptions(
222
+ preference=None,
223
+ template=Template2Options(
224
+ algorithm_name="NSGA-II",
225
+ crossover=SimulatedBinaryCrossoverOptions(
226
+ name="SimulatedBinaryCrossover",
227
+ xover_distribution=20, # Note that the operator defaults are different in Template2
228
+ xover_probability=0.9,
229
+ ),
230
+ mutation=BoundedPolynomialMutationOptions(
231
+ name="BoundedPolynomialMutation",
232
+ distribution_index=20,
233
+ mutation_probability=0.01,
234
+ ),
235
+ selection=NSGA2SelectorOptions(
236
+ name="NSGA2Selector",
237
+ population_size=100,
238
+ ),
239
+ mate_selection=TournamentSelectionOptions(
240
+ name="TournamentSelection",
241
+ tournament_size=2,
242
+ winner_size=100,
243
+ ),
244
+ generator=LHSGeneratorOptions(
245
+ name="LHSGenerator",
246
+ n_points=100,
247
+ ),
248
+ repair=NoRepairOptions(
249
+ name="NoRepair",
250
+ ),
251
+ termination=MaxGenerationsTerminatorOptions(
252
+ name="MaxGenerationsTerminator",
253
+ max_generations=100,
254
+ ),
255
+ use_archive=True,
256
+ verbosity=2,
257
+ seed=42,
258
+ ),
259
+ )
260
+
261
+
262
+ def rvea_mixed_integer_options() -> EMOOptions:
263
+ """Get default RVEA options for mixed integer problems as a Pydantic model.
264
+
265
+ References:
266
+ R. Cheng, Y. Jin, M. Olhofer and B. Sendhoff, "A Reference Vector Guided Evolutionary Algorithm for Many-
267
+ Objective Optimization," in IEEE Transactions on Evolutionary Computation, vol. 20, no. 5, pp. 773-791,
268
+ Oct. 2016, doi: 10.1109/TEVC.2016.2519378.
269
+
270
+ J. Hakanen, T. Chugh, K. Sindhya, Y. Jin, and K. Miettinen, “Connections of reference vectors and different
271
+ types of preference information in interactive multiobjective evolutionary algorithms,” in 2016 IEEE Symposium
272
+ Series on Computational Intelligence (SSCI), Athens, Greece: IEEE, Dec. 2016, pp. 1-8.
273
+
274
+ Returns:
275
+ EMOOptions: The default RVEA mixed integer options as a Pydantic model
276
+ """
277
+ return EMOOptions(
278
+ preference=None,
279
+ template=Template1Options(
280
+ algorithm_name="RVEA_Mixed_Integer",
281
+ crossover=UniformMixedIntegerCrossoverOptions(),
282
+ mutation=MixedIntegerRandomMutationOptions(),
283
+ selection=RVEASelectorOptions(
284
+ name="RVEASelector",
285
+ alpha=2,
286
+ parameter_adaptation_strategy=ParameterAdaptationStrategy.GENERATION_BASED,
287
+ reference_vector_options=ReferenceVectorOptions(
288
+ adaptation_frequency=100,
289
+ creation_type="simplex",
290
+ vector_type="spherical",
291
+ lattice_resolution=None,
292
+ number_of_vectors=100,
293
+ adaptation_distance=0.2,
294
+ reference_point=None,
295
+ preferred_solutions=None,
296
+ non_preferred_solutions=None,
297
+ preferred_ranges=None,
298
+ ),
299
+ ),
300
+ generator=RandomMixedIntegerGeneratorOptions(n_points=100),
301
+ repair=NoRepairOptions(
302
+ name="NoRepair",
303
+ ),
304
+ termination=MaxGenerationsTerminatorOptions(
305
+ name="MaxGenerationsTerminator",
306
+ max_generations=100,
307
+ ),
308
+ use_archive=True,
309
+ verbosity=2,
310
+ seed=42,
311
+ ),
312
+ )
313
+
314
+
315
+ def nsga3_mixed_integer_options() -> EMOOptions:
316
+ """Get default NSGA3 options for mixed integer problems as a Pydantic model.
317
+
318
+ References:
319
+ K. Deb and H. Jain, “An Evolutionary Many-Objective Optimization Algorithm Using Reference-Point-Based
320
+ Nondominated Sorting Approach, Part I: Solving Problems With Box Constraints,” IEEE Transactions on Evolutionary
321
+ Computation, vol. 18, no. 4, pp. 577-601, Aug. 2014.
322
+
323
+ J. Hakanen, T. Chugh, K. Sindhya, Y. Jin, and K. Miettinen, “Connections of reference vectors and different
324
+ types of preference information in interactive multiobjective evolutionary algorithms,” in 2016 IEEE Symposium
325
+ Series on Computational Intelligence (SSCI), Athens, Greece: IEEE, Dec. 2016, pp. 1-8.
326
+
327
+ Returns:
328
+ EMOOptions: The default NSGA3 mixed integer options as a Pydantic model
329
+ """
330
+ return EMOOptions(
331
+ preference=None,
332
+ template=Template1Options(
333
+ algorithm_name="NSGA3_Mixed_Integer",
334
+ crossover=UniformMixedIntegerCrossoverOptions(),
335
+ mutation=MixedIntegerRandomMutationOptions(),
336
+ selection=NSGA3SelectorOptions(
337
+ name="NSGA3Selector",
338
+ reference_vector_options=ReferenceVectorOptions(
339
+ adaptation_frequency=0,
340
+ creation_type="simplex",
341
+ vector_type="planar",
342
+ lattice_resolution=None,
343
+ number_of_vectors=100,
344
+ adaptation_distance=0.2,
345
+ reference_point=None,
346
+ preferred_solutions=None,
347
+ non_preferred_solutions=None,
348
+ preferred_ranges=None,
349
+ ),
350
+ ),
351
+ generator=RandomMixedIntegerGeneratorOptions(n_points=100),
352
+ repair=NoRepairOptions(
353
+ name="NoRepair",
354
+ ),
355
+ termination=MaxGenerationsTerminatorOptions(
356
+ name="MaxGenerationsTerminator",
357
+ max_generations=100,
358
+ ),
359
+ use_archive=True,
360
+ verbosity=2,
361
+ seed=42,
362
+ ),
363
+ )
364
+
365
+
366
+ def ibea_mixed_integer_options() -> EMOOptions:
367
+ """Get default IBEA options for mixed integer problems as a Pydantic model.
368
+
369
+ References:
370
+ Zitzler, E., Künzli, S. (2004). Indicator-Based Selection in Multiobjective Search. In: Yao, X., et al.
371
+ Parallel Problem Solving from Nature - PPSN VIII. PPSN 2004. Lecture Notes in Computer Science, vol 3242.
372
+ Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-540-30217-9_84
373
+
374
+ Returns:
375
+ EMOOptions: The default IBEA mixed integer options as a Pydantic model
376
+ """
377
+ return EMOOptions(
378
+ preference=None,
379
+ template=Template2Options(
380
+ algorithm_name="IBEA_Mixed_Integer",
381
+ crossover=UniformMixedIntegerCrossoverOptions(),
382
+ mutation=MixedIntegerRandomMutationOptions(),
383
+ selection=IBEASelectorOptions(
384
+ name="IBEASelector",
385
+ binary_indicator="eps",
386
+ kappa=0.05,
387
+ population_size=100,
388
+ ),
389
+ mate_selection=TournamentSelectionOptions(
390
+ name="TournamentSelection",
391
+ tournament_size=2,
392
+ winner_size=100,
393
+ ),
394
+ generator=RandomMixedIntegerGeneratorOptions(n_points=100),
395
+ repair=NoRepairOptions(
396
+ name="NoRepair",
397
+ ),
398
+ termination=MaxGenerationsTerminatorOptions(
399
+ name="MaxGenerationsTerminator",
400
+ max_generations=100,
401
+ ),
402
+ use_archive=True,
403
+ verbosity=2,
404
+ seed=42,
405
+ ),
406
+ )
407
+
408
+
409
+ if __name__ == "__main__":
410
+ import json
411
+ from pathlib import Path
412
+
413
+ current_dir = Path(__file__)
414
+ json_dump_path = current_dir.parent.parent.parent.parent / "datasets" / "emoTemplates"
415
+
416
+ for algo_name, algo in zip(
417
+ ["rvea", "nsga3", "ibea", "rvea_mixed_integer", "nsga3_mixed_integer", "ibea_mixed_integer"],
418
+ [
419
+ rvea_options,
420
+ nsga3_options,
421
+ ibea_options,
422
+ rvea_mixed_integer_options,
423
+ nsga3_mixed_integer_options,
424
+ ibea_mixed_integer_options,
425
+ ],
426
+ strict=True,
427
+ ):
428
+ if not json_dump_path.exists():
429
+ json_dump_path.mkdir(parents=True, exist_ok=True)
430
+ with Path.open(json_dump_path / f"{algo_name}.json", "w") as f:
431
+ json.dump(algo().model_dump(), f, indent=4)
432
+
433
+ # Also dump the schema
434
+ with Path.open(json_dump_path / f"emoOptionsSchema.json", "w") as f:
435
+ json.dump(EMOOptions.model_json_schema(), f, indent=4)
@@ -0,0 +1,164 @@
1
+ """JSON Schema for crossover operator options."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Literal
6
+
7
+ from pydantic import BaseModel, Field
8
+
9
+ from desdeo.emo.operators.crossover import (
10
+ BaseCrossover,
11
+ BlendAlphaCrossover,
12
+ BoundedExponentialCrossover,
13
+ LocalCrossover,
14
+ SimulatedBinaryCrossover,
15
+ SingleArithmeticCrossover,
16
+ SinglePointBinaryCrossover,
17
+ UniformIntegerCrossover,
18
+ UniformMixedIntegerCrossover,
19
+ )
20
+
21
+ if TYPE_CHECKING:
22
+ from desdeo.problem import Problem
23
+ from desdeo.tools.patterns import Publisher
24
+
25
+
26
+ class SimulatedBinaryCrossoverOptions(BaseModel):
27
+ """Options for Simulated Binary Crossover (SBX)."""
28
+
29
+ name: Literal["SimulatedBinaryCrossover"] = Field(
30
+ default="SimulatedBinaryCrossover", frozen=True, description="The name of the crossover operator."
31
+ )
32
+ """The name of the crossover operator."""
33
+ xover_probability: float = Field(default=0.5, ge=0.0, le=1.0, description="The SBX crossover probability.")
34
+ """The SBX crossover probability."""
35
+ xover_distribution: float = Field(default=30.0, gt=0.0, description="The SBX distribution index.")
36
+ """The SBX distribution index."""
37
+
38
+
39
+ class SinglePointBinaryCrossoverOptions(BaseModel):
40
+ """Options for Single Point Binary Crossover."""
41
+
42
+ name: Literal["SinglePointBinaryCrossover"] = Field(
43
+ default="SinglePointBinaryCrossover", frozen=True, description="The name of the crossover operator."
44
+ )
45
+ """The name of the crossover operator."""
46
+
47
+
48
+ class UniformIntegerCrossoverOptions(BaseModel):
49
+ """Options for Uniform Integer Crossover."""
50
+
51
+ name: Literal["UniformIntegerCrossover"] = Field(
52
+ default="UniformIntegerCrossover", frozen=True, description="The name of the crossover operator."
53
+ )
54
+ """The name of the crossover operator."""
55
+
56
+
57
+ class UniformMixedIntegerCrossoverOptions(BaseModel):
58
+ """Options for Uniform Mixed Integer Crossover."""
59
+
60
+ name: Literal["UniformMixedIntegerCrossover"] = Field(
61
+ default="UniformMixedIntegerCrossover", frozen=True, description="The name of the crossover operator."
62
+ )
63
+ """The name of the crossover operator."""
64
+
65
+
66
+ class BlendAlphaCrossoverOptions(BaseModel):
67
+ """Options for Blend Alpha Crossover."""
68
+
69
+ name: Literal["BlendAlphaCrossover"] = Field(
70
+ default="BlendAlphaCrossover", frozen=True, description="The name of the crossover operator."
71
+ )
72
+ """The name of the crossover operator."""
73
+ alpha: float = Field(
74
+ default=0.5,
75
+ ge=0.0,
76
+ description=(
77
+ "Non-negative blending factor 'alpha' that controls the extent to which offspring"
78
+ " may be sampled outside the interval defined by each pair of parent genes. "
79
+ "alpha = 0 restricts children strictly within the parents range, larger alpha allows some outliers."
80
+ ),
81
+ )
82
+ """
83
+ Non-negative blending factor 'alpha' that controls the extent to which offspring
84
+ may be sampled outside the interval defined by each pair of parent genes.
85
+ alpha = 0 restricts children strictly within the parents range, larger alpha allows some outliers.
86
+ """
87
+ xover_probability: float = Field(default=1.0, ge=0.0, le=1.0)
88
+
89
+
90
+ class SingleArithmeticCrossoverOptions(BaseModel):
91
+ """Options for Single Arithmetic Crossover."""
92
+
93
+ name: Literal["SingleArithmeticCrossover"] = Field(
94
+ default="SingleArithmeticCrossover", frozen=True, description="The name of the crossover operator."
95
+ )
96
+ """The name of the crossover operator."""
97
+ xover_probability: float = Field(default=1.0, ge=0.0, le=1.0, description="The crossover probability.")
98
+ """The crossover probability."""
99
+
100
+
101
+ class LocalCrossoverOptions(BaseModel):
102
+ """Options for Local Crossover."""
103
+
104
+ name: Literal["LocalCrossover"] = Field(
105
+ default="LocalCrossover", frozen=True, description="The name of the crossover operator."
106
+ )
107
+ """The name of the crossover operator."""
108
+ xover_probability: float = Field(default=1.0, ge=0.0, le=1.0, description="The crossover probability.")
109
+ """The crossover probability."""
110
+
111
+
112
+ class BoundedExponentialCrossoverOptions(BaseModel):
113
+ """Options for Bounded Exponential Crossover."""
114
+
115
+ name: Literal["BoundedExponentialCrossover"] = Field(
116
+ default="BoundedExponentialCrossover", frozen=True, description="The name of the crossover operator."
117
+ )
118
+ """The name of the crossover operator."""
119
+ xover_probability: float = Field(default=1.0, ge=0.0, le=1.0, description="The crossover probability.")
120
+ """The crossover probability."""
121
+ lambda_: float = Field(default=1.0, gt=0.0, description="Positive scale λ for the exponential distribution.")
122
+ """Positive scale λ for the exponential distribution."""
123
+
124
+
125
+ CrossoverOptions = (
126
+ SimulatedBinaryCrossoverOptions
127
+ | SinglePointBinaryCrossoverOptions
128
+ | UniformIntegerCrossoverOptions
129
+ | UniformMixedIntegerCrossoverOptions
130
+ | BlendAlphaCrossoverOptions
131
+ | SingleArithmeticCrossoverOptions
132
+ | LocalCrossoverOptions
133
+ | BoundedExponentialCrossoverOptions
134
+ )
135
+
136
+
137
+ def crossover_constructor(
138
+ problem: Problem, publisher: Publisher, seed: int, verbosity: int, options: CrossoverOptions
139
+ ) -> BaseCrossover:
140
+ """Construct a crossover operator.
141
+
142
+ Args:
143
+ problem (Problem): The optimization problem to solve.
144
+ publisher (Publisher): The publisher for communication.
145
+ seed (int): The random seed for reproducibility.
146
+ verbosity (int): The verbosity level of the output.
147
+ options (CrossoverOptions): The options for the crossover operator.
148
+
149
+ Returns:
150
+ BaseCrossover: The constructed crossover operator.
151
+ """
152
+ crossover_types = {
153
+ "SimulatedBinaryCrossover": SimulatedBinaryCrossover,
154
+ "SinglePointBinaryCrossover": SinglePointBinaryCrossover,
155
+ "UniformIntegerCrossover": UniformIntegerCrossover,
156
+ "UniformMixedIntegerCrossover": UniformMixedIntegerCrossover,
157
+ "BlendAlphaCrossover": BlendAlphaCrossover,
158
+ "SingleArithmeticCrossover": SingleArithmeticCrossover,
159
+ "LocalCrossover": LocalCrossover,
160
+ "BoundedExponentialCrossover": BoundedExponentialCrossover,
161
+ }
162
+ options = options.model_dump()
163
+ name = options.pop("name")
164
+ return crossover_types[name](problem=problem, publisher=publisher, seed=seed, verbosity=verbosity, **dict(options))