pymoo 0.6.1.6__cp312-cp312-macosx_10_13_universal2.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 (337) hide show
  1. pymoo/__init__.py +3 -0
  2. pymoo/algorithms/__init__.py +0 -0
  3. pymoo/algorithms/base/__init__.py +0 -0
  4. pymoo/algorithms/base/bracket.py +38 -0
  5. pymoo/algorithms/base/genetic.py +110 -0
  6. pymoo/algorithms/base/line.py +62 -0
  7. pymoo/algorithms/base/local.py +39 -0
  8. pymoo/algorithms/base/meta.py +79 -0
  9. pymoo/algorithms/hyperparameters.py +91 -0
  10. pymoo/algorithms/moo/__init__.py +0 -0
  11. pymoo/algorithms/moo/age.py +310 -0
  12. pymoo/algorithms/moo/age2.py +194 -0
  13. pymoo/algorithms/moo/cmopso.py +239 -0
  14. pymoo/algorithms/moo/ctaea.py +305 -0
  15. pymoo/algorithms/moo/dnsga2.py +80 -0
  16. pymoo/algorithms/moo/kgb.py +450 -0
  17. pymoo/algorithms/moo/moead.py +183 -0
  18. pymoo/algorithms/moo/mopso_cd.py +309 -0
  19. pymoo/algorithms/moo/nsga2.py +113 -0
  20. pymoo/algorithms/moo/nsga3.py +361 -0
  21. pymoo/algorithms/moo/pinsga2.py +370 -0
  22. pymoo/algorithms/moo/rnsga2.py +188 -0
  23. pymoo/algorithms/moo/rnsga3.py +246 -0
  24. pymoo/algorithms/moo/rvea.py +214 -0
  25. pymoo/algorithms/moo/sms.py +196 -0
  26. pymoo/algorithms/moo/spea2.py +191 -0
  27. pymoo/algorithms/moo/unsga3.py +49 -0
  28. pymoo/algorithms/soo/__init__.py +0 -0
  29. pymoo/algorithms/soo/convex/__init__.py +0 -0
  30. pymoo/algorithms/soo/nonconvex/__init__.py +0 -0
  31. pymoo/algorithms/soo/nonconvex/brkga.py +162 -0
  32. pymoo/algorithms/soo/nonconvex/cmaes.py +556 -0
  33. pymoo/algorithms/soo/nonconvex/de.py +283 -0
  34. pymoo/algorithms/soo/nonconvex/direct.py +148 -0
  35. pymoo/algorithms/soo/nonconvex/es.py +213 -0
  36. pymoo/algorithms/soo/nonconvex/g3pcx.py +94 -0
  37. pymoo/algorithms/soo/nonconvex/ga.py +95 -0
  38. pymoo/algorithms/soo/nonconvex/ga_niching.py +223 -0
  39. pymoo/algorithms/soo/nonconvex/isres.py +74 -0
  40. pymoo/algorithms/soo/nonconvex/nelder.py +251 -0
  41. pymoo/algorithms/soo/nonconvex/nrbo.py +191 -0
  42. pymoo/algorithms/soo/nonconvex/optuna.py +80 -0
  43. pymoo/algorithms/soo/nonconvex/pattern.py +185 -0
  44. pymoo/algorithms/soo/nonconvex/pso.py +337 -0
  45. pymoo/algorithms/soo/nonconvex/pso_ep.py +307 -0
  46. pymoo/algorithms/soo/nonconvex/random_search.py +25 -0
  47. pymoo/algorithms/soo/nonconvex/sres.py +56 -0
  48. pymoo/algorithms/soo/univariate/__init__.py +0 -0
  49. pymoo/algorithms/soo/univariate/exp.py +46 -0
  50. pymoo/algorithms/soo/univariate/golden.py +65 -0
  51. pymoo/algorithms/soo/univariate/quadr_interp.py +81 -0
  52. pymoo/algorithms/soo/univariate/wolfe.py +163 -0
  53. pymoo/config.py +33 -0
  54. pymoo/constraints/__init__.py +3 -0
  55. pymoo/constraints/adaptive.py +66 -0
  56. pymoo/constraints/as_obj.py +56 -0
  57. pymoo/constraints/as_penalty.py +41 -0
  58. pymoo/constraints/eps.py +34 -0
  59. pymoo/constraints/from_bounds.py +36 -0
  60. pymoo/core/__init__.py +0 -0
  61. pymoo/core/algorithm.py +408 -0
  62. pymoo/core/callback.py +38 -0
  63. pymoo/core/crossover.py +79 -0
  64. pymoo/core/decision_making.py +102 -0
  65. pymoo/core/decomposition.py +76 -0
  66. pymoo/core/duplicate.py +163 -0
  67. pymoo/core/evaluator.py +116 -0
  68. pymoo/core/indicator.py +34 -0
  69. pymoo/core/individual.py +784 -0
  70. pymoo/core/infill.py +65 -0
  71. pymoo/core/initialization.py +44 -0
  72. pymoo/core/mating.py +39 -0
  73. pymoo/core/meta.py +21 -0
  74. pymoo/core/mixed.py +164 -0
  75. pymoo/core/mutation.py +44 -0
  76. pymoo/core/operator.py +46 -0
  77. pymoo/core/parameters.py +134 -0
  78. pymoo/core/plot.py +208 -0
  79. pymoo/core/population.py +180 -0
  80. pymoo/core/problem.py +373 -0
  81. pymoo/core/recorder.py +99 -0
  82. pymoo/core/repair.py +23 -0
  83. pymoo/core/replacement.py +96 -0
  84. pymoo/core/result.py +52 -0
  85. pymoo/core/sampling.py +45 -0
  86. pymoo/core/selection.py +61 -0
  87. pymoo/core/solution.py +10 -0
  88. pymoo/core/survival.py +107 -0
  89. pymoo/core/termination.py +70 -0
  90. pymoo/core/variable.py +415 -0
  91. pymoo/decomposition/__init__.py +0 -0
  92. pymoo/decomposition/aasf.py +24 -0
  93. pymoo/decomposition/asf.py +10 -0
  94. pymoo/decomposition/pbi.py +13 -0
  95. pymoo/decomposition/perp_dist.py +13 -0
  96. pymoo/decomposition/tchebicheff.py +11 -0
  97. pymoo/decomposition/util.py +13 -0
  98. pymoo/decomposition/weighted_sum.py +8 -0
  99. pymoo/docs.py +187 -0
  100. pymoo/experimental/__init__.py +0 -0
  101. pymoo/experimental/algorithms/__init__.py +0 -0
  102. pymoo/experimental/algorithms/gde3.py +57 -0
  103. pymoo/functions/__init__.py +135 -0
  104. pymoo/functions/compiled/__init__.py +0 -0
  105. pymoo/functions/compiled/calc_perpendicular_distance.cpp +27464 -0
  106. pymoo/functions/compiled/calc_perpendicular_distance.cpython-312-darwin.so +0 -0
  107. pymoo/functions/compiled/decomposition.cpp +28853 -0
  108. pymoo/functions/compiled/decomposition.cpython-312-darwin.so +0 -0
  109. pymoo/functions/compiled/info.cpp +7058 -0
  110. pymoo/functions/compiled/info.cpython-312-darwin.so +0 -0
  111. pymoo/functions/compiled/mnn.cpp +30095 -0
  112. pymoo/functions/compiled/mnn.cpython-312-darwin.so +0 -0
  113. pymoo/functions/compiled/non_dominated_sorting.cpp +35692 -0
  114. pymoo/functions/compiled/non_dominated_sorting.cpython-312-darwin.so +0 -0
  115. pymoo/functions/compiled/pruning_cd.cpp +29248 -0
  116. pymoo/functions/compiled/pruning_cd.cpython-312-darwin.so +0 -0
  117. pymoo/functions/compiled/stochastic_ranking.cpp +28042 -0
  118. pymoo/functions/compiled/stochastic_ranking.cpython-312-darwin.so +0 -0
  119. pymoo/functions/standard/__init__.py +1 -0
  120. pymoo/functions/standard/calc_perpendicular_distance.py +20 -0
  121. pymoo/functions/standard/decomposition.py +18 -0
  122. pymoo/functions/standard/hv.py +5 -0
  123. pymoo/functions/standard/mnn.py +78 -0
  124. pymoo/functions/standard/non_dominated_sorting.py +474 -0
  125. pymoo/functions/standard/pruning_cd.py +93 -0
  126. pymoo/functions/standard/stochastic_ranking.py +42 -0
  127. pymoo/gradient/__init__.py +24 -0
  128. pymoo/gradient/automatic.py +85 -0
  129. pymoo/gradient/grad_autograd.py +105 -0
  130. pymoo/gradient/grad_complex.py +35 -0
  131. pymoo/gradient/grad_jax.py +51 -0
  132. pymoo/gradient/numpy.py +22 -0
  133. pymoo/gradient/toolbox/__init__.py +19 -0
  134. pymoo/indicators/__init__.py +0 -0
  135. pymoo/indicators/distance_indicator.py +55 -0
  136. pymoo/indicators/gd.py +7 -0
  137. pymoo/indicators/gd_plus.py +7 -0
  138. pymoo/indicators/hv/__init__.py +59 -0
  139. pymoo/indicators/hv/approximate.py +105 -0
  140. pymoo/indicators/hv/exact.py +68 -0
  141. pymoo/indicators/hv/exact_2d.py +102 -0
  142. pymoo/indicators/igd.py +7 -0
  143. pymoo/indicators/igd_plus.py +7 -0
  144. pymoo/indicators/kktpm.py +151 -0
  145. pymoo/indicators/migd.py +55 -0
  146. pymoo/indicators/rmetric.py +203 -0
  147. pymoo/indicators/spacing.py +52 -0
  148. pymoo/mcdm/__init__.py +0 -0
  149. pymoo/mcdm/compromise_programming.py +19 -0
  150. pymoo/mcdm/high_tradeoff.py +40 -0
  151. pymoo/mcdm/pseudo_weights.py +32 -0
  152. pymoo/operators/__init__.py +0 -0
  153. pymoo/operators/control.py +190 -0
  154. pymoo/operators/crossover/__init__.py +0 -0
  155. pymoo/operators/crossover/binx.py +47 -0
  156. pymoo/operators/crossover/dex.py +125 -0
  157. pymoo/operators/crossover/erx.py +164 -0
  158. pymoo/operators/crossover/expx.py +53 -0
  159. pymoo/operators/crossover/hux.py +37 -0
  160. pymoo/operators/crossover/nox.py +25 -0
  161. pymoo/operators/crossover/ox.py +88 -0
  162. pymoo/operators/crossover/pcx.py +84 -0
  163. pymoo/operators/crossover/pntx.py +49 -0
  164. pymoo/operators/crossover/sbx.py +137 -0
  165. pymoo/operators/crossover/spx.py +5 -0
  166. pymoo/operators/crossover/ux.py +20 -0
  167. pymoo/operators/mutation/__init__.py +0 -0
  168. pymoo/operators/mutation/bitflip.py +17 -0
  169. pymoo/operators/mutation/gauss.py +60 -0
  170. pymoo/operators/mutation/inversion.py +42 -0
  171. pymoo/operators/mutation/nom.py +7 -0
  172. pymoo/operators/mutation/pm.py +96 -0
  173. pymoo/operators/mutation/rm.py +23 -0
  174. pymoo/operators/repair/__init__.py +0 -0
  175. pymoo/operators/repair/bounce_back.py +32 -0
  176. pymoo/operators/repair/bounds_repair.py +97 -0
  177. pymoo/operators/repair/inverse_penalty.py +91 -0
  178. pymoo/operators/repair/rounding.py +18 -0
  179. pymoo/operators/repair/to_bound.py +31 -0
  180. pymoo/operators/repair/vtype.py +11 -0
  181. pymoo/operators/sampling/__init__.py +0 -0
  182. pymoo/operators/sampling/lhs.py +76 -0
  183. pymoo/operators/sampling/rnd.py +52 -0
  184. pymoo/operators/selection/__init__.py +0 -0
  185. pymoo/operators/selection/rnd.py +75 -0
  186. pymoo/operators/selection/tournament.py +78 -0
  187. pymoo/operators/survival/__init__.py +0 -0
  188. pymoo/operators/survival/rank_and_crowding/__init__.py +1 -0
  189. pymoo/operators/survival/rank_and_crowding/classes.py +212 -0
  190. pymoo/operators/survival/rank_and_crowding/metrics.py +208 -0
  191. pymoo/optimize.py +72 -0
  192. pymoo/parallelization/__init__.py +15 -0
  193. pymoo/parallelization/dask.py +25 -0
  194. pymoo/parallelization/joblib.py +28 -0
  195. pymoo/parallelization/ray.py +31 -0
  196. pymoo/parallelization/starmap.py +24 -0
  197. pymoo/problems/__init__.py +157 -0
  198. pymoo/problems/dyn.py +47 -0
  199. pymoo/problems/dynamic/__init__.py +0 -0
  200. pymoo/problems/dynamic/cec2015.py +108 -0
  201. pymoo/problems/dynamic/df.py +451 -0
  202. pymoo/problems/dynamic/misc.py +167 -0
  203. pymoo/problems/functional.py +48 -0
  204. pymoo/problems/many/__init__.py +5 -0
  205. pymoo/problems/many/cdtlz.py +159 -0
  206. pymoo/problems/many/dcdtlz.py +88 -0
  207. pymoo/problems/many/dtlz.py +264 -0
  208. pymoo/problems/many/wfg.py +553 -0
  209. pymoo/problems/multi/__init__.py +14 -0
  210. pymoo/problems/multi/bnh.py +34 -0
  211. pymoo/problems/multi/carside.py +48 -0
  212. pymoo/problems/multi/clutch.py +104 -0
  213. pymoo/problems/multi/csi.py +55 -0
  214. pymoo/problems/multi/ctp.py +198 -0
  215. pymoo/problems/multi/dascmop.py +213 -0
  216. pymoo/problems/multi/kursawe.py +25 -0
  217. pymoo/problems/multi/modact.py +68 -0
  218. pymoo/problems/multi/mw.py +400 -0
  219. pymoo/problems/multi/omnitest.py +48 -0
  220. pymoo/problems/multi/osy.py +32 -0
  221. pymoo/problems/multi/srn.py +28 -0
  222. pymoo/problems/multi/sympart.py +94 -0
  223. pymoo/problems/multi/tnk.py +24 -0
  224. pymoo/problems/multi/truss2d.py +83 -0
  225. pymoo/problems/multi/welded_beam.py +41 -0
  226. pymoo/problems/multi/wrm.py +36 -0
  227. pymoo/problems/multi/zdt.py +151 -0
  228. pymoo/problems/multi_to_single.py +22 -0
  229. pymoo/problems/single/__init__.py +12 -0
  230. pymoo/problems/single/ackley.py +24 -0
  231. pymoo/problems/single/cantilevered_beam.py +34 -0
  232. pymoo/problems/single/flowshop_scheduling.py +113 -0
  233. pymoo/problems/single/g.py +874 -0
  234. pymoo/problems/single/griewank.py +18 -0
  235. pymoo/problems/single/himmelblau.py +15 -0
  236. pymoo/problems/single/knapsack.py +49 -0
  237. pymoo/problems/single/mopta08.py +26 -0
  238. pymoo/problems/single/multimodal.py +20 -0
  239. pymoo/problems/single/pressure_vessel.py +30 -0
  240. pymoo/problems/single/rastrigin.py +20 -0
  241. pymoo/problems/single/rosenbrock.py +22 -0
  242. pymoo/problems/single/schwefel.py +18 -0
  243. pymoo/problems/single/simple.py +13 -0
  244. pymoo/problems/single/sphere.py +19 -0
  245. pymoo/problems/single/traveling_salesman.py +79 -0
  246. pymoo/problems/single/zakharov.py +19 -0
  247. pymoo/problems/static.py +14 -0
  248. pymoo/problems/util.py +42 -0
  249. pymoo/problems/zero_to_one.py +27 -0
  250. pymoo/termination/__init__.py +23 -0
  251. pymoo/termination/collection.py +12 -0
  252. pymoo/termination/cv.py +48 -0
  253. pymoo/termination/default.py +45 -0
  254. pymoo/termination/delta.py +64 -0
  255. pymoo/termination/fmin.py +16 -0
  256. pymoo/termination/ftol.py +144 -0
  257. pymoo/termination/indicator.py +49 -0
  258. pymoo/termination/max_eval.py +14 -0
  259. pymoo/termination/max_gen.py +15 -0
  260. pymoo/termination/max_time.py +20 -0
  261. pymoo/termination/robust.py +34 -0
  262. pymoo/termination/xtol.py +33 -0
  263. pymoo/util/__init__.py +33 -0
  264. pymoo/util/archive.py +152 -0
  265. pymoo/util/cache.py +29 -0
  266. pymoo/util/clearing.py +82 -0
  267. pymoo/util/display/__init__.py +0 -0
  268. pymoo/util/display/column.py +52 -0
  269. pymoo/util/display/display.py +34 -0
  270. pymoo/util/display/multi.py +100 -0
  271. pymoo/util/display/output.py +53 -0
  272. pymoo/util/display/progress.py +54 -0
  273. pymoo/util/display/single.py +67 -0
  274. pymoo/util/dominator.py +67 -0
  275. pymoo/util/hv.py +21 -0
  276. pymoo/util/matlab_engine.py +39 -0
  277. pymoo/util/misc.py +447 -0
  278. pymoo/util/nds/__init__.py +0 -0
  279. pymoo/util/nds/dominance_degree_non_dominated_sort.py +159 -0
  280. pymoo/util/nds/efficient_non_dominated_sort.py +152 -0
  281. pymoo/util/nds/fast_non_dominated_sort.py +70 -0
  282. pymoo/util/nds/find_non_dominated.py +54 -0
  283. pymoo/util/nds/naive_non_dominated_sort.py +36 -0
  284. pymoo/util/nds/non_dominated_sorting.py +94 -0
  285. pymoo/util/nds/tree_based_non_dominated_sort.py +133 -0
  286. pymoo/util/normalization.py +312 -0
  287. pymoo/util/optimum.py +42 -0
  288. pymoo/util/randomized_argsort.py +63 -0
  289. pymoo/util/ref_dirs/__init__.py +24 -0
  290. pymoo/util/ref_dirs/construction.py +89 -0
  291. pymoo/util/ref_dirs/das_dennis.py +52 -0
  292. pymoo/util/ref_dirs/energy.py +317 -0
  293. pymoo/util/ref_dirs/energy_layer.py +119 -0
  294. pymoo/util/ref_dirs/genetic_algorithm.py +64 -0
  295. pymoo/util/ref_dirs/incremental.py +69 -0
  296. pymoo/util/ref_dirs/misc.py +128 -0
  297. pymoo/util/ref_dirs/optimizer.py +59 -0
  298. pymoo/util/ref_dirs/performance.py +162 -0
  299. pymoo/util/ref_dirs/reduction.py +85 -0
  300. pymoo/util/ref_dirs/sample_and_map.py +24 -0
  301. pymoo/util/reference_direction.py +258 -0
  302. pymoo/util/remote.py +55 -0
  303. pymoo/util/roulette.py +29 -0
  304. pymoo/util/running_metric.py +128 -0
  305. pymoo/util/sliding_window.py +25 -0
  306. pymoo/util/value_functions.py +720 -0
  307. pymoo/util/vectors.py +40 -0
  308. pymoo/util/vf_dominator.py +102 -0
  309. pymoo/vendor/__init__.py +0 -0
  310. pymoo/vendor/cec2018.py +398 -0
  311. pymoo/vendor/gta.py +617 -0
  312. pymoo/vendor/vendor_cmaes.py +421 -0
  313. pymoo/vendor/vendor_coco.py +81 -0
  314. pymoo/vendor/vendor_scipy.py +232 -0
  315. pymoo/version.py +1 -0
  316. pymoo/visualization/__init__.py +21 -0
  317. pymoo/visualization/app/__init__.py +0 -0
  318. pymoo/visualization/app/pso.py +61 -0
  319. pymoo/visualization/fitness_landscape.py +128 -0
  320. pymoo/visualization/heatmap.py +123 -0
  321. pymoo/visualization/matplotlib.py +61 -0
  322. pymoo/visualization/pcp.py +121 -0
  323. pymoo/visualization/petal.py +91 -0
  324. pymoo/visualization/radar.py +108 -0
  325. pymoo/visualization/radviz.py +68 -0
  326. pymoo/visualization/scatter.py +150 -0
  327. pymoo/visualization/star_coordinate.py +75 -0
  328. pymoo/visualization/util.py +296 -0
  329. pymoo/visualization/video/__init__.py +0 -0
  330. pymoo/visualization/video/callback_video.py +82 -0
  331. pymoo/visualization/video/one_var_one_obj.py +57 -0
  332. pymoo/visualization/video/two_var_one_obj.py +62 -0
  333. pymoo-0.6.1.6.dist-info/METADATA +209 -0
  334. pymoo-0.6.1.6.dist-info/RECORD +337 -0
  335. pymoo-0.6.1.6.dist-info/WHEEL +6 -0
  336. pymoo-0.6.1.6.dist-info/licenses/LICENSE +191 -0
  337. pymoo-0.6.1.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,61 @@
