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,59 @@
1
+ import numpy as np
2
+
3
+
4
+ class Optimizer:
5
+
6
+ def __init__(self, precision=1e-6) -> None:
7
+ super().__init__()
8
+ self.has_converged = False
9
+ self.precision = precision
10
+
11
+ def next(self, X, dX):
12
+ _X = self._next(X, dX)
13
+
14
+ if np.abs(_X - X).mean() < self.precision:
15
+ self.has_converged = True
16
+
17
+ return _X
18
+
19
+
20
+ class GradientDescent(Optimizer):
21
+
22
+ def __init__(self, learning_rate=0.01, **kwargs) -> None:
23
+ super().__init__(**kwargs)
24
+ self.learning_rate = learning_rate
25
+
26
+ def _next(self, X, dX):
27
+ return X - self.learning_rate * dX
28
+
29
+
30
+ class Adam(Optimizer):
31
+
32
+ def __init__(self, alpha=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-8, **kwargs) -> None:
33
+ super().__init__(**kwargs)
34
+
35
+ self.alpha = alpha
36
+ self.beta_1 = beta_1
37
+ self.beta_2 = beta_2
38
+ self.epsilon = epsilon
39
+
40
+ self.m_t = 0
41
+ self.v_t = 0
42
+ self.t = 0
43
+
44
+ def _next(self, X, dX):
45
+ self.t += 1
46
+ beta_1, beta_2 = self.beta_1, self.beta_2
47
+
48
+ # update moving average of gradient and squared gradient
49
+ self.m_t = beta_1 * self.m_t + (1 - beta_1) * dX
50
+ self.v_t = beta_2 * self.v_t + (1 - beta_2) * (dX * dX)
51
+
52
+ # calculates the bias-corrected estimates
53
+ m_cap = self.m_t / (1 - (beta_1 ** self.t))
54
+ v_cap = self.v_t / (1 - (beta_2 ** self.t))
55
+
56
+ # do the gradient update
57
+ _X = X - (self.alpha * m_cap) / (np.sqrt(v_cap) + self.epsilon)
58
+
59
+ return _X
@@ -0,0 +1,162 @@
1
+ import numpy as np
2
+ import numpy as np
3
+ from scipy.spatial.qhull import Delaunay
4
+ from scipy.stats import gmean
5
+
6
+ from pymoo.util.misc import distance_of_closest_points_to_others, vectorized_cdist, cdist
7
+ from pymoo.util.ref_dirs.das_dennis import DasDennis
8
+ from pymoo.util.reference_direction import get_partition_closest_to_points
9
+
10
+
11
+ def distance_of_closest_point(ref_dirs):
12
+ _, dist = distance_of_closest_points_to_others(ref_dirs)
13
+ return dist.min()
14
+
15
+
16
+ def average_distance_to_other_points(ref_dirs):
17
+ D = vectorized_cdist(ref_dirs, ref_dirs)
18
+ D = D[np.triu_indices(len(ref_dirs), 1)]
19
+ return D.mean()
20
+
21
+
22
+ def closest_point_variance(z):
23
+ for row in np.eye(z.shape[1]):
24
+ if not np.any(np.all(row == z, axis=1)):
25
+ z = np.vstack([z, row])
26
+
27
+ D = vectorized_cdist(z, z)
28
+ np.fill_diagonal(D, 1)
29
+
30
+ return D.min(axis=1).var()
31
+
32
+
33
+ def closest_point_variance_mod(z):
34
+ n_points, n_dim = z.shape
35
+
36
+ for row in np.eye(z.shape[1]):
37
+ if not np.any(np.all(row == z, axis=1)):
38
+ z = np.vstack([z, row])
39
+
40
+ D = vectorized_cdist(z, z)
41
+ np.fill_diagonal(D, np.inf)
42
+
43
+ k = int(np.ceil(np.sqrt(n_dim)))
44
+ I = D.argsort(axis=1)[:, k - 1]
45
+
46
+ return D[np.arange(n_points), I].var()
47
+
48
+
49
+ def geometric_mean_var(z):
50
+ for row in np.eye(z.shape[1]):
51
+ if not np.any(np.all(row == z, axis=1)):
52
+ z = np.vstack([z, row])
53
+ n_points, n_dim = z.shape
54
+
55
+ D = vectorized_cdist(z, z)
56
+ np.fill_diagonal(D, np.inf)
57
+
58
+ k = n_dim - 1
59
+ I = D.argsort(axis=1)[:, :k]
60
+
61
+ first = np.column_stack([np.arange(n_points) for _ in range(k)])
62
+
63
+ val = gmean(D[first, I], axis=1)
64
+
65
+ return val.var()
66
+
67
+
68
+ def mean_mean(z):
69
+ for row in np.eye(z.shape[1]):
70
+ if not np.any(np.all(row == z, axis=1)):
71
+ z = np.vstack([z, row])
72
+ n_points, n_dim = z.shape
73
+
74
+ D = vectorized_cdist(z, z)
75
+ np.fill_diagonal(D, np.inf)
76
+
77
+ k = n_dim - 1
78
+ I = D.argsort(axis=1)[:, :k]
79
+
80
+ first = np.column_stack([np.arange(n_points) for _ in range(k)])
81
+
82
+ val = np.mean(D[first, I], axis=1)
83
+
84
+ return val.mean()
85
+
86
+
87
+ def potential_energy(x):
88
+ _x = x / x.sum(axis=1)[:, None]
89
+ D = ((_x[:, None] - _x[None, :]) ** 2).sum(axis=2)
90
+ D = D[np.triu_indices(len(_x), 1)]
91
+ return (1 / D).mean()
92
+
93
+
94
+ def iterative_igd(X, n_partitions=None, batch_size=100):
95
+ n_points, n_dim = X.shape
96
+
97
+ if n_partitions is None:
98
+ n_partitions = get_partition_closest_to_points(n_points * n_dim * 10, n_dim) + 1
99
+
100
+ scaling = 1 + 1 / 2
101
+
102
+ dd = DasDennis(n_partitions, n_dim, scaling=scaling)
103
+ val = 0
104
+
105
+ while dd.has_next():
106
+ points = dd.next(n_points=batch_size)
107
+ val += cdist(points, X).min(axis=1).sum()
108
+
109
+ val /= dd.number_of_points()
110
+ return val
111
+
112
+
113
+ def gram_schmidt(X, row_vecs=True, norm=True):
114
+ if not row_vecs:
115
+ X = X.T
116
+ Y = X[0:1, :].copy()
117
+ for i in range(1, X.shape[0]):
118
+ proj = np.diag((X[i, :].dot(Y.T) / np.linalg.norm(Y, axis=1) ** 2).flat).dot(Y)
119
+ Y = np.vstack((Y, X[i, :] - proj.sum(0)))
120
+ if norm:
121
+ Y = np.diag(1 / np.linalg.norm(Y, axis=1)).dot(Y)
122
+ if row_vecs:
123
+ return Y
124
+ else:
125
+ return Y.T
126
+
127
+
128
+ def triangulation(X):
129
+ return simplex_edge_difference(project_onto_one_dim_less(X))
130
+
131
+
132
+ def project_onto_one_dim_less(X):
133
+ E = np.eye(X.shape[1])
134
+ P = E[0]
135
+ D = E[1:] - P
136
+ O = gram_schmidt(D)
137
+ return (X - P) @ O.T
138
+
139
+
140
+ def simplex_edge_difference(X):
141
+ tri = Delaunay(X, qhull_options="QJ")
142
+
143
+ simplices = []
144
+ for e in tri.simplices:
145
+ diff = X[e[1:]] - X[e[0]]
146
+ det = np.linalg.det(diff)
147
+ if det > 1e-6:
148
+ simplices.append(e)
149
+
150
+ val = []
151
+ for triangle in simplices:
152
+ dists = np.zeros(len(triangle))
153
+
154
+ for i in range(len(triangle)):
155
+ a, b = triangle[i], triangle[(i + 1) % len(triangle)]
156
+ dists[i] = np.linalg.norm(X[a] - X[b])
157
+
158
+ val.append(dists.max() - dists.min())
159
+
160
+ val = np.array(val)
161
+
162
+ return val.mean()
@@ -0,0 +1,85 @@
1
+ import numpy as np
2
+
3
+
4
+ from pymoo.util.misc import cdist
5
+
6
+ from pymoo.util.ref_dirs.misc import project_onto_unit_simplex_recursive
7
+ from pymoo.util.reference_direction import ReferenceDirectionFactory, sample_on_unit_simplex, \
8
+ select_points_with_maximum_distance, get_partition_closest_to_points, UniformReferenceDirectionFactory
9
+
10
+
11
+ def kmeans(X, centroids, n_max_iter, a_tol, n_ignore):
12
+
13
+ for i in range(n_max_iter):
14
+
15
+ # copy the old centroids
16
+ last_centroids = np.copy(centroids)
17
+
18
+ # assign all points to one of the centroids
19
+ points_to_centroid = cdist(X, centroids).argmin(axis=1)
20
+
21
+ centroids_to_points = [[] for _ in range(len(centroids))]
22
+ for j, k in enumerate(points_to_centroid):
23
+ centroids_to_points[k].append(j)
24
+
25
+ for j in range(n_ignore, len(centroids_to_points)):
26
+ centroids[j] = np.mean(X[centroids_to_points[j]], axis=0)
27
+
28
+ project_onto_unit_simplex_recursive(centroids)
29
+ centroids /= centroids.sum(axis=1)[:, None]
30
+
31
+ delta = np.abs(centroids - last_centroids).sum(axis=1).mean()
32
+
33
+ if delta < a_tol:
34
+ break
35
+
36
+ return centroids
37
+
38
+
39
+ class ReductionBasedReferenceDirectionFactory(ReferenceDirectionFactory):
40
+
41
+ def __init__(self,
42
+ n_dim,
43
+ n_points,
44
+ scaling=None,
45
+ n_sample_points=10000,
46
+ sampling="kraemer",
47
+ kmeans=True,
48
+ kmeans_max_iter=1000,
49
+ kmeans_a_tol=0.0001,
50
+ **kwargs):
51
+
52
+ super().__init__(n_dim, scaling, **kwargs)
53
+ self.n_sample_points = n_sample_points
54
+ self.sampling = sampling
55
+ self.kmeans = kmeans
56
+ self.kmeans_max_iter = kmeans_max_iter
57
+ self.kmeans_a_tol = kmeans_a_tol
58
+
59
+ if n_points is None:
60
+ raise Exception("Please provide the number of points to be factored!")
61
+
62
+ self.n_points = n_points
63
+
64
+ def _do(self, random_state=None):
65
+ rnd = sample_on_unit_simplex(self.n_sample_points, self.n_dim, random_state=random_state, unit_simplex_mapping=self.sampling)
66
+
67
+ def h(n):
68
+ return get_partition_closest_to_points(n, self.n_dim)
69
+
70
+ H = h(self.n_points)
71
+
72
+ E = UniformReferenceDirectionFactory(self.n_dim, n_partitions=H).do()
73
+ E = E[np.any(E == 0, axis=1)]
74
+
75
+ # add the edge coordinates
76
+ X = np.vstack([E, rnd])
77
+
78
+ I = select_points_with_maximum_distance(X, self.n_points, selected=list(range((len(E)))))
79
+ centroids = X[I].copy()
80
+
81
+ if self.kmeans:
82
+ #centroids = kmeans(X, centroids, self.kmeans_max_iter, self.kmeans_a_tol, 0)
83
+ centroids = kmeans(X, centroids, self.kmeans_max_iter, self.kmeans_a_tol, len(E))
84
+
85
+ return centroids
@@ -0,0 +1,24 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.problem import Problem
4
+ from pymoo.operators.sampling.lhs import LatinHypercubeSampling
5
+ from pymoo.util.reference_direction import ReferenceDirectionFactory, map_onto_unit_simplex
6
+
7
+
8
+ class RandomSamplingAndMap(ReferenceDirectionFactory):
9
+
10
+ def __init__(self,
11
+ n_dim,
12
+ n_points,
13
+ **kwargs):
14
+ super().__init__(n_dim, **kwargs)
15
+ self.n_points = n_points
16
+
17
+ def _do(self, random_state=None):
18
+ problem = Problem(n_var=self.n_dim, xl=0.0, xu=1.0)
19
+ sampling = LatinHypercubeSampling()
20
+
21
+ x = sampling(problem, self.n_points - self.n_dim, to_numpy=True, random_state=random_state)
22
+ x = map_onto_unit_simplex(x, "kraemer")
23
+ x = np.vstack([x, np.eye(self.n_dim)])
24
+ return x
@@ -0,0 +1,258 @@
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
+ from pymoo.util import default_random_state
8
+
9
+
10
+ # =========================================================================================================
11
+ # Model
12
+ # =========================================================================================================
13
+
14
+
15
+ def default_ref_dirs(m):
16
+ if m == 1:
17
+ return np.array([[1.0]])
18
+ elif m == 2:
19
+ return UniformReferenceDirectionFactory(m, n_partitions=99).do()
20
+ elif m == 3:
21
+ return UniformReferenceDirectionFactory(m, n_partitions=12).do()
22
+ else:
23
+ raise Exception("No default reference directions for more than 3 objectives. Please provide them directly:"
24
+ "https://pymoo.org/misc/reference_directions.html")
25
+
26
+
27
+ class ReferenceDirectionFactory:
28
+
29
+ def __init__(self, n_dim, scaling=None, lexsort=True, verbose=False, **kwargs) -> None:
30
+ super().__init__()
31
+ self.n_dim = n_dim
32
+ self.scaling = scaling
33
+ self.lexsort = lexsort
34
+ self.verbose = verbose
35
+
36
+ def __call__(self):
37
+ return self.do()
38
+
39
+ @default_random_state(seed=1)
40
+ def do(self, random_state=None):
41
+
42
+ if self.n_dim == 1:
43
+ return np.array([[1.0]])
44
+ else:
45
+
46
+ val = self._do(random_state=random_state)
47
+ if isinstance(val, tuple):
48
+ ref_dirs, other = val[0], val[1:]
49
+ else:
50
+ ref_dirs = val
51
+
52
+ if self.scaling is not None:
53
+ ref_dirs = scale_reference_directions(ref_dirs, self.scaling)
54
+
55
+ # do ref_dirs is desired
56
+ if self.lexsort:
57
+ I = np.lexsort([ref_dirs[:, j] for j in range(ref_dirs.shape[1])][::-1])
58
+ ref_dirs = ref_dirs[I]
59
+
60
+ return ref_dirs
61
+
62
+ def _do(self, random_state=None):
63
+ return None
64
+
65
+
66
+ # =========================================================================================================
67
+ # Das Dennis Reference Directions (Uniform)
68
+ # =========================================================================================================
69
+
70
+
71
+ def get_number_of_uniform_points(n_partitions, n_dim):
72
+ """
73
+ Returns the number of uniform points that can be created uniformly.
74
+ """
75
+ return int(special.binom(n_dim + n_partitions - 1, n_partitions))
76
+
77
+
78
+ def get_partition_closest_to_points(n_points, n_dim):
79
+ """
80
+ Returns the corresponding partition number which create the desired number of points
81
+ or less!
82
+ """
83
+
84
+ if n_dim == 1:
85
+ return 0
86
+
87
+ n_partitions = 1
88
+ _n_points = get_number_of_uniform_points(n_partitions, n_dim)
89
+ while _n_points <= n_points:
90
+ n_partitions += 1
91
+ _n_points = get_number_of_uniform_points(n_partitions, n_dim)
92
+ return n_partitions - 1
93
+
94
+
95
+ def das_dennis(n_partitions, n_dim):
96
+ if n_partitions == 0:
97
+ return np.full((1, n_dim), 1 / n_dim)
98
+ else:
99
+ ref_dirs = []
100
+ ref_dir = np.full(n_dim, np.nan)
101
+ das_dennis_recursion(ref_dirs, ref_dir, n_partitions, n_partitions, 0)
102
+ return np.concatenate(ref_dirs, axis=0)
103
+
104
+
105
+ def das_dennis_recursion(ref_dirs, ref_dir, n_partitions, beta, depth):
106
+ if depth == len(ref_dir) - 1:
107
+ ref_dir[depth] = beta / (1.0 * n_partitions)
108
+ ref_dirs.append(ref_dir[None, :])
109
+ else:
110
+ for i in range(beta + 1):
111
+ ref_dir[depth] = 1.0 * i / (1.0 * n_partitions)
112
+ das_dennis_recursion(ref_dirs, np.copy(ref_dir), n_partitions, beta - i, depth + 1)
113
+
114
+
115
+ class UniformReferenceDirectionFactory(ReferenceDirectionFactory):
116
+
117
+ def __init__(self, n_dim, scaling=None, n_points=None, n_partitions=None, **kwargs) -> None:
118
+ super().__init__(n_dim, scaling=scaling, **kwargs)
119
+
120
+ if n_points is not None:
121
+ n_partitions = get_partition_closest_to_points(n_points, n_dim)
122
+ results_in = get_number_of_uniform_points(n_partitions, n_dim)
123
+
124
+ # the number of points are not matching to any partition number
125
+ if results_in != n_points:
126
+ results_in_next = get_number_of_uniform_points(n_partitions + 1, n_dim)
127
+ raise Exception("The number of points (n_points = %s) can not be created uniformly.\n"
128
+ "Either choose n_points = %s (n_partitions = %s) or "
129
+ "n_points = %s (n_partitions = %s)." %
130
+ (n_points, results_in, n_partitions, results_in_next, n_partitions + 1))
131
+
132
+ self.n_partitions = n_partitions
133
+
134
+ elif n_partitions is not None:
135
+ self.n_partitions = n_partitions
136
+
137
+ else:
138
+ raise Exception("Either provide number of partitions or number of points.")
139
+
140
+ def _do(self, random_state=None):
141
+ return das_dennis(self.n_partitions, self.n_dim)
142
+
143
+
144
+ # =========================================================================================================
145
+ # Multi Layer
146
+ # =========================================================================================================
147
+
148
+
149
+ class MultiLayerReferenceDirectionFactory:
150
+
151
+ def __init__(self, *args) -> None:
152
+ self.layers = []
153
+ self.layers.extend(args)
154
+
155
+ def __call__(self):
156
+ return self.do()
157
+
158
+ def add_layer(self, *args):
159
+ self.layers.extend(args)
160
+
161
+ def do(self):
162
+ ref_dirs = []
163
+ for factory in self.layers:
164
+ ref_dirs.append(factory)
165
+ ref_dirs = np.concatenate(ref_dirs, axis=0)
166
+ is_duplicate = find_duplicates(ref_dirs)
167
+ return ref_dirs[np.logical_not(is_duplicate)]
168
+
169
+
170
+ # =========================================================================================================
171
+ # Util
172
+ # =========================================================================================================
173
+
174
+ @default_random_state
175
+ def get_rng(random_state=None, **kwargs):
176
+ return random_state
177
+
178
+
179
+ @default_random_state
180
+ def sample_on_unit_simplex(n_points, n_dim, unit_simplex_mapping="kraemer", random_state=None, **kwargs):
181
+ if unit_simplex_mapping == "sum":
182
+ rnd = map_onto_unit_simplex(random_state.random((n_points, n_dim)), "sum")
183
+
184
+ elif unit_simplex_mapping == "kraemer":
185
+ rnd = map_onto_unit_simplex(random_state.random((n_points, n_dim)), "kraemer")
186
+
187
+ elif unit_simplex_mapping == "das-dennis":
188
+ n_partitions = get_partition_closest_to_points(n_points, n_dim)
189
+ rnd = UniformReferenceDirectionFactory(n_dim, n_partitions=n_partitions).do()
190
+
191
+ else:
192
+ raise Exception("Please define a valid sampling on unit simplex strategy!")
193
+
194
+ return rnd
195
+
196
+
197
+ def map_onto_unit_simplex(rnd, method):
198
+ n_points, n_dim = rnd.shape
199
+
200
+ if method == "sum":
201
+ ret = rnd / rnd.sum(axis=1)[:, None]
202
+
203
+ elif method == "kraemer":
204
+ M = sys.maxsize
205
+
206
+ rnd *= M
207
+ rnd = rnd[:, :n_dim - 1]
208
+ rnd = np.column_stack([np.zeros(n_points), rnd, np.full(n_points, M)])
209
+
210
+ rnd = np.sort(rnd, axis=1)
211
+
212
+ ret = np.full((n_points, n_dim), np.nan)
213
+ for i in range(1, n_dim + 1):
214
+ ret[:, i - 1] = rnd[:, i] - rnd[:, i - 1]
215
+ ret /= M
216
+
217
+ else:
218
+ raise Exception("Invalid unit simplex mapping!")
219
+
220
+ return ret
221
+
222
+
223
+ def scale_reference_directions(ref_dirs, scaling):
224
+ return ref_dirs * scaling + ((1 - scaling) / ref_dirs.shape[1])
225
+
226
+
227
+ def select_points_with_maximum_distance(X, n_select, selected=[], random_state=None):
228
+ n_points, n_dim = X.shape
229
+
230
+ # calculate the distance matrix
231
+ D = cdist(X, X)
232
+
233
+ # if no selection provided pick randomly in the beginning
234
+ if len(selected) == 0:
235
+ # random_state should be provided by caller
236
+ selected = [random_state.integers(len(X))]
237
+
238
+ # create variables to store what selected and what not
239
+ not_selected = [i for i in range(n_points) if i not in selected]
240
+
241
+ # remove unnecessary points
242
+ dist_to_closest_selected = D[:, selected].min(axis=1)
243
+
244
+ # now select the points until sufficient ones are found
245
+ while len(selected) < n_select:
246
+ # find point that has the maximum distance to all others
247
+ index_in_not_selected = dist_to_closest_selected[not_selected].argmax()
248
+ I = not_selected[index_in_not_selected]
249
+
250
+ # add the closest distance to selected point
251
+ is_closer = D[I] < dist_to_closest_selected
252
+ dist_to_closest_selected[is_closer] = D[I][is_closer]
253
+
254
+ # add it to the selected and remove from not selected
255
+ selected.append(I)
256
+ not_selected = np.delete(not_selected, index_in_not_selected)
257
+
258
+ 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,29 @@
1
+ import numpy as np
2
+ from pymoo.util import default_random_state
3
+
4
+
5
+ class RouletteWheelSelection:
6
+
7
+ def __init__(self, val, larger_is_better=True):
8
+ super().__init__()
9
+ if not larger_is_better:
10
+ val = val.max() - val
11
+ _sum = val.sum()
12
+ self.cumulative = np.array([val[:k].sum() / _sum for k in range(1, len(val))])
13
+
14
+ @default_random_state
15
+ def next(self, n=None, random_state=None):
16
+ if n is None:
17
+ X = random_state.random((1, 1))
18
+ else:
19
+ X = random_state.random((n, 1))
20
+ if n > 1:
21
+ X.repeat(n - 1, axis=1)
22
+
23
+ M = self.cumulative[None, :].repeat(len(X), axis=0)
24
+ B = X >= M
25
+ ret = B.sum(axis=1)
26
+
27
+ if n is None:
28
+ return ret[0]
29
+ return ret