pymoo 0.6.1.5.dev0__cp311-cp311-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-311-x86_64-linux-musl.so +0 -0
  91. pymoo/cython/calc_perpendicular_distance.pyx +67 -0
  92. pymoo/cython/decomposition.cpython-311-x86_64-linux-musl.so +0 -0
  93. pymoo/cython/decomposition.pyx +165 -0
  94. pymoo/cython/hv.cpython-311-x86_64-linux-musl.so +0 -0
  95. pymoo/cython/hv.pyx +18 -0
  96. pymoo/cython/info.cpython-311-x86_64-linux-musl.so +0 -0
  97. pymoo/cython/info.pyx +5 -0
  98. pymoo/cython/mnn.cpython-311-x86_64-linux-musl.so +0 -0
  99. pymoo/cython/mnn.pyx +273 -0
  100. pymoo/cython/non_dominated_sorting.cpython-311-x86_64-linux-musl.so +0 -0
  101. pymoo/cython/non_dominated_sorting.pyx +645 -0
  102. pymoo/cython/pruning_cd.cpython-311-x86_64-linux-musl.so +0 -0
  103. pymoo/cython/pruning_cd.pyx +197 -0
  104. pymoo/cython/stochastic_ranking.cpython-311-x86_64-linux-musl.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,260 @@