1
+ from abc import abstractmethod
2
+
3
+ import numpy as np
4
+
5
+ from pymoo.core.operator import Operator
6
+ from pymoo.util import default_random_state
7
+
8
+
9
+ class Selection(Operator):
10
+
11
+ def __init__(self, **kwargs) -> None:
12
+ """
13
+ This class is used to select parents for the mating or other evolutionary operators.
14
+ Several strategies can be used to increase the selection pressure.
15
+ """
16
+ super().__init__(**kwargs)
17
+
18
+ @default_random_state
19
+ def do(self, problem, pop, n_select, n_parents, to_pop=True, *args, random_state=None, **kwargs):
20
+ """
21
+ Choose from the population new individuals to be selected.
22
+
23
+ Parameters
24
+ ----------
25
+
26
+
27
+ problem: class
28
+ The problem to be solved. Provides information such as lower and upper bounds or feasibility
29
+ conditions for custom crossovers.
30
+
31
+ pop : :class:`~pymoo.core.population.Population`
32
+ The population which should be selected from. Some criteria from the design or objective space
33
+ might be used for the selection. Therefore, only the number of individual might be not enough.
34
+
35
+ n_select : int
36
+ Number of individuals to select.
37
+
38
+ n_parents : int
39
+ Number of parents needed to create an offspring.
40
+
41
+ to_pop : bool
42
+ Whether IF(!) the implementation returns only indices, it should be converted to individuals.
43
+
44
+ Returns
45
+ -------
46
+ parents : list
47
+ List of parents to be used in the crossover
48
+
49
+ """
50
+
51
+ ret = self._do(problem, pop, n_select, n_parents, *args, random_state=random_state, **kwargs)
52
+
53
+ # if some selections return indices they are used to create the individual list
54
+ if to_pop and isinstance(ret, np.ndarray) and np.issubdtype(ret.dtype, np.integer):
55
+ ret = pop[ret]
56
+
57
+ return ret
58
+
59
+ @abstractmethod
60
+ def _do(self, problem, pop, n_select, n_parents, *args, random_state=None, **kwargs):
61
+ pass
pymoo/core/solution.py ADDED
@@ -0,0 +1,10 @@
1
+ from pymoo.core.individual import Individual
2
+ from pymoo.core.population import Population
3
+
4
+
5
+ class Solution(Individual):
6
+ pass
7
+
8
+
9
+ class SolutionSet(Population):
10
+ pass
pymoo/core/survival.py ADDED
@@ -0,0 +1,107 @@
1
+ from abc import abstractmethod
2
+
3
+ import numpy as np
4
+
5
+ from pymoo.core.population import Population
6
+ from pymoo.util import default_random_state
7
+
8
+
9
+ # ---------------------------------------------------------------------------------------------------------
10
+ # Survival
11
+ # ---------------------------------------------------------------------------------------------------------
12
+
13
+
14
+ class Survival:
15
+
16
+ def __init__(self, filter_infeasible=True):
17
+ super().__init__()
18
+ self.filter_infeasible = filter_infeasible
19
+
20
+ @default_random_state
21
+ def do(self,
22
+ problem,
23
+ pop,
24
+ *args,
25
+ n_survive=None,
26
+ random_state=None,
27
+ return_indices=False,
28
+ **kwargs):
29
+
30
+ # make sure the population has at least one individual
31
+ if len(pop) == 0:
32
+ return pop
33
+
34
+ if n_survive is None:
35
+ n_survive = len(pop)
36
+
37
+ n_survive = min(n_survive, len(pop))
38
+
39
+ # if the split should be done beforehand
40
+ if self.filter_infeasible and problem.has_constraints():
41
+
42
+ # split feasible and infeasible solutions
43
+ feas, infeas = split_by_feasibility(pop, sort_infeas_by_cv=True)
44
+
45
+ if len(feas) == 0:
46
+ survivors = Population()
47
+ else:
48
+ survivors = self._do(problem, pop[feas], *args, n_survive=min(len(feas), n_survive),
49
+ random_state=random_state, **kwargs)
50
+
51
+ # calculate how many individuals are still remaining to be filled up with infeasible ones
52
+ n_remaining = n_survive - len(survivors)
53
+
54
+ # if infeasible solutions needs to be added
55
+ if n_remaining > 0:
56
+ survivors = Population.merge(survivors, pop[infeas[:n_remaining]])
57
+
58
+ else:
59
+ survivors = self._do(problem, pop, *args, n_survive=n_survive, random_state=random_state, **kwargs)
60
+
61
+ if return_indices:
62
+ H = {}
63
+ for k, ind in enumerate(pop):
64
+ H[ind] = k
65
+ return [H[survivor] for survivor in survivors]
66
+ else:
67
+ return survivors
68
+
69
+ @abstractmethod
70
+ def _do(self, problem, pop, *args, n_survive=None, random_state=None, **kwargs):
71
+ pass
72
+
73
+
74
+ class ToReplacement(Survival):
75
+
76
+ def __init__(self, survival):
77
+ super().__init__(False)
78
+ self.survival = survival
79
+
80
+ def _do(self, problem, pop, off, random_state=None, **kwargs):
81
+ merged = Population.merge(pop, off)
82
+ I = self.survival.do(problem, merged, n_survive=len(merged), return_indices=True, random_state=random_state, **kwargs)
83
+ merged.set("__rank__", I)
84
+
85
+ for k in range(len(pop)):
86
+ if off[k].get("__rank__") < pop[k].get("__rank__"):
87
+ pop[k] = off[k]
88
+
89
+ return pop
90
+
91
+
92
+ def split_by_feasibility(pop, sort_infeas_by_cv=True, sort_feas_by_obj=False, return_pop=False):
93
+ F, CV, b = pop.get("F", "CV", "FEAS")
94
+
95
+ feasible = np.where(b)[0]
96
+ infeasible = np.where(~b)[0]
97
+
98
+ if sort_infeas_by_cv:
99
+ infeasible = infeasible[np.argsort(CV[infeasible, 0])]
100
+
101
+ if sort_feas_by_obj:
102
+ feasible = feasible[np.argsort(F[feasible, 0])]
103
+
104
+ if not return_pop:
105
+ return feasible, infeasible
106
+ else:
107
+ return feasible, infeasible, pop[feasible], pop[infeasible]
@@ -0,0 +1,70 @@
1
+ from abc import abstractmethod
2
+
3
+
4
+ class Termination:
5
+
6
+ def __init__(self) -> None:
7
+ super().__init__()
8
+
9
+ # the algorithm can be forced to terminate by setting this attribute to true
10
+ self.force_termination = False
11
+
12
+ # the value indicating how much perc has been made
13
+ self.perc = 0.0
14
+
15
+ def update(self, algorithm):
16
+ """
17
+ Provide the termination criterion a current status of the algorithm to update the perc.
18
+
19
+ Parameters
20
+ ----------
21
+ algorithm : object
22
+ The algorithm object which is used to determine whether a run has terminated.
23
+ """
24
+
25
+ if self.force_termination:
26
+ progress = 1.0
27
+ else:
28
+ progress = self._update(algorithm)
29
+ assert progress >= 0.0, "Invalid progress was set by the TerminationCriterion."
30
+
31
+ self.perc = progress
32
+ return self.perc
33
+
34
+ def has_terminated(self):
35
+ return self.perc >= 1.0
36
+
37
+ def do_continue(self):
38
+ return not self.has_terminated()
39
+
40
+ def terminate(self):
41
+ self.force_termination = True
42
+
43
+ @abstractmethod
44
+ def _update(self, algorithm):
45
+ pass
46
+
47
+
48
+ class NoTermination(Termination):
49
+
50
+ def _update(self, algorithm):
51
+ return 0.0
52
+
53
+
54
+ class MultipleCriteria(Termination):
55
+
56
+ def __init__(self, *args) -> None:
57
+ super().__init__()
58
+ self.criteria = args
59
+
60
+
61
+ class TerminateIfAny(MultipleCriteria):
62
+
63
+ def _update(self, algorithm):
64
+ return max([termination.update(algorithm) for termination in self.criteria])
65
+
66
+
67
+ class TerminateIfAll(MultipleCriteria):
68
+
69
+ def _update(self, algorithm):
70
+ return min([termination.update(algorithm) for termination in self.criteria])
pymoo/core/variable.py ADDED
@@ -0,0 +1,415 @@
1
+ """
2
+ Module containing infrastructure for representing decision variable classes.
3
+ """
4
+
5
+ # public API for when using ``from pymoo.core.variable import *``
6
+ __all__ = [
7
+ "Variable",
8
+ "BoundedVariable",
9
+ "Real",
10
+ "Integer",
11
+ "Binary",
12
+ "Choice",
13
+ "get",
14
+ ]
15
+
16
+ from typing import Any, Optional, Tuple
17
+ from typing import Union
18
+ import numpy as np
19
+ from numpy.typing import ArrayLike
20
+ from pymoo.util import default_random_state
21
+
22
+
23
+ class Variable(object):
24
+ """
25
+ Semi-abstract base class for the representation of a decision variable.
26
+ """
27
+
28
+ def __init__(
29
+ self,
30
+ value: Optional[object] = None,
31
+ active: bool = True,
32
+ flag: str = "default",
33
+ ) -> None:
34
+ """
35
+ Constructor for the ``Variable`` class.
36
+
37
+ Parameters
38
+ ----------
39
+ value : object, None
40
+ Value the decision variable is to take.
41
+ active : bool
42
+ Whether the variable is active (``True``) or inactive (``False``).
43
+ flag : str
44
+ Flag to bind to the decision variable.
45
+ """
46
+ super().__init__()
47
+ self.value = value
48
+ self.flag = flag
49
+ self.active = active
50
+
51
+ @default_random_state
52
+ def sample(
53
+ self,
54
+ n: Optional[int] = None,
55
+ random_state=None,
56
+ ) -> Union[object,np.ndarray]:
57
+ """
58
+ Randomly sample ``n`` instances of a decision variable.
59
+
60
+ Parameters
61
+ ----------
62
+ n : int, None
63
+ Number of decision variable samples which to draw.
64
+ If ``int``, sample ``n`` decision variables.
65
+ If ``None``, sample a single decision variables.
66
+
67
+ Returns
68
+ -------
69
+ out : object, np.ndarray
70
+ If ``n`` is ``int``, return a ``np.ndarray`` of shape ``(n,)``
71
+ containing sampled decision variables.
72
+ If ``n`` is ``None``, return an ``object`` of a sampled decision
73
+ variable.
74
+ """
75
+ if n is None:
76
+ return self._sample(1, random_state=random_state)[0]
77
+ else:
78
+ return self._sample(n, random_state=random_state)
79
+
80
+ def _sample(
81
+ self,
82
+ n: int,
83
+ random_state=None,
84
+ ) -> np.ndarray:
85
+ """
86
+ Randomly sample ``n`` instances of a decision variable.
87
+ This is an abstract private method governing the behavior of the
88
+ ``sample`` method.
89
+
90
+ Parameters
91
+ ----------
92
+ n : int
93
+ Number of decision variable samples which to draw.
94
+
95
+ Returns
96
+ -------
97
+ out : np.ndarray
98
+ An array of shape ``(n,)`` containing sampled decision variables.
99
+ """
100
+ pass
101
+
102
+ def set(
103
+ self,
104
+ value: object,
105
+ ) -> None:
106
+ """
107
+ Set the value of a decision variable.
108
+
109
+ Parameters
110
+ ----------
111
+ value : object
112
+ Value to assign to the decision variable.
113
+ """
114
+ self.value = value
115
+
116
+ def get(
117
+ self,
118
+ **kwargs: Any
119
+ ) -> object:
120
+ """
121
+ Get the value of a decision variable.
122
+
123
+ Parameters
124
+ ----------
125
+ kwargs : Any
126
+ Additional keyword arguments.
127
+
128
+ Returns
129
+ -------
130
+ out : object
131
+ The value of the decision variable.
132
+ """
133
+ return self.value
134
+
135
+
136
+ class BoundedVariable(Variable):
137
+ """
138
+ Semi-abstract class for the representation of a bounded decision variable.
139
+ """
140
+
141
+ def __init__(
142
+ self,
143
+ value: Optional[object] = None,
144
+ bounds: Tuple[Optional[object],Optional[object]] = (None, None),
145
+ strict: Optional[Tuple[Optional[object],Optional[object]]] = None,
146
+ **kwargs: Any,
147
+ ) -> None:
148
+ """
149
+ Constructor for the ``BoundedVariable`` class.
150
+
151
+ Parameters
152
+ ----------
153
+ value : object
154
+ Value the decision variable is to take.
155
+ bounds : tuple
156
+ A tuple of length 2 containing upper and lower limits for the
157
+ decision variable.
158
+ strict : tuple, None
159
+ Strict boundaries for the decision variable.
160
+ If ``None``, the value of ``bounds`` is copied to ``strict``.
161
+ kwargs : Any
162
+ Additional keyword arguments for ``active`` and ``flag``.
163
+ """
164
+ # call the Variable constructor
165
+ super().__init__(value=value, **kwargs)
166
+ self.bounds = bounds
167
+
168
+ # if no strict boundaries were provided, consider ``bounds`` as
169
+ # strict boundaries
170
+ if strict is None:
171
+ strict = bounds
172
+ self.strict = strict
173
+
174
+ @property
175
+ def lb(self) -> object:
176
+ """
177
+ Lower bound of the decision variable.
178
+
179
+ Returns
180
+ -------
181
+ out : object
182
+ The decision variable lower bound.
183
+ """
184
+ return self.bounds[0]
185
+
186
+ @property
187
+ def ub(self) -> object:
188
+ """
189
+ Upper bound of the decision variable.
190
+
191
+ Returns
192
+ -------
193
+ out : object
194
+ The decision variable upper bound.
195
+ """
196
+ return self.bounds[1]
197
+
198
+
199
+ class Real(BoundedVariable):
200
+ """
201
+ Class for the representation of bounded, real decision variables.
202
+ """
203
+ # variable type represented by this object class
204
+ vtype = float
205
+
206
+ def _sample(
207
+ self,
208
+ n: int,
209
+ random_state=None,
210
+ ) -> np.ndarray:
211
+ """
212
+ Randomly sample ``n`` instances of a real, bounded decision variable.
213
+ Decision variables are sampled from a uniform distribution.
214
+
215
+ This is a private method governing the behavior of the ``sample``
216
+ method.
217
+
218
+ Parameters
219
+ ----------
220
+ n : int
221
+ Number of decision variable samples which to draw.
222
+ random_state
223
+ Random state for sampling.
224
+
225
+ Returns
226
+ -------
227
+ out : np.ndarray
228
+ An array of shape ``(n,)`` containing sampled real, bounded
229
+ decision variables.
230
+ """
231
+ low, high = self.bounds
232
+ return random_state.uniform(low=low, high=high, size=n)
233
+
234
+
235
+ class Integer(BoundedVariable):
236
+ """
237
+ Class for the representation of bounded, integer decision variables.
238
+ """
239
+ # variable type represented by this object class
240
+ vtype = int
241
+
242
+ def _sample(
243
+ self,
244
+ n: int,
245
+ random_state=None,
246
+ ) -> np.ndarray:
247
+ """
248
+ Randomly sample ``n`` instances of a bounded, integer decision variable.
249
+ Decision variables are sampled from a uniform distribution.
250
+
251
+ This is a private method governing the behavior of the ``sample``
252
+ method.
253
+
254
+ Parameters
255
+ ----------
256
+ n : int
257
+ Number of decision variable samples which to draw.
258
+ random_state
259
+ Random state for sampling.
260
+
261
+ Returns
262
+ -------
263
+ out : np.ndarray
264
+ An array of shape ``(n,)`` containing sampled bounded, integer
265
+ decision variables.
266
+ """
267
+ low, high = self.bounds
268
+ return random_state.integers(low, high + 1, size=n)
269
+
270
+
271
+ class Binary(BoundedVariable):
272
+ """
273
+ Class for the representation of a binary, bounded decision variable.
274
+ """
275
+ # variable type represented by this object class
276
+ vtype = bool
277
+
278
+ def _sample(
279
+ self,
280
+ n: int,
281
+ random_state=None,
282
+ ) -> np.ndarray:
283
+ """
284
+ Randomly sample ``n`` instances of a bounded, binary decision variable.
285
+ Decision variables are sampled from a uniform distribution.
286
+
287
+ This is a private method governing the behavior of the ``sample``
288
+ method.
289
+
290
+ Parameters
291
+ ----------
292
+ n : int
293
+ Number of decision variable samples which to draw.
294
+ random_state
295
+ Random state for sampling.
296
+
297
+ Returns
298
+ -------
299
+ out : np.ndarray
300
+ An array of shape ``(n,)`` containing sampled bounded, binary
301
+ decision variables.
302
+ """
303
+ return random_state.random(size=n) < 0.5
304
+
305
+
306
+ class Choice(Variable):
307
+ """
308
+ Class for the representation of a discrete, subset decision variable.
309
+ """
310
+ # variable type represented by this object class
311
+ vtype = object
312
+
313
+ def __init__(
314
+ self,
315
+ value: Optional[object] = None,
316
+ options: Optional[ArrayLike] = None,
317
+ all: Optional[ArrayLike] = None,
318
+ **kwargs: Any,
319
+ ) -> None:
320
+ """
321
+ Constructor for the ``Choice`` class.
322
+
323
+ Parameters
324
+ ----------
325
+ value : object
326
+ Value the decision variable is to take.
327
+ options : ArrayLike, None
328
+ A list of decision variable options from which to choose.
329
+ all : ArrayLike, None
330
+ A strict list of decision variable options from which to choose.
331
+ If ``None``, the value of ``options`` is copied to ``all``.
332
+ kwargs : Any
333
+ Additional keyword arguments for ``active`` and ``flag``.
334
+ """
335
+ # all super constructor
336
+ super().__init__(value=value, **kwargs)
337
+ self.options = options
338
+
339
+ # if strict list not provided, set to ``options``
340
+ if all is None:
341
+ all = options
342
+ self.all = all
343
+
344
+ def _sample(
345
+ self,
346
+ n: int,
347
+ random_state=None,
348
+ ) -> np.ndarray:
349
+ """
350
+ Randomly sample ``n`` instances of a discrete, subset decision variable.
351
+ Decision variables are sampled with replacement from a uniform
352
+ distribution.
353
+
354
+ This is a private method governing the behavior of the ``sample``
355
+ method.
356
+
357
+ Parameters
358
+ ----------
359
+ n : int
360
+ Number of decision variable samples which to draw.
361
+ random_state
362
+ Random state for sampling.
363
+
364
+ Returns
365
+ -------
366
+ out : np.ndarray
367
+ An array of shape ``(n,)`` containing sampled bounded, integer
368
+ decision variables.
369
+ """
370
+ return random_state.choice(self.options, size=n)
371
+
372
+
373
+ def get(
374
+ *args: Tuple[Union[Variable,object],...],
375
+ size: Optional[Union[tuple,int]] = None,
376
+ **kwargs: Any
377
+ ) -> Union[tuple,object,None]:
378
+ """
379
+ Get decision variable values from a tuple of ``Variable`` objects.
380
+
381
+ Parameters
382
+ ----------
383
+ args : tuple
384
+ A tuple of ``Variable`` or ``object``s.
385
+ size : tuple, int, None
386
+ Size to reshape decision variables.
387
+ kwargs : Any
388
+ Additional keyword arguments to pass to the ``get`` method of the
389
+ ``Variable`` class when getting decision variable values.
390
+
391
+ Returns
392
+ -------
393
+ out : tuple, object, None
394
+ Decision variable value(s).
395
+ """
396
+ if len(args) == 0:
397
+ return
398
+
399
+ ret = []
400
+ for arg in args:
401
+ v = arg.get(**kwargs) if isinstance(arg, Variable) else arg
402
+
403
+ if size is not None:
404
+
405
+ if isinstance(v, np.ndarray):
406
+ v = np.reshape(v, size)
407
+ else:
408
+ v = np.full(size, v)
409
+
410
+ ret.append(v)
411
+
412
+ if len(ret) == 1:
413
+ return ret[0]
414
+ else:
415
+ return tuple(ret)
File without changes
@@ -0,0 +1,24 @@
1
+ import numpy as np
2
+
3
+ from pymoo.decomposition.asf import ASF
4
+
5
+
6
+ class AASF(ASF):
7
+
8
+ def __init__(self, eps=1e-10, _type="auto", rho=None, beta=None, **kwargs) -> None:
9
+ super().__init__(eps, _type, **kwargs)
10
+ if rho is None and beta is None:
11
+ raise Exception("Either provide rho or beta!")
12
+ elif rho is None:
13
+ self.rho = calc_rho(beta)
14
+ else:
15
+ self.rho = rho
16
+
17
+ def _do(self, F, weights, **kwargs):
18
+ asf = super()._do(F, weights, **kwargs)
19
+ augment = ((F - self.utopian_point) / np.clip(weights, 1e-12, np.inf)).sum(axis=1)
20
+ return asf + self.rho * augment
21
+
22
+
23
+ def calc_rho(beta):
24
+ return 1 / (1 - np.tan(beta / 360 * 2 * np.pi)) - 1
@@ -0,0 +1,10 @@
1
+ from pymoo.core.decomposition import Decomposition
2
+
3
+
4
+ class ASF(Decomposition):
5
+
6
+ def _do(self, F, weights, weight_0=1e-10, **kwargs):
7
+ _weights = weights.astype(float)
8
+ _weights[weights == 0] = weight_0
9
+ asf = ((F - self.utopian_point) / _weights).max(axis=1)
10
+ return asf