pymoo 0.6.1.5.dev0__cp39-cp39-musllinux_1_2_x86_64.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.

Potentially problematic release.


This version of pymoo might be problematic. Click here for more details.

Files changed (330) 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 +109 -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 +89 -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/ctaea.py +298 -0
  14. pymoo/algorithms/moo/dnsga2.py +76 -0
  15. pymoo/algorithms/moo/kgb.py +446 -0
  16. pymoo/algorithms/moo/moead.py +183 -0
  17. pymoo/algorithms/moo/nsga2.py +113 -0
  18. pymoo/algorithms/moo/nsga3.py +358 -0
  19. pymoo/algorithms/moo/pinsga2.py +370 -0
  20. pymoo/algorithms/moo/rnsga2.py +188 -0
  21. pymoo/algorithms/moo/rnsga3.py +246 -0
  22. pymoo/algorithms/moo/rvea.py +214 -0
  23. pymoo/algorithms/moo/sms.py +195 -0
  24. pymoo/algorithms/moo/spea2.py +190 -0
  25. pymoo/algorithms/moo/unsga3.py +47 -0
  26. pymoo/algorithms/soo/__init__.py +0 -0
  27. pymoo/algorithms/soo/convex/__init__.py +0 -0
  28. pymoo/algorithms/soo/nonconvex/__init__.py +0 -0
  29. pymoo/algorithms/soo/nonconvex/brkga.py +161 -0
  30. pymoo/algorithms/soo/nonconvex/cmaes.py +554 -0
  31. pymoo/algorithms/soo/nonconvex/de.py +279 -0
  32. pymoo/algorithms/soo/nonconvex/direct.py +149 -0
  33. pymoo/algorithms/soo/nonconvex/es.py +203 -0
  34. pymoo/algorithms/soo/nonconvex/g3pcx.py +94 -0
  35. pymoo/algorithms/soo/nonconvex/ga.py +93 -0
  36. pymoo/algorithms/soo/nonconvex/ga_niching.py +223 -0
  37. pymoo/algorithms/soo/nonconvex/isres.py +74 -0
  38. pymoo/algorithms/soo/nonconvex/nelder.py +251 -0
  39. pymoo/algorithms/soo/nonconvex/optuna.py +80 -0
  40. pymoo/algorithms/soo/nonconvex/pattern.py +183 -0
  41. pymoo/algorithms/soo/nonconvex/pso.py +399 -0
  42. pymoo/algorithms/soo/nonconvex/pso_ep.py +297 -0
  43. pymoo/algorithms/soo/nonconvex/random_search.py +25 -0
  44. pymoo/algorithms/soo/nonconvex/sres.py +56 -0
  45. pymoo/algorithms/soo/univariate/__init__.py +0 -0
  46. pymoo/algorithms/soo/univariate/backtracking.py +59 -0
  47. pymoo/algorithms/soo/univariate/exp.py +46 -0
  48. pymoo/algorithms/soo/univariate/golden.py +65 -0
  49. pymoo/algorithms/soo/univariate/quadr_interp.py +81 -0
  50. pymoo/algorithms/soo/univariate/wolfe.py +163 -0
  51. pymoo/config.py +33 -0
  52. pymoo/constraints/__init__.py +3 -0
  53. pymoo/constraints/adaptive.py +62 -0
  54. pymoo/constraints/as_obj.py +56 -0
  55. pymoo/constraints/as_penalty.py +41 -0
  56. pymoo/constraints/eps.py +26 -0
  57. pymoo/constraints/from_bounds.py +36 -0
  58. pymoo/core/__init__.py +0 -0
  59. pymoo/core/algorithm.py +394 -0
  60. pymoo/core/callback.py +38 -0
  61. pymoo/core/crossover.py +77 -0
  62. pymoo/core/decision_making.py +102 -0
  63. pymoo/core/decomposition.py +76 -0
  64. pymoo/core/duplicate.py +163 -0
  65. pymoo/core/evaluator.py +116 -0
  66. pymoo/core/indicator.py +34 -0
  67. pymoo/core/individual.py +784 -0
  68. pymoo/core/infill.py +64 -0
  69. pymoo/core/initialization.py +42 -0
  70. pymoo/core/mating.py +39 -0
  71. pymoo/core/meta.py +21 -0
  72. pymoo/core/mixed.py +165 -0
  73. pymoo/core/mutation.py +44 -0
  74. pymoo/core/operator.py +40 -0
  75. pymoo/core/parameters.py +134 -0
  76. pymoo/core/plot.py +210 -0
  77. pymoo/core/population.py +180 -0
  78. pymoo/core/problem.py +460 -0
  79. pymoo/core/recorder.py +99 -0
  80. pymoo/core/repair.py +23 -0
  81. pymoo/core/replacement.py +96 -0
  82. pymoo/core/result.py +52 -0
  83. pymoo/core/sampling.py +43 -0
  84. pymoo/core/selection.py +61 -0
  85. pymoo/core/solution.py +10 -0
  86. pymoo/core/survival.py +103 -0
  87. pymoo/core/termination.py +70 -0
  88. pymoo/core/variable.py +399 -0
  89. pymoo/cython/__init__.py +0 -0
  90. pymoo/cython/calc_perpendicular_distance.cpython-39-x86_64-linux-gnu.so +0 -0
  91. pymoo/cython/calc_perpendicular_distance.pyx +67 -0
  92. pymoo/cython/decomposition.cpython-39-x86_64-linux-gnu.so +0 -0
  93. pymoo/cython/decomposition.pyx +165 -0
  94. pymoo/cython/hv.cpython-39-x86_64-linux-gnu.so +0 -0
  95. pymoo/cython/hv.pyx +18 -0
  96. pymoo/cython/info.cpython-39-x86_64-linux-gnu.so +0 -0
  97. pymoo/cython/info.pyx +5 -0
  98. pymoo/cython/mnn.cpython-39-x86_64-linux-gnu.so +0 -0
  99. pymoo/cython/mnn.pyx +273 -0
  100. pymoo/cython/non_dominated_sorting.cpython-39-x86_64-linux-gnu.so +0 -0
  101. pymoo/cython/non_dominated_sorting.pyx +645 -0
  102. pymoo/cython/pruning_cd.cpython-39-x86_64-linux-gnu.so +0 -0
  103. pymoo/cython/pruning_cd.pyx +197 -0
  104. pymoo/cython/stochastic_ranking.cpython-39-x86_64-linux-gnu.so +0 -0
  105. pymoo/cython/stochastic_ranking.pyx +49 -0
  106. pymoo/cython/utils.pxd +129 -0
  107. pymoo/cython/vendor/__init__.py +0 -0
  108. pymoo/cython/vendor/hypervolume.cpp +1621 -0
  109. pymoo/cython/vendor/hypervolume.h +63 -0
  110. pymoo/decomposition/__init__.py +0 -0
  111. pymoo/decomposition/aasf.py +24 -0
  112. pymoo/decomposition/asf.py +10 -0
  113. pymoo/decomposition/pbi.py +13 -0
  114. pymoo/decomposition/perp_dist.py +13 -0
  115. pymoo/decomposition/tchebicheff.py +11 -0
  116. pymoo/decomposition/util.py +13 -0
  117. pymoo/decomposition/weighted_sum.py +8 -0
  118. pymoo/docs.py +187 -0
  119. pymoo/experimental/__init__.py +0 -0
  120. pymoo/experimental/algorithms/__init__.py +0 -0
  121. pymoo/experimental/algorithms/gde3.py +57 -0
  122. pymoo/gradient/__init__.py +21 -0
  123. pymoo/gradient/automatic.py +57 -0
  124. pymoo/gradient/grad_autograd.py +105 -0
  125. pymoo/gradient/grad_complex.py +35 -0
  126. pymoo/gradient/grad_jax.py +51 -0
  127. pymoo/gradient/toolbox/__init__.py +6 -0
  128. pymoo/indicators/__init__.py +0 -0
  129. pymoo/indicators/distance_indicator.py +55 -0
  130. pymoo/indicators/gd.py +7 -0
  131. pymoo/indicators/gd_plus.py +7 -0
  132. pymoo/indicators/hv/__init__.py +63 -0
  133. pymoo/indicators/hv/exact.py +71 -0
  134. pymoo/indicators/hv/exact_2d.py +102 -0
  135. pymoo/indicators/hv/monte_carlo.py +74 -0
  136. pymoo/indicators/igd.py +7 -0
  137. pymoo/indicators/igd_plus.py +7 -0
  138. pymoo/indicators/kktpm.py +151 -0
  139. pymoo/indicators/migd.py +55 -0
  140. pymoo/indicators/rmetric.py +203 -0
  141. pymoo/indicators/spacing.py +52 -0
  142. pymoo/mcdm/__init__.py +0 -0
  143. pymoo/mcdm/compromise_programming.py +19 -0
  144. pymoo/mcdm/high_tradeoff.py +40 -0
  145. pymoo/mcdm/pseudo_weights.py +32 -0
  146. pymoo/operators/__init__.py +0 -0
  147. pymoo/operators/control.py +187 -0
  148. pymoo/operators/crossover/__init__.py +0 -0
  149. pymoo/operators/crossover/binx.py +45 -0
  150. pymoo/operators/crossover/dex.py +122 -0
  151. pymoo/operators/crossover/erx.py +162 -0
  152. pymoo/operators/crossover/expx.py +51 -0
  153. pymoo/operators/crossover/hux.py +37 -0
  154. pymoo/operators/crossover/nox.py +13 -0
  155. pymoo/operators/crossover/ox.py +84 -0
  156. pymoo/operators/crossover/pcx.py +82 -0
  157. pymoo/operators/crossover/pntx.py +49 -0
  158. pymoo/operators/crossover/sbx.py +125 -0
  159. pymoo/operators/crossover/spx.py +5 -0
  160. pymoo/operators/crossover/ux.py +20 -0
  161. pymoo/operators/mutation/__init__.py +0 -0
  162. pymoo/operators/mutation/bitflip.py +17 -0
  163. pymoo/operators/mutation/gauss.py +58 -0
  164. pymoo/operators/mutation/inversion.py +42 -0
  165. pymoo/operators/mutation/nom.py +7 -0
  166. pymoo/operators/mutation/pm.py +94 -0
  167. pymoo/operators/mutation/rm.py +23 -0
  168. pymoo/operators/repair/__init__.py +0 -0
  169. pymoo/operators/repair/bounce_back.py +32 -0
  170. pymoo/operators/repair/bounds_repair.py +95 -0
  171. pymoo/operators/repair/inverse_penalty.py +89 -0
  172. pymoo/operators/repair/rounding.py +18 -0
  173. pymoo/operators/repair/to_bound.py +31 -0
  174. pymoo/operators/repair/vtype.py +11 -0
  175. pymoo/operators/sampling/__init__.py +0 -0
  176. pymoo/operators/sampling/lhs.py +73 -0
  177. pymoo/operators/sampling/rnd.py +50 -0
  178. pymoo/operators/selection/__init__.py +0 -0
  179. pymoo/operators/selection/rnd.py +72 -0
  180. pymoo/operators/selection/tournament.py +76 -0
  181. pymoo/operators/survival/__init__.py +0 -0
  182. pymoo/operators/survival/rank_and_crowding/__init__.py +1 -0
  183. pymoo/operators/survival/rank_and_crowding/classes.py +209 -0
  184. pymoo/operators/survival/rank_and_crowding/metrics.py +208 -0
  185. pymoo/optimize.py +72 -0
  186. pymoo/problems/__init__.py +157 -0
  187. pymoo/problems/dyn.py +47 -0
  188. pymoo/problems/dynamic/__init__.py +0 -0
  189. pymoo/problems/dynamic/cec2015.py +108 -0
  190. pymoo/problems/dynamic/df.py +452 -0
  191. pymoo/problems/dynamic/misc.py +167 -0
  192. pymoo/problems/functional.py +48 -0
  193. pymoo/problems/many/__init__.py +5 -0
  194. pymoo/problems/many/cdtlz.py +159 -0
  195. pymoo/problems/many/dcdtlz.py +88 -0
  196. pymoo/problems/many/dtlz.py +264 -0
  197. pymoo/problems/many/wfg.py +550 -0
  198. pymoo/problems/multi/__init__.py +14 -0
  199. pymoo/problems/multi/bnh.py +34 -0
  200. pymoo/problems/multi/carside.py +48 -0
  201. pymoo/problems/multi/clutch.py +104 -0
  202. pymoo/problems/multi/csi.py +55 -0
  203. pymoo/problems/multi/ctp.py +198 -0
  204. pymoo/problems/multi/dascmop.py +213 -0
  205. pymoo/problems/multi/kursawe.py +25 -0
  206. pymoo/problems/multi/modact.py +68 -0
  207. pymoo/problems/multi/mw.py +400 -0
  208. pymoo/problems/multi/omnitest.py +48 -0
  209. pymoo/problems/multi/osy.py +32 -0
  210. pymoo/problems/multi/srn.py +28 -0
  211. pymoo/problems/multi/sympart.py +94 -0
  212. pymoo/problems/multi/tnk.py +24 -0
  213. pymoo/problems/multi/truss2d.py +83 -0
  214. pymoo/problems/multi/welded_beam.py +41 -0
  215. pymoo/problems/multi/wrm.py +36 -0
  216. pymoo/problems/multi/zdt.py +151 -0
  217. pymoo/problems/multi_to_single.py +22 -0
  218. pymoo/problems/single/__init__.py +12 -0
  219. pymoo/problems/single/ackley.py +24 -0
  220. pymoo/problems/single/cantilevered_beam.py +34 -0
  221. pymoo/problems/single/flowshop_scheduling.py +112 -0
  222. pymoo/problems/single/g.py +874 -0
  223. pymoo/problems/single/griewank.py +18 -0
  224. pymoo/problems/single/himmelblau.py +15 -0
  225. pymoo/problems/single/knapsack.py +48 -0
  226. pymoo/problems/single/mopta08.py +26 -0
  227. pymoo/problems/single/multimodal.py +20 -0
  228. pymoo/problems/single/pressure_vessel.py +30 -0
  229. pymoo/problems/single/rastrigin.py +20 -0
  230. pymoo/problems/single/rosenbrock.py +22 -0
  231. pymoo/problems/single/schwefel.py +18 -0
  232. pymoo/problems/single/simple.py +13 -0
  233. pymoo/problems/single/sphere.py +19 -0
  234. pymoo/problems/single/traveling_salesman.py +79 -0
  235. pymoo/problems/single/zakharov.py +19 -0
  236. pymoo/problems/static.py +14 -0
  237. pymoo/problems/util.py +42 -0
  238. pymoo/problems/zero_to_one.py +27 -0
  239. pymoo/termination/__init__.py +23 -0
  240. pymoo/termination/collection.py +12 -0
  241. pymoo/termination/cv.py +48 -0
  242. pymoo/termination/default.py +45 -0
  243. pymoo/termination/delta.py +64 -0
  244. pymoo/termination/fmin.py +16 -0
  245. pymoo/termination/ftol.py +144 -0
  246. pymoo/termination/indicator.py +49 -0
  247. pymoo/termination/max_eval.py +14 -0
  248. pymoo/termination/max_gen.py +15 -0
  249. pymoo/termination/max_time.py +20 -0
  250. pymoo/termination/robust.py +34 -0
  251. pymoo/termination/xtol.py +33 -0
  252. pymoo/util/__init__.py +0 -0
  253. pymoo/util/archive.py +150 -0
  254. pymoo/util/cache.py +29 -0
  255. pymoo/util/clearing.py +82 -0
  256. pymoo/util/display/__init__.py +0 -0
  257. pymoo/util/display/column.py +52 -0
  258. pymoo/util/display/display.py +34 -0
  259. pymoo/util/display/multi.py +96 -0
  260. pymoo/util/display/output.py +53 -0
  261. pymoo/util/display/progress.py +54 -0
  262. pymoo/util/display/single.py +67 -0
  263. pymoo/util/dominator.py +67 -0
  264. pymoo/util/function_loader.py +129 -0
  265. pymoo/util/hv.py +23 -0
  266. pymoo/util/matlab_engine.py +39 -0
  267. pymoo/util/misc.py +460 -0
  268. pymoo/util/mnn.py +70 -0
  269. pymoo/util/nds/__init__.py +0 -0
  270. pymoo/util/nds/dominance_degree_non_dominated_sort.py +159 -0
  271. pymoo/util/nds/efficient_non_dominated_sort.py +152 -0
  272. pymoo/util/nds/fast_non_dominated_sort.py +70 -0
  273. pymoo/util/nds/naive_non_dominated_sort.py +36 -0
  274. pymoo/util/nds/non_dominated_sorting.py +67 -0
  275. pymoo/util/nds/tree_based_non_dominated_sort.py +133 -0
  276. pymoo/util/normalization.py +312 -0
  277. pymoo/util/optimum.py +42 -0
  278. pymoo/util/plotting.py +177 -0
  279. pymoo/util/pruning_cd.py +89 -0
  280. pymoo/util/randomized_argsort.py +60 -0
  281. pymoo/util/ref_dirs/__init__.py +24 -0
  282. pymoo/util/ref_dirs/construction.py +88 -0
  283. pymoo/util/ref_dirs/das_dennis.py +52 -0
  284. pymoo/util/ref_dirs/energy.py +319 -0
  285. pymoo/util/ref_dirs/energy_layer.py +119 -0
  286. pymoo/util/ref_dirs/genetic_algorithm.py +63 -0
  287. pymoo/util/ref_dirs/incremental.py +68 -0
  288. pymoo/util/ref_dirs/misc.py +128 -0
  289. pymoo/util/ref_dirs/optimizer.py +59 -0
  290. pymoo/util/ref_dirs/performance.py +162 -0
  291. pymoo/util/ref_dirs/reduction.py +85 -0
  292. pymoo/util/ref_dirs/sample_and_map.py +24 -0
  293. pymoo/util/reference_direction.py +260 -0
  294. pymoo/util/remote.py +55 -0
  295. pymoo/util/roulette.py +27 -0
  296. pymoo/util/running_metric.py +128 -0
  297. pymoo/util/sliding_window.py +25 -0
  298. pymoo/util/stochastic_ranking.py +32 -0
  299. pymoo/util/value_functions.py +719 -0
  300. pymoo/util/vectors.py +40 -0
  301. pymoo/util/vf_dominator.py +99 -0
  302. pymoo/vendor/__init__.py +0 -0
  303. pymoo/vendor/cec2018.py +398 -0
  304. pymoo/vendor/gta.py +617 -0
  305. pymoo/vendor/hv.py +267 -0
  306. pymoo/vendor/vendor_cmaes.py +412 -0
  307. pymoo/vendor/vendor_coco.py +81 -0
  308. pymoo/vendor/vendor_scipy.py +232 -0
  309. pymoo/version.py +1 -0
  310. pymoo/visualization/__init__.py +8 -0
  311. pymoo/visualization/fitness_landscape.py +127 -0
  312. pymoo/visualization/heatmap.py +123 -0
  313. pymoo/visualization/pcp.py +120 -0
  314. pymoo/visualization/petal.py +91 -0
  315. pymoo/visualization/radar.py +108 -0
  316. pymoo/visualization/radviz.py +68 -0
  317. pymoo/visualization/scatter.py +150 -0
  318. pymoo/visualization/star_coordinate.py +75 -0
  319. pymoo/visualization/util.py +123 -0
  320. pymoo/visualization/video/__init__.py +0 -0
  321. pymoo/visualization/video/callback_video.py +82 -0
  322. pymoo/visualization/video/one_var_one_obj.py +57 -0
  323. pymoo/visualization/video/two_var_one_obj.py +62 -0
  324. pymoo-0.6.1.5.dev0.dist-info/METADATA +187 -0
  325. pymoo-0.6.1.5.dev0.dist-info/RECORD +330 -0
  326. pymoo-0.6.1.5.dev0.dist-info/WHEEL +5 -0
  327. pymoo-0.6.1.5.dev0.dist-info/licenses/LICENSE +191 -0
  328. pymoo-0.6.1.5.dev0.dist-info/top_level.txt +1 -0
  329. pymoo.libs/libgcc_s-2298274a.so.1 +0 -0
  330. pymoo.libs/libstdc++-08d5c7eb.so.6.0.33 +0 -0