1
+ import sys
2
+
3
+ import numpy as np
4
+ from scipy import special
5
+
6
+ from pymoo.util.misc import find_duplicates, cdist
7
+
8
+
9
+ # =========================================================================================================
10
+ # Model
11
+ # =========================================================================================================
12
+
13
+
14
+ def default_ref_dirs(m):
15
+ if m == 1:
16
+ return np.array([[1.0]])
17
+ elif m == 2:
18
+ return UniformReferenceDirectionFactory(m, n_partitions=99).do()
19
+ elif m == 3:
20
+ return UniformReferenceDirectionFactory(m, n_partitions=12).do()
21
+ else:
22
+ raise Exception("No default reference directions for more than 3 objectives. Please provide them directly:"
23
+ "https://pymoo.org/misc/reference_directions.html")
24
+
25
+
26
+ class ReferenceDirectionFactory:
27
+
28
+ def __init__(self, n_dim, scaling=None, lexsort=True, verbose=False, seed=None, **kwargs) -> None:
29
+ super().__init__()
30
+ self.n_dim = n_dim
31
+ self.scaling = scaling
32
+ self.lexsort = lexsort
33
+ self.verbose = verbose
34
+ self.seed = seed
35
+
36
+ def __call__(self):
37
+ return self.do()
38
+
39
+ def do(self):
40
+
41
+ # set the random seed if it is provided
42
+ if self.seed is not None:
43
+ np.random.seed(self.seed)
44
+
45
+ if self.n_dim == 1:
46
+ return np.array([[1.0]])
47
+ else:
48
+
49
+ val = self._do()
50
+ if isinstance(val, tuple):
51
+ ref_dirs, other = val[0], val[1:]
52
+ else:
53
+ ref_dirs = val
54
+
55
+ if self.scaling is not None:
56
+ ref_dirs = scale_reference_directions(ref_dirs, self.scaling)
57
+
58
+ # do ref_dirs is desired
59
+ if self.lexsort:
60
+ I = np.lexsort([ref_dirs[:, j] for j in range(ref_dirs.shape[1])][::-1])
61
+ ref_dirs = ref_dirs[I]
62
+
63
+ return ref_dirs
64
+
65
+ def _do(self):
66
+ return None
67
+
68
+
69
+ # =========================================================================================================
70
+ # Das Dennis Reference Directions (Uniform)
71
+ # =========================================================================================================
72
+
73
+
74
+ def get_number_of_uniform_points(n_partitions, n_dim):
75
+ """
76
+ Returns the number of uniform points that can be created uniformly.
77
+ """
78
+ return int(special.binom(n_dim + n_partitions - 1, n_partitions))
79
+
80
+
81
+ def get_partition_closest_to_points(n_points, n_dim):
82
+ """
83
+ Returns the corresponding partition number which create the desired number of points
84
+ or less!
85
+ """
86
+
87
+ if n_dim == 1:
88
+ return 0
89
+
90
+ n_partitions = 1
91
+ _n_points = get_number_of_uniform_points(n_partitions, n_dim)
92
+ while _n_points <= n_points:
93
+ n_partitions += 1
94
+ _n_points = get_number_of_uniform_points(n_partitions, n_dim)
95
+ return n_partitions - 1
96
+
97
+
98
+ def das_dennis(n_partitions, n_dim):
99
+ if n_partitions == 0:
100
+ return np.full((1, n_dim), 1 / n_dim)
101
+ else:
102
+ ref_dirs = []
103
+ ref_dir = np.full(n_dim, np.nan)
104
+ das_dennis_recursion(ref_dirs, ref_dir, n_partitions, n_partitions, 0)
105
+ return np.concatenate(ref_dirs, axis=0)
106
+
107
+
108
+ def das_dennis_recursion(ref_dirs, ref_dir, n_partitions, beta, depth):
109
+ if depth == len(ref_dir) - 1:
110
+ ref_dir[depth] = beta / (1.0 * n_partitions)
111
+ ref_dirs.append(ref_dir[None, :])
112
+ else:
113
+ for i in range(beta + 1):
114
+ ref_dir[depth] = 1.0 * i / (1.0 * n_partitions)
115
+ das_dennis_recursion(ref_dirs, np.copy(ref_dir), n_partitions, beta - i, depth + 1)
116
+
117
+
118
+ class UniformReferenceDirectionFactory(ReferenceDirectionFactory):
119
+
120
+ def __init__(self, n_dim, scaling=None, n_points=None, n_partitions=None, **kwargs) -> None:
121
+ super().__init__(n_dim, scaling=scaling, **kwargs)
122
+
123
+ if n_points is not None:
124
+ n_partitions = get_partition_closest_to_points(n_points, n_dim)
125
+ results_in = get_number_of_uniform_points(n_partitions, n_dim)
126
+
127
+ # the number of points are not matching to any partition number
128
+ if results_in != n_points:
129
+ results_in_next = get_number_of_uniform_points(n_partitions + 1, n_dim)
130
+ raise Exception("The number of points (n_points = %s) can not be created uniformly.\n"
131
+ "Either choose n_points = %s (n_partitions = %s) or "
132
+ "n_points = %s (n_partitions = %s)." %
133
+ (n_points, results_in, n_partitions, results_in_next, n_partitions + 1))
134
+
135
+ self.n_partitions = n_partitions
136
+
137
+ elif n_partitions is not None:
138
+ self.n_partitions = n_partitions
139
+
140
+ else:
141
+ raise Exception("Either provide number of partitions or number of points.")
142
+
143
+ def _do(self):
144
+ return das_dennis(self.n_partitions, self.n_dim)
145
+
146
+
147
+ # =========================================================================================================
148
+ # Multi Layer
149
+ # =========================================================================================================
150
+
151
+
152
+ class MultiLayerReferenceDirectionFactory:
153
+
154
+ def __init__(self, *args) -> None:
155
+ self.layers = []
156
+ self.layers.extend(args)
157
+
158
+ def __call__(self):
159
+ return self.do()
160
+
161
+ def add_layer(self, *args):
162
+ self.layers.extend(args)
163
+
164
+ def do(self):
165
+ ref_dirs = []
166
+ for factory in self.layers:
167
+ ref_dirs.append(factory)
168
+ ref_dirs = np.concatenate(ref_dirs, axis=0)
169
+ is_duplicate = find_duplicates(ref_dirs)
170
+ return ref_dirs[np.logical_not(is_duplicate)]
171
+
172
+
173
+ # =========================================================================================================
174
+ # Util
175
+ # =========================================================================================================
176
+
177
+ def get_rng(seed=None):
178
+ if seed is None or type(seed) == int:
179
+ rng = np.random.default_rng(seed)
180
+ return rng
181
+
182
+
183
+ def sample_on_unit_simplex(n_points, n_dim, unit_simplex_mapping="kraemer", seed=None):
184
+ if unit_simplex_mapping == "sum":
185
+ rnd = map_onto_unit_simplex(get_rng(seed).random((n_points, n_dim)), "sum")
186
+
187
+ elif unit_simplex_mapping == "kraemer":
188
+ rnd = map_onto_unit_simplex(get_rng(seed).random((n_points, n_dim)), "kraemer")
189
+
190
+ elif unit_simplex_mapping == "das-dennis":
191
+ n_partitions = get_partition_closest_to_points(n_points, n_dim)
192
+ rnd = UniformReferenceDirectionFactory(n_dim, n_partitions=n_partitions).do()
193
+
194
+ else:
195
+ raise Exception("Please define a valid sampling on unit simplex strategy!")
196
+
197
+ return rnd
198
+
199
+
200
+ def map_onto_unit_simplex(rnd, method):
201
+ n_points, n_dim = rnd.shape
202
+
203
+ if method == "sum":
204
+ ret = rnd / rnd.sum(axis=1)[:, None]
205
+
206
+ elif method == "kraemer":
207
+ M = sys.maxsize
208
+
209
+ rnd *= M
210
+ rnd = rnd[:, :n_dim - 1]
211
+ rnd = np.column_stack([np.zeros(n_points), rnd, np.full(n_points, M)])
212
+
213
+ rnd = np.sort(rnd, axis=1)
214
+
215
+ ret = np.full((n_points, n_dim), np.nan)
216
+ for i in range(1, n_dim + 1):
217
+ ret[:, i - 1] = rnd[:, i] - rnd[:, i - 1]
218
+ ret /= M
219
+
220
+ else:
221
+ raise Exception("Invalid unit simplex mapping!")
222
+
223
+ return ret
224
+
225
+
226
+ def scale_reference_directions(ref_dirs, scaling):
227
+ return ref_dirs * scaling + ((1 - scaling) / ref_dirs.shape[1])
228
+
229
+
230
+ def select_points_with_maximum_distance(X, n_select, selected=[]):
231
+ n_points, n_dim = X.shape
232
+
233
+ # calculate the distance matrix
234
+ D = cdist(X, X)
235
+
236
+ # if no selection provided pick randomly in the beginning
237
+ if len(selected) == 0:
238
+ selected = [np.random.randint(len(X))]
239
+
240
+ # create variables to store what selected and what not
241
+ not_selected = [i for i in range(n_points) if i not in selected]
242
+
243
+ # remove unnecessary points
244
+ dist_to_closest_selected = D[:, selected].min(axis=1)
245
+
246
+ # now select the points until sufficient ones are found
247
+ while len(selected) < n_select:
248
+ # find point that has the maximum distance to all others
249
+ index_in_not_selected = dist_to_closest_selected[not_selected].argmax()
250
+ I = not_selected[index_in_not_selected]
251
+
252
+ # add the closest distance to selected point
253
+ is_closer = D[I] < dist_to_closest_selected
254
+ dist_to_closest_selected[is_closer] = D[I][is_closer]
255
+
256
+ # add it to the selected and remove from not selected
257
+ selected.append(I)
258
+ not_selected = np.delete(not_selected, index_in_not_selected)
259
+
260
+ return selected
pymoo/util/remote.py ADDED
@@ -0,0 +1,55 @@
1
+ import json
2
+ import os
3
+ import urllib.request
4
+ from os.path import join, dirname, abspath
5
+
6
+ import numpy as np
7
+
8
+ from pymoo.config import Config
9
+
10
+
11
+ class Remote:
12
+ # -------------------------------------------------
13
+ # Singleton Pattern
14
+ # -------------------------------------------------
15
+ __instance = None
16
+
17
+ @staticmethod
18
+ def get_instance():
19
+ if Remote.__instance is None:
20
+ server = Config.data()
21
+ folder = join(dirname(dirname(abspath(__file__))), 'data')
22
+ Remote.__instance = Remote(server, folder)
23
+ return Remote.__instance
24
+
25
+ # -------------------------------------------------
26
+
27
+ def __init__(self, server, folder=None) -> None:
28
+ super().__init__()
29
+ self.server = server
30
+ self.folder = folder
31
+
32
+ def load(self, *args, to="numpy"):
33
+
34
+ # the local file we can try loading
35
+ f = join(str(self.folder), *args)
36
+
37
+ # check if that path already exists
38
+ if not os.path.exists(f):
39
+
40
+ # if not make sure to create it that the file can be written
41
+ folder = dirname(f)
42
+ if not os.path.exists(folder):
43
+ os.makedirs(folder)
44
+
45
+ # create the url to load it from and download the file remotely
46
+ url = self.server + "/".join(args)
47
+ urllib.request.urlretrieve(url, f)
48
+
49
+ if to == "numpy":
50
+ return np.loadtxt(f)
51
+ elif to == "json":
52
+ with open(f) as file:
53
+ return json.load(file)
54
+
55
+ return f
pymoo/util/roulette.py ADDED
@@ -0,0 +1,27 @@
1
+ import numpy as np
2
+
3
+
4
+ class RouletteWheelSelection:
5
+
6
+ def __init__(self, val, larger_is_better=True):
7
+ super().__init__()
8
+ if not larger_is_better:
9
+ val = val.max() - val
10
+ _sum = val.sum()
11
+ self.cumulative = np.array([val[:k].sum() / _sum for k in range(1, len(val))])
12
+
13
+ def next(self, n=None):
14
+ if n is None:
15
+ X = np.random.random((1, 1))
16
+ else:
17
+ X = np.random.random((n, 1))
18
+ if n > 1:
19
+ X.repeat(n - 1, axis=1)
20
+
21
+ M = self.cumulative[None, :].repeat(len(X), axis=0)
22
+ B = X >= M
23
+ ret = B.sum(axis=1)
24
+
25
+ if n is None:
26
+ return ret[0]
27
+ return ret
@@ -0,0 +1,128 @@
1
+ import matplotlib.pyplot as plt
2
+ import numpy as np
3
+
4
+ from pymoo.core.callback import Callback
5
+ from pymoo.indicators.hv import Hypervolume
6
+ from pymoo.indicators.igd import IGD
7
+ from pymoo.termination.ftol import calc_delta_norm
8
+ from pymoo.util.normalization import normalize
9
+ from pymoo.util.sliding_window import SlidingWindow
10
+ from pymoo.visualization.video.callback_video import AnimationCallback
11
+
12
+
13
+ class RunningMetric(Callback):
14
+
15
+ def __init__(self,
16
+ period=None,
17
+ indicator="igd") -> None:
18
+
19
+ super().__init__()
20
+ self.indicator = indicator
21
+
22
+ self.delta_ideal = None
23
+ self.delta_nadir = None
24
+ self.delta_f = None
25
+
26
+ self.history = SlidingWindow(period)
27
+
28
+ def update(self, algorithm):
29
+ history = self.history
30
+
31
+ F = algorithm.opt.get("F")
32
+ c_F, c_ideal, c_nadir = F, F.min(axis=0), F.max(axis=0)
33
+
34
+ # find the normalization constant to divide by
35
+ norm = c_nadir - c_ideal
36
+
37
+ # make sure all dimensions in ideal are strictly lower than in nadir
38
+ c_nadir[c_ideal == c_nadir] += 1e-16
39
+ norm[c_ideal == c_nadir] = 1.0
40
+
41
+ # append the current optimum to the history
42
+ history.append(dict(F=F, ideal=c_ideal, nadir=c_nadir))
43
+
44
+ # normalize the current objective space values (use the utopian if equal)
45
+ c_N = normalize(c_F, c_ideal, c_nadir)
46
+
47
+ # normalize all previous generations with respect to current ideal and nadir
48
+ N = [normalize(e["F"], c_ideal, c_nadir) for e in history]
49
+
50
+ # calculate the delta difference for each previous ideal and nadir point to current
51
+ delta_ideal = [calc_delta_norm(history[k]["ideal"], history[k - 1]["ideal"], norm) for k in
52
+ range(1, len(history))] + [0.0]
53
+ delta_nadir = [calc_delta_norm(history[k]["nadir"], history[k - 1]["nadir"], norm) for k in
54
+ range(1, len(history))] + [0.0]
55
+
56
+ # now calculate the indicator from each previous one to the current
57
+ if self.indicator == "igd":
58
+ delta_f = [IGD(c_N).do(N[k]) for k in range(len(N))]
59
+ elif self.indicator == "hv":
60
+ hv = Hypervolume(ref_point=np.ones(c_F.shape[1]))
61
+ delta_f = [hv.do(N[k]) for k in range(len(N))]
62
+ else:
63
+ raise Exception("Unknown indicator.")
64
+
65
+ self.delta_ideal, self.delta_nadir, self.delta_f = delta_ideal, delta_nadir, delta_f
66
+
67
+
68
+ class RunningMetricAnimation(AnimationCallback):
69
+
70
+ def __init__(self,
71
+ delta_gen,
72
+ n_plots=4,
73
+ key_press=True,
74
+ **kwargs) -> None:
75
+
76
+ super().__init__(**kwargs)
77
+ self.running = RunningMetric()
78
+ self.delta_gen = delta_gen
79
+ self.key_press = key_press
80
+ self.data = SlidingWindow(n_plots)
81
+
82
+ def draw(self, data, ax):
83
+
84
+ for tau, x, f, v in data[:-1]:
85
+ ax.plot(x, f, label="t=%s" % tau, alpha=0.6, linewidth=3)
86
+
87
+ tau, x, f, v = data[-1]
88
+ ax.plot(x, f, label="t=%s (*)" % tau, alpha=0.9, linewidth=3)
89
+
90
+ for k in range(len(v)):
91
+ if v[k]:
92
+ ax.plot([k + 1, k + 1], [0, f[k]], color="black", linewidth=0.5, alpha=0.5)
93
+ ax.plot([k + 1], [f[k]], "o", color="black", alpha=0.5, markersize=2)
94
+
95
+ ax.set_yscale("symlog")
96
+ ax.legend()
97
+
98
+ ax.set_xlabel("Generation")
99
+ ax.set_ylabel("$\Delta \, f$", rotation=0)
100
+
101
+ def do(self, _, algorithm, force_plot=False, **kwargs):
102
+ running = self.running
103
+
104
+ # update the running metric to have the most recent information
105
+ running.update(algorithm)
106
+
107
+ tau = algorithm.n_gen
108
+
109
+ if (tau > 0 and tau % self.delta_gen == 0) or force_plot:
110
+
111
+ f = running.delta_f
112
+ x = np.arange(len(f)) + 1
113
+ v = [max(ideal, nadir) > 0.005 for ideal, nadir in zip(running.delta_ideal, running.delta_nadir)]
114
+ self.data.append((tau, x, f, v))
115
+
116
+ fig, ax = plt.subplots()
117
+ self.draw(self.data, ax)
118
+
119
+ if self.key_press:
120
+ def press(event):
121
+ if event.key == 'q':
122
+ algorithm.termination.force_termination = True
123
+
124
+ fig.canvas.mpl_connect('key_press_event', press)
125
+
126
+ plt.draw()
127
+ plt.waitforbuttonpress()
128
+ plt.close('all')
@@ -0,0 +1,25 @@
1
+ import numpy as np
2
+
3
+
4
+ class SlidingWindow(list):
5
+
6
+ def __init__(self, size=None) -> None:
7
+ super().__init__()
8
+ self.size = size
9
+
10
+ def append(self, entry):
11
+ super().append(entry)
12
+
13
+ if self.size is not None:
14
+ while len(self) > self.size:
15
+ self.pop(0)
16
+
17
+ def is_full(self):
18
+ return self.size == len(self)
19
+
20
+ def to_numpy(self):
21
+ return np.array(self)
22
+
23
+ def clear(self):
24
+ while len(self) > 0:
25
+ self.pop()
@@ -0,0 +1,32 @@
1
+ from pymoo.util.misc import swap
2
+
3
+ import numpy as np
4
+
5
+
6
+ def stochastic_ranking(f, phi, pr, I=None):
7
+ _lambda = len(f)
8
+
9
+ if I is None:
10
+ I = np.arange(_lambda)
11
+
12
+ for i in range(_lambda):
13
+
14
+ at_least_one_swap = False
15
+
16
+ for j in range(_lambda - 1):
17
+
18
+ u = np.random.random()
19
+
20
+ if u < pr or (phi[I[j]] == 0 and phi[I[j + 1]] == 0):
21
+ if f[I[j]] > f[I[j + 1]]:
22
+ swap(I, j, j + 1)
23
+ at_least_one_swap = True
24
+ else:
25
+ if phi[I[j]] > phi[I[j + 1]]:
26
+ swap(I, j, j + 1)
27
+ at_least_one_swap = True
28
+
29
+ if not at_least_one_swap:
30
+ break
31
+
32
+ return I