@@ -0,0 +1,144 @@
1
+ import numpy as np
2
+
3
+ from pymoo.indicators.hv import Hypervolume
4
+ from pymoo.indicators.igd import IGD
5
+ from pymoo.util.normalization import normalize
6
+ from pymoo.termination.delta import DeltaToleranceTermination
7
+
8
+
9
+ def calc_delta(a, b):
10
+ return np.max(np.abs((a - b)))
11
+
12
+
13
+ def calc_delta_norm(a, b, norm):
14
+ return np.max(np.abs((a - b) / norm))
15
+
16
+
17
+ class SingleObjectiveSpaceTermination(DeltaToleranceTermination):
18
+
19
+ def __init__(self, tol=1e-6, only_feas=True, **kwargs) -> None:
20
+ super().__init__(tol, **kwargs)
21
+ self.only_feas = only_feas
22
+
23
+ def _delta(self, prev, current):
24
+ if prev == np.inf or current == np.inf:
25
+ return np.inf
26
+ else:
27
+ return max(0, prev - current)
28
+
29
+ def _data(self, algorithm):
30
+ opt = algorithm.opt
31
+ f = opt.get("f")
32
+
33
+ if self.only_feas:
34
+ f = f[opt.get("feas")]
35
+
36
+ if len(f) > 0:
37
+ return f.min()
38
+ else:
39
+ return np.inf
40
+
41
+
42
+ class MultiObjectiveSpaceTermination(DeltaToleranceTermination):
43
+
44
+ def __init__(self, tol=0.0025, only_feas=True, **kwargs):
45
+ super().__init__(tol, **kwargs)
46
+ self.delta_ideal = None
47
+ self.delta_nadir = None
48
+ self.delta_f = None
49
+ self.only_feas = only_feas
50
+
51
+ def _data(self, algorithm):
52
+ feas, F = algorithm.opt.get("feas", "F")
53
+
54
+ if self.only_feas:
55
+ F = F[feas]
56
+
57
+ if len(F) > 0:
58
+ return dict(ideal=F.min(axis=0), nadir=F.max(axis=0), F=F, feas=True)
59
+ else:
60
+ return dict(ideal=None, nadir=None, F=F, feas=False)
61
+
62
+ def _delta(self, prev, current):
63
+
64
+ if not (prev["feas"] and current["feas"]):
65
+ return np.inf
66
+
67
+ # this is the range between the nadir and the ideal point
68
+ norm = current["nadir"] - current["ideal"]
69
+
70
+ # if the range is degenerated (very close to zero) - disable normalization by dividing by one
71
+ norm[norm < 1e-32] = 1.0
72
+
73
+ # calculate the change from last to current in ideal and nadir point
74
+ delta_ideal = calc_delta_norm(current["ideal"], prev["ideal"], norm)
75
+ delta_nadir = calc_delta_norm(current["nadir"], prev["nadir"], norm)
76
+
77
+ # get necessary data from the current population
78
+ c_F, c_ideal, c_nadir = current["F"], current["ideal"], current["nadir"]
79
+ p_F = prev["F"]
80
+
81
+ # normalize last and current with respect to most recent ideal and nadir
82
+ c_N = normalize(c_F, c_ideal, c_nadir)
83
+ p_N = normalize(p_F, c_ideal, c_nadir)
84
+
85
+ # calculate IGD from one to another
86
+ delta_f = IGD(c_N).do(p_N)
87
+
88
+ # store the delta values to the object
89
+ self.delta_ideal, self.delta_nadir, self.delta_f = delta_ideal, delta_nadir, delta_f
90
+
91
+ return max(delta_ideal, delta_nadir, delta_f)
92
+
93
+
94
+ class MultiObjectiveSpaceTerminationWithRenormalization(MultiObjectiveSpaceTermination):
95
+
96
+ def __init__(self,
97
+ n=30,
98
+ all_to_current=False,
99
+ sliding_window=True,
100
+ indicator="igd",
101
+ **kwargs) -> None:
102
+
103
+ super().__init__(**kwargs)
104
+ self.n = n
105
+ self.all_to_current = all_to_current
106
+ self.sliding_window = sliding_window
107
+ self.indicator = indicator
108
+
109
+ self.data = []
110
+
111
+ def _metric(self, data):
112
+ ret = super()._metric(data)
113
+
114
+ if not self.sliding_window:
115
+ data = self.data[-self.metric_window_size:]
116
+
117
+ # get necessary data from the current population
118
+ current = data[-1]
119
+ c_F, c_ideal, c_nadir = current["F"], current["ideal"], current["nadir"]
120
+
121
+ # normalize all previous generations with respect to current ideal and nadir
122
+ N = [normalize(e["F"], c_ideal, c_nadir) for e in data]
123
+
124
+ # check if the movement of all points is significant
125
+ if self.all_to_current:
126
+
127
+ c_N = normalize(c_F, c_ideal, c_nadir)
128
+ if self.indicator == "igd":
129
+ delta_f = [IGD(c_N).do(N[k]) for k in range(len(N))]
130
+ elif self.indicator == "hv":
131
+ hv = Hypervolume(ref_point=np.ones(c_F.shape[1]))
132
+ delta_f = [hv.do(N[k]) for k in range(len(N))]
133
+ else:
134
+ delta_f = [IGD(N[k + 1]).do(N[k]) for k in range(len(N) - 1)]
135
+
136
+ ret["delta_f"] = delta_f
137
+
138
+ return ret
139
+
140
+ def _decide(self, metrics):
141
+ delta_ideal = [e["delta_ideal"] for e in metrics]
142
+ delta_nadir = [e["delta_nadir"] for e in metrics]
143
+ delta_f = [max(e["delta_f"]) for e in metrics]
144
+ return max(max(delta_ideal), max(delta_nadir), max(delta_f)) > self.tol
@@ -0,0 +1,49 @@
1
+ from math import log
2
+
3
+ from pymoo.core.termination import Termination
4
+
5
+
6
+ class IndicatorTermination(Termination):
7
+
8
+ def __init__(self, indicator, threshold, goal, **kwargs) -> None:
9
+ super().__init__()
10
+
11
+ # the indicator to be used
12
+ self.indicator = indicator
13
+
14
+ # define the threshold for termination
15
+ self.threshold = threshold
16
+
17
+ # what is the optimization goal for this indicator
18
+ self.goal = goal
19
+ assert goal in ["minimize", "maximize"]
20
+
21
+ # optional parameters when the indicator calculation is performed
22
+ self.kwargs = kwargs
23
+
24
+ # initial the minimum and maximum values of the indicator
25
+ self._min = float("inf")
26
+ self._max = -float("inf")
27
+
28
+ def _update(self, algorithm):
29
+
30
+ # get the objective space values
31
+ F = algorithm.opt.get("F")
32
+
33
+ # get the resulting value from the indicator
34
+ v = self.indicator.do(F, **self.kwargs)
35
+
36
+ threshold = self.threshold
37
+
38
+ # update the minimum and maximum boundary ranges
39
+ self._min = min(self._min, v)
40
+ self._max = max(self._max, v)
41
+ _min, _max = self._min, self._max
42
+
43
+ # depending on the goal either set the percentage
44
+ if self.goal == "minimize":
45
+ perc = 1 - (v - threshold) / (_max - threshold)
46
+ else:
47
+ perc = (v - _min) / (threshold - _min)
48
+
49
+ return perc
@@ -0,0 +1,14 @@
1
+ from pymoo.core.termination import Termination
2
+
3
+
4
+ class MaximumFunctionCallTermination(Termination):
5
+
6
+ def __init__(self, n_max_evals=float("inf")) -> None:
7
+ super().__init__()
8
+ self.n_max_evals = n_max_evals
9
+
10
+ def _update(self, algorithm):
11
+ if self.n_max_evals is None:
12
+ return 0.0
13
+ else:
14
+ return algorithm.evaluator.n_eval / self.n_max_evals
@@ -0,0 +1,15 @@
1
+ from pymoo.core.termination import Termination
2
+
3
+
4
+ class MaximumGenerationTermination(Termination):
5
+
6
+ def __init__(self, n_max_gen=float("inf")) -> None:
7
+ super().__init__()
8
+ self.n_max_gen = n_max_gen
9
+
10
+ def _update(self, algorithm):
11
+ if self.n_max_gen is None:
12
+ return 0.0
13
+ else:
14
+ return algorithm.n_gen / self.n_max_gen
15
+
@@ -0,0 +1,20 @@
1
+ import time
2
+
3
+ from pymoo.core.termination import Termination
4
+ from pymoo.util.misc import time_to_int
5
+
6
+
7
+ class TimeBasedTermination(Termination):
8
+
9
+ def __init__(self, max_time) -> None:
10
+ super().__init__()
11
+ if isinstance(max_time, str):
12
+ self.max_time = time_to_int(max_time)
13
+ elif isinstance(max_time, int) or isinstance(max_time, float):
14
+ self.max_time = max_time
15
+ else:
16
+ raise Exception("Either provide the time as a string or an integer.")
17
+
18
+ def _update(self, algorithm):
19
+ elapsed = time.time() - algorithm.start_time
20
+ return elapsed / self.max_time
@@ -0,0 +1,34 @@
1
+ from pymoo.core.termination import Termination
2
+ from pymoo.util.sliding_window import SlidingWindow
3
+
4
+
5
+ class RobustTermination(Termination):
6
+
7
+ def __init__(self,
8
+ termination,
9
+ period=30,
10
+ ) -> None:
11
+ """
12
+
13
+ Parameters
14
+ ----------
15
+
16
+ termination : Termination
17
+ The termination criterion that shall become robust
18
+
19
+ period : int
20
+ The number of last generations to be considered for termination.
21
+
22
+ """
23
+ super().__init__()
24
+
25
+ # create a collection in case number of max generation or evaluations is used
26
+ self.termination = termination
27
+
28
+ # the history calculated also in a sliding window
29
+ self.history = SlidingWindow(period)
30
+
31
+ def _update(self, algorithm):
32
+ perc = self.termination.update(algorithm)
33
+ self.history.append(perc)
34
+ return min(self.history)
@@ -0,0 +1,33 @@
1
+ import numpy as np
2
+
3
+ from pymoo.indicators.igd import IGD
4
+ from pymoo.termination.delta import DeltaToleranceTermination
5
+ from pymoo.util.normalization import normalize
6
+
7
+
8
+
9
+ class DesignSpaceTermination(DeltaToleranceTermination):
10
+
11
+ def __init__(self, tol=0.005, **kwargs):
12
+ """
13
+ Check the distance in the design-space and terminate based on tolerance.
14
+ (only works if variables can be converted to float)
15
+ """
16
+ super().__init__(tol, **kwargs)
17
+
18
+ def _delta(self, prev, current):
19
+ try:
20
+ return IGD(current.astype(float)).do(prev.astype(float))
21
+ except:
22
+ return np.inf
23
+
24
+ def _data(self, algorithm):
25
+
26
+ X = algorithm.opt.get("X")
27
+
28
+ # do normalization if bounds are given
29
+ problem = algorithm.problem
30
+ if X.dtype != object and problem.has_bounds():
31
+ X = normalize(X, xl=problem.xl, xu=problem.xu)
32
+
33
+ return X
pymoo/util/__init__.py ADDED
File without changes
pymoo/util/archive.py ADDED
@@ -0,0 +1,150 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.duplicate import DefaultDuplicateElimination
4
+ from pymoo.core.population import Population, merge
5
+ from pymoo.util.nds.non_dominated_sorting import NonDominatedSorting
6
+
7
+
8
+ class Truncation:
9
+
10
+ def __call__(self, sols, k):
11
+ pass
12
+
13
+
14
+ class RandomTruncation(Truncation):
15
+
16
+ def __call__(self, sols, k):
17
+ return np.random.choice(sols, size=k, replace=False)
18
+
19
+
20
+ class SurvivalTruncation(Truncation):
21
+
22
+ def __init__(self, survival, problem=None) -> None:
23
+ super().__init__()
24
+ self.survival = survival
25
+
26
+ if problem is None:
27
+ from pymoo.core.problem import Problem
28
+ problem = Problem()
29
+
30
+ self.problem = problem
31
+
32
+ def __call__(self, sols, k):
33
+ return self.survival.do(self.problem, sols, n_survive=k)
34
+
35
+
36
+ class Archive(Population):
37
+
38
+ def __new__(cls,
39
+ individuals=[],
40
+ max_size=None,
41
+ truncate_size=None,
42
+ truncation=RandomTruncation(),
43
+ duplicate_elimination=DefaultDuplicateElimination(epsilon=1e-32)):
44
+
45
+ obj = super().__new__(cls, individuals)
46
+ obj.max_size = max_size
47
+ obj.truncate_size = min(max_size, truncate_size) if truncate_size is not None else max_size
48
+ obj.truncation = truncation
49
+ obj.duplicate_elimination = duplicate_elimination
50
+
51
+ return obj
52
+
53
+ def __array_finalize__(self, obj):
54
+ if obj is None: # __new__ handles instantiation
55
+ return
56
+
57
+ max_size = getattr(obj, 'max_size', None)
58
+ truncate_size = getattr(obj, 'truncate_size', None)
59
+ truncation = getattr(obj, 'truncation', RandomTruncation())
60
+ duplicate_elimination = getattr(obj, 'duplicate_elimination', DefaultDuplicateElimination(epsilon=1e-32))
61
+
62
+ self.max_size = max_size
63
+ self.truncate_size = min(max_size, truncate_size) if truncate_size is not None else max_size
64
+ self.truncation = truncation
65
+ self.duplicate_elimination = duplicate_elimination
66
+
67
+ def add(self, sols):
68
+
69
+ if len(self) > 0:
70
+ sols = merge(self, sols)
71
+
72
+ opt = self._find_opt(sols)
73
+
74
+ if self.duplicate_elimination:
75
+ opt = self.duplicate_elimination.do(opt)
76
+
77
+ if self.max_size and len(opt) > self.max_size:
78
+ opt = self.truncation(opt, self.truncate_size)
79
+
80
+ cls = self.__class__
81
+ obj = cls.__new__(cls, individuals=opt, **self.view(Archive).__dict__)
82
+ return obj
83
+
84
+ def _find_opt(self, sols):
85
+ pass
86
+
87
+
88
+ class VoidArchive(Archive):
89
+
90
+ def add(self, sols):
91
+ return self
92
+
93
+
94
+ class SingleObjectiveArchive(Archive):
95
+
96
+ def __new__(cls, max_size=10, **kwargs):
97
+ return super().__new__(cls, max_size=max_size, **kwargs).view(cls)
98
+
99
+ def _find_opt(self, sols):
100
+ feas = sols.get("feas")
101
+
102
+ if np.any(feas):
103
+ sols = sols[feas]
104
+
105
+ f = sols.get("f")
106
+ I, = np.where(f == f[f.argmin()])
107
+
108
+ else:
109
+ cv = sols.get("cv")
110
+ I, = np.where(cv == cv[cv.argmin()])
111
+
112
+ return sols[I]
113
+
114
+
115
+ class MultiObjectiveArchive(Archive):
116
+
117
+ def __new__(cls, max_size=200, truncate_size=100, **kwargs):
118
+ return super().__new__(cls,
119
+ max_size=max_size,
120
+ truncate_size=truncate_size,
121
+ **kwargs)
122
+
123
+ def _find_opt(self, sols):
124
+ feas = sols.get("feas")
125
+
126
+ if np.any(feas):
127
+ sols = sols[feas]
128
+
129
+ F = sols.get("F")
130
+ I = NonDominatedSorting().do(F, only_non_dominated_front=True)
131
+ else:
132
+ cv = sols.get("cv")
133
+ I, = np.where(cv == cv[cv.argmin()])
134
+
135
+ return sols[I]
136
+
137
+
138
+ def default_archive(problem, **kwargs):
139
+ if problem.n_obj == 1:
140
+ return SingleObjectiveArchive(**kwargs)
141
+
142
+ elif problem.n_obj == 2:
143
+ from pymoo.algorithms.moo.sms import LeastHypervolumeContributionSurvival
144
+ survival = LeastHypervolumeContributionSurvival()
145
+ return MultiObjectiveArchive(truncation=SurvivalTruncation(survival, problem=problem), **kwargs)
146
+
147
+ elif problem.n_obj >= 3:
148
+ from pymoo.algorithms.moo.spea2 import SPEA2Survival
149
+ survival = SPEA2Survival()
150
+ return MultiObjectiveArchive(truncation=SurvivalTruncation(survival, problem=problem), **kwargs)
pymoo/util/cache.py ADDED
@@ -0,0 +1,29 @@
1
+ def Cache(func):
2
+ """
3
+
4
+ This is a function decorator for class attributes. It just remembers the result of the FIRST function call
5
+ and returns this from there on. Other cashes like LRU are difficult to use because the input can be unhashable
6
+ or bigger numpy arrays. Thus the user has to choose how to use this cache.
7
+ """
8
+
9
+ func_name = func.__name__
10
+
11
+ def wrapper(self, *args, use_cache=True, set_cache=True, **kwargs):
12
+
13
+ if "cache" not in self.__dict__:
14
+ self.__dict__["cache"] = {}
15
+
16
+ cache = self.__dict__["cache"]
17
+
18
+ if use_cache and func_name in cache:
19
+ return cache[func_name]
20
+ else:
21
+
22
+ obj = func(self, *args, **kwargs)
23
+
24
+ if set_cache:
25
+ cache[func_name] = obj
26
+
27
+ return obj
28
+
29
+ return wrapper
pymoo/util/clearing.py ADDED
@@ -0,0 +1,82 @@
1
+ import numpy as np
2
+
3
+
4
+ def func_select_by_objective(pop):
5
+ F = pop.get("F")
6
+ return F[:, 0].argmin()
7
+
8
+
9
+ def func_select_from_sorted(_):
10
+ return 0
11
+
12
+
13
+ def select_by_clearing(pop, D, n_select, func_select, delta=0.05):
14
+ clearing = EpsilonClearing(D, delta)
15
+
16
+ while len(clearing.selected()) < n_select:
17
+ remaining = clearing.remaining()
18
+
19
+ if len(remaining) == 0:
20
+ clearing.reset()
21
+ remaining = clearing.remaining()
22
+
23
+ best = remaining[func_select(pop[remaining])]
24
+ clearing.select(best)
25
+
26
+ S = clearing.selected()
27
+ return S
28
+
29
+
30
+ class EpsilonClearing:
31
+
32
+ def __init__(self,
33
+ D,
34
+ epsilon) -> None:
35
+
36
+ super().__init__()
37
+
38
+ if isinstance(D, tuple):
39
+ self.n, self.D = D
40
+ else:
41
+ self.D = D
42
+ self.n = len(D)
43
+
44
+ self.epsilon = epsilon
45
+
46
+ self.S = []
47
+ self.C = np.full(self.n, False)
48
+
49
+ def remaining(self):
50
+ return np.where(~self.C)[0]
51
+
52
+ def has_remaining(self):
53
+ return self.C.sum() != self.n
54
+
55
+ def cleared(self):
56
+ return self.C
57
+
58
+ def selected(self):
59
+ return self.S
60
+
61
+ def reset(self):
62
+ self.C = np.full(self.n, False)
63
+ self.C[self.S] = True
64
+
65
+ def select(self, k):
66
+ self.S.append(k)
67
+ self.C[k] = True
68
+
69
+ if callable(self.D):
70
+ dist_to_other = self.D(k)
71
+ else:
72
+ dist_to_other = self.D[k]
73
+
74
+ less_than_epsilon = dist_to_other < self.epsilon
75
+
76
+ # problems which are currently not cleared and are supposed to
77
+ cleared = np.where(np.logical_and(~self.C, less_than_epsilon))[0]
78
+
79
+ # set them to be cleared
80
+ self.C[cleared] = True
81
+
82
+ return cleared
File without changes
@@ -0,0 +1,52 @@
1
+ import numpy as np
2
+
3
+
4
+ class Column:
5
+
6
+ def __init__(self, name, width=13, func=None, truncate=True) -> None:
7
+ super().__init__()
8
+ self.name = name
9
+ self.func = func
10
+ self.width = width
11
+ self.truncate = truncate
12
+ self.value = None
13
+
14
+ def update(self, algorithm):
15
+ if self.func:
16
+ self.value = self.func(algorithm)
17
+
18
+ def header(self):
19
+ return str(self.name).center(self.width)
20
+
21
+ def text(self):
22
+ value = self.value
23
+ if value is None:
24
+ value = "-"
25
+
26
+ return format_text(value, self.width, self.truncate)
27
+
28
+ def set(self, value):
29
+ self.value = value
30
+
31
+
32
+ def number_to_text(number, width):
33
+ if number >= 10 or number * 1e5 < 1:
34
+ return f"%.{width - 7}E" % number
35
+ else:
36
+ return f"%.{width - 3}f" % number
37
+
38
+
39
+ def format_text(value, width, truncate):
40
+ if value is not None:
41
+
42
+ if isinstance(value, (np.floating, float)):
43
+ text = number_to_text(value, width)
44
+ else:
45
+ text = str(value)
46
+
47
+ if truncate and len(text) > width:
48
+ text = text[:width]
49
+ else:
50
+ text = "-"
51
+ text = text.rjust(width)
52
+ return text
@@ -0,0 +1,34 @@
1
+ from pymoo.core.callback import Callback
2
+ from pymoo.util.display.progress import ProgressBar
3
+
4
+
5
+ class Display(Callback):
6
+
7
+ def __init__(self, output=None, progress=False, verbose=False):
8
+ super().__init__()
9
+ self.output = output
10
+ self.verbose = verbose
11
+ self.progress = ProgressBar() if progress else None
12
+
13
+ def update(self, algorithm, **kwargs):
14
+ output, progress = self.output, self.progress
15
+
16
+ if self.verbose and output:
17
+ text = ""
18
+ header = not output.is_initialized
19
+ output(algorithm)
20
+
21
+ if header:
22
+ text += output.header(border=True) + '\n'
23
+ text += output.text()
24
+
25
+ print(text)
26
+
27
+ if progress:
28
+ perc = algorithm.termination.perc
29
+ progress.set(perc)
30
+
31
+ def finalize(self):
32
+
33
+ if self.progress:
34
+ self.progress.close()