pymoo 0.6.1.5.dev0__cp310-cp310-macosx_11_0_arm64.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 (328) 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-310-darwin.so +0 -0
  91. pymoo/cython/calc_perpendicular_distance.pyx +67 -0
  92. pymoo/cython/decomposition.cpython-310-darwin.so +0 -0
  93. pymoo/cython/decomposition.pyx +165 -0
  94. pymoo/cython/hv.cpython-310-darwin.so +0 -0
  95. pymoo/cython/hv.pyx +18 -0
  96. pymoo/cython/info.cpython-310-darwin.so +0 -0
  97. pymoo/cython/info.pyx +5 -0
  98. pymoo/cython/mnn.cpython-310-darwin.so +0 -0
  99. pymoo/cython/mnn.pyx +273 -0
  100. pymoo/cython/non_dominated_sorting.cpython-310-darwin.so +0 -0
  101. pymoo/cython/non_dominated_sorting.pyx +645 -0
  102. pymoo/cython/pruning_cd.cpython-310-darwin.so +0 -0
  103. pymoo/cython/pruning_cd.pyx +197 -0
  104. pymoo/cython/stochastic_ranking.cpython-310-darwin.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 +328 -0
  326. pymoo-0.6.1.5.dev0.dist-info/WHEEL +6 -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
@@ -0,0 +1,102 @@
1
+ import numpy as np
2
+ from scipy.spatial.ckdtree import cKDTree
3
+
4
+ from pymoo.core.indicator import Indicator
5
+
6
+
7
+ class DecisionMaking(Indicator):
8
+
9
+ def __init__(self, **kwargs) -> None:
10
+ super().__init__(**kwargs)
11
+ self.default_if_empty = None
12
+
13
+ def _do(self, F, *args, **kwargs):
14
+ pass
15
+
16
+
17
+ class NeighborFinder:
18
+
19
+ def __init__(self, N,
20
+ epsilon=0.125,
21
+ n_neighbors=None,
22
+ n_min_neigbors=None,
23
+ consider_2d=True):
24
+
25
+ super().__init__()
26
+ self.N = N
27
+ self.consider_2d = consider_2d
28
+
29
+ _, n_dim = N.shape
30
+
31
+ # at least find min(dimensionality times two neighbors, number PO solutions - 1) - if enabled
32
+ if n_min_neigbors == "auto":
33
+ self.n_min_neigbors = min(2 * n_dim, _ - 1)
34
+
35
+ # disable the minimum neighbor variable
36
+ else:
37
+ self.n_min_neigbors = np.inf
38
+
39
+ # either choose epsilon
40
+ self.epsilon = epsilon
41
+
42
+ # if none choose the number of neighbors
43
+ self.n_neighbors = n_neighbors
44
+
45
+ if self.N.shape[1] == 1:
46
+ raise Exception("At least 2 objectives must be provided.")
47
+
48
+ elif self.consider_2d and self.N.shape[1] == 2:
49
+ self.min, self.max = N.min(), N.max()
50
+ self.rank = np.argsort(N[:, 0])
51
+ self.pos_in_rank = np.argsort(self.rank)
52
+
53
+ else:
54
+ self.tree = cKDTree(N)
55
+
56
+ def find(self, i):
57
+
58
+ if self.consider_2d and self.N.shape[1] == 2:
59
+ neighbours = []
60
+
61
+ pos = self.pos_in_rank[i]
62
+ if pos > 0:
63
+ neighbours.append(self.rank[pos - 1])
64
+ if pos < len(self.N) - 1:
65
+ neighbours.append(self.rank[pos + 1])
66
+
67
+ else:
68
+
69
+ # for each neighbour in a specific radius of that solution
70
+ if self.epsilon is not None:
71
+ neighbours = self.tree.query_ball_point([self.N[i]], self.epsilon).tolist()[0]
72
+ elif self.n_neighbors is not None:
73
+ neighbours = self.tree.query([self.N[i]], k=self.n_neighbors + 1)[1].tolist()[0]
74
+ else:
75
+ raise Exception("Either define epsilon or number of neighbors.")
76
+
77
+ # in case n_min_neigbors is enabled
78
+ if len(neighbours) < self.n_min_neigbors:
79
+ neighbours = self.tree.query([self.N[i]], k=self.n_min_neigbors + 1)[1].tolist()[0]
80
+
81
+ return neighbours
82
+
83
+
84
+ def find_outliers_upper_tail(mu):
85
+
86
+ # remove values that are nan
87
+ I = np.where(np.logical_and(np.logical_not(np.isnan(mu)), np.logical_not(np.isinf(mu))))[0]
88
+ mu = mu[I]
89
+
90
+ # calculate mean and sigma
91
+ mean, sigma = mu.mean(), mu.std()
92
+
93
+ # calculate the deviation in terms of sigma
94
+ deviation = (mu - mean) / sigma
95
+
96
+ # 2 * sigma is considered as an outlier
97
+ S = I[np.where(deviation >= 2)[0]]
98
+
99
+ if len(S) == 0 and deviation.max() > 1:
100
+ S = I[[np.argmax(mu)]]
101
+
102
+ return S if len(S) > 0 else None
@@ -0,0 +1,76 @@
1
+ import numpy as np
2
+
3
+ from pymoo.util.misc import at_least_2d_array, to_1d_array_if_possible
4
+
5
+
6
+ class Decomposition:
7
+
8
+ def __init__(self, eps=0.0, _type="auto", **kwargs) -> None:
9
+ super().__init__()
10
+ self.eps = eps
11
+ self._type = _type
12
+ self.ideal_point, self.utopian_point, self.nadir_point = None, None, None
13
+
14
+ def __call__(self, *args, **kwargs):
15
+ return self.do(*args, **kwargs)
16
+
17
+ def do(self,
18
+ F,
19
+ weights,
20
+ _type="auto",
21
+ ideal_point=None,
22
+ utopian_point=None,
23
+ nadir_point=None,
24
+ **kwargs):
25
+
26
+ _F, _weights = to_1d_array_if_possible(F), to_1d_array_if_possible(weights)
27
+
28
+ if _type == "auto":
29
+ if _F.ndim == 1 and _weights.ndim > 1:
30
+ _type = "one_to_many"
31
+ elif _F.ndim > 1 and _weights.ndim == 1:
32
+ _type = "many_to_one"
33
+ elif _F.ndim == 2 and _weights.ndim == 2 and _F.shape[0] == _weights.shape[0]:
34
+ _type = "one_to_one"
35
+ else:
36
+ _type = "many_to_many"
37
+
38
+ # make both at least 2d arrays
39
+ F, weights = at_least_2d_array(F), at_least_2d_array(weights)
40
+
41
+ # get the number of points and weights
42
+ n_points, n_weights = F.shape[0], weights.shape[0]
43
+
44
+ self.ideal_point = ideal_point
45
+ if self.ideal_point is None:
46
+ self.ideal_point = np.zeros(F.shape[1])
47
+
48
+ self.utopian_point = utopian_point
49
+ if self.utopian_point is None:
50
+ self.utopian_point = self.ideal_point - self.eps
51
+
52
+ # set the nadir point by default to value or default
53
+ self.nadir_point = nadir_point
54
+ if self.nadir_point is None:
55
+ self.nadir_point = self.utopian_point + np.ones(F.shape[1])
56
+
57
+ if _type == "one_to_one":
58
+ D = self._do(F, weights=weights, **kwargs).flatten()
59
+
60
+ elif _type == "one_to_many":
61
+ F = np.repeat(F, n_weights, axis=0)
62
+ D = self._do(F, weights=weights, **kwargs).flatten()
63
+
64
+ elif _type == "many_to_one":
65
+ weights = np.repeat(weights, n_points, axis=0)
66
+ D = self._do(F, weights=weights, **kwargs).flatten()
67
+
68
+ elif _type == "many_to_many":
69
+ F = np.repeat(F, n_weights, axis=0)
70
+ weights = np.tile(weights, (n_points, 1))
71
+ D = self._do(F, weights=weights, **kwargs).reshape(n_points, n_weights)
72
+
73
+ else:
74
+ raise Exception("Unknown type for decomposition: %s" % _type)
75
+
76
+ return D
@@ -0,0 +1,163 @@
1
+ import numpy as np
2
+
3
+ from pymoo.util.misc import cdist
4
+
5
+
6
+ def default_attr(pop):
7
+ return pop.get("X")
8
+
9
+
10
+ class DuplicateElimination:
11
+
12
+ def __init__(self, func=None) -> None:
13
+ super().__init__()
14
+ self.func = func
15
+
16
+ if self.func is None:
17
+ self.func = default_attr
18
+
19
+ def do(self, pop, *args, return_indices=False, to_itself=True):
20
+ original = pop
21
+
22
+ if len(pop) == 0:
23
+ return (pop, [], []) if return_indices else pop
24
+
25
+ if to_itself:
26
+ pop = pop[~self._do(pop, None, np.full(len(pop), False))]
27
+
28
+ for arg in args:
29
+ if len(arg) > 0:
30
+
31
+ if len(pop) == 0:
32
+ break
33
+ elif len(arg) == 0:
34
+ continue
35
+ else:
36
+ pop = pop[~self._do(pop, arg, np.full(len(pop), False))]
37
+
38
+ if return_indices:
39
+ no_duplicate, is_duplicate = [], []
40
+ H = set(pop)
41
+
42
+ for i, ind in enumerate(original):
43
+ if ind in H:
44
+ no_duplicate.append(i)
45
+ else:
46
+ is_duplicate.append(i)
47
+
48
+ return pop, no_duplicate, is_duplicate
49
+ else:
50
+ return pop
51
+
52
+ def _do(self, pop, other, is_duplicate):
53
+ return is_duplicate
54
+
55
+
56
+ class DefaultDuplicateElimination(DuplicateElimination):
57
+
58
+ def __init__(self, epsilon=1e-16, **kwargs) -> None:
59
+ super().__init__(**kwargs)
60
+ self.epsilon = epsilon
61
+
62
+ def calc_dist(self, pop, other=None):
63
+ X = self.func(pop)
64
+
65
+ if other is None:
66
+ D = cdist(X, X)
67
+ D[np.triu_indices(len(X))] = np.inf
68
+ else:
69
+ _X = self.func(other)
70
+ D = cdist(X, _X)
71
+
72
+ return D
73
+
74
+ def _do(self, pop, other, is_duplicate):
75
+ D = self.calc_dist(pop, other)
76
+ D[np.isnan(D)] = np.inf
77
+
78
+ is_duplicate[np.any(D <= self.epsilon, axis=1)] = True
79
+ return is_duplicate
80
+
81
+
82
+ def to_float(val):
83
+ if isinstance(val, bool) or isinstance(val, np.bool_):
84
+ return 0.0 if val else 1.0
85
+ else:
86
+ return val
87
+
88
+
89
+ class ElementwiseDuplicateElimination(DefaultDuplicateElimination):
90
+
91
+ def __init__(self, cmp_func=None, **kwargs) -> None:
92
+ super().__init__(**kwargs)
93
+
94
+ if cmp_func is None:
95
+ cmp_func = self.is_equal
96
+
97
+ self.cmp_func = cmp_func
98
+
99
+ def is_equal(self, a, b):
100
+ pass
101
+
102
+ def _do(self, pop, other, is_duplicate):
103
+
104
+ if other is None:
105
+ for i in range(len(pop)):
106
+ for j in range(i + 1, len(pop)):
107
+ val = to_float(self.cmp_func(pop[i], pop[j]))
108
+ if val < self.epsilon:
109
+ is_duplicate[i] = True
110
+ break
111
+ else:
112
+ for i in range(len(pop)):
113
+ for j in range(len(other)):
114
+ val = to_float(self.cmp_func(pop[i], other[j]))
115
+ if val < self.epsilon:
116
+ is_duplicate[i] = True
117
+ break
118
+
119
+ return is_duplicate
120
+
121
+
122
+ def to_hash(x):
123
+ try:
124
+ h = hash(x)
125
+ except:
126
+ try:
127
+ h = hash(str(x))
128
+ except:
129
+ raise Exception("Hash could not be calculated. Please use another duplicate elimination.")
130
+
131
+ return h
132
+
133
+
134
+ class HashDuplicateElimination(DuplicateElimination):
135
+
136
+ def __init__(self, func=to_hash) -> None:
137
+ super().__init__()
138
+ self.func = func
139
+
140
+ def _do(self, pop, other, is_duplicate):
141
+ H = set()
142
+
143
+ if other is not None:
144
+ for o in other:
145
+ val = self.func(o)
146
+ H.add(self.func(val))
147
+
148
+ for i, ind in enumerate(pop):
149
+ val = self.func(ind)
150
+ h = self.func(val)
151
+
152
+ if h in H:
153
+ is_duplicate[i] = True
154
+ else:
155
+ H.add(h)
156
+
157
+ return is_duplicate
158
+
159
+
160
+ class NoDuplicateElimination(DuplicateElimination):
161
+
162
+ def do(self, pop, *args, **kwargs):
163
+ return pop
@@ -0,0 +1,116 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.individual import Individual
4
+ from pymoo.core.population import Population
5
+ from pymoo.core.problem import Problem
6
+
7
+
8
+ class Evaluator:
9
+
10
+ def __init__(self,
11
+ skip_already_evaluated: bool = True,
12
+ evaluate_values_of: list = ["F", "G", "H"],
13
+ callback=None):
14
+
15
+ """
16
+ The evaluator has the purpose to glue the problem with the population/individual objects.
17
+ Additionally, it serves as a bookkeeper to store determine the number of function evaluations of runs, time,
18
+ and others.
19
+
20
+
21
+ Parameters
22
+ ----------
23
+ skip_already_evaluated : bool
24
+ If individual that are already evaluated shall be skipped.
25
+
26
+ evaluate_values_of : list
27
+ The type of values to be asked the problem to evaluated. By default all objective, ieq. and eq. constraints.
28
+
29
+ """
30
+
31
+ self.evaluate_values_of = evaluate_values_of
32
+ self.skip_already_evaluated = skip_already_evaluated
33
+ self.callback = callback
34
+
35
+ # current number of function evaluations - initialized to zero
36
+ self.n_eval = 0
37
+
38
+ def eval(self,
39
+ problem: Problem,
40
+ pop: Population,
41
+ skip_already_evaluated: bool = None,
42
+ evaluate_values_of: list = None,
43
+ count_evals: bool = True,
44
+ **kwargs):
45
+
46
+ # load the default settings from the evaluator object if not already provided
47
+ evaluate_values_of = self.evaluate_values_of if evaluate_values_of is None else evaluate_values_of
48
+ skip_already_evaluated = self.skip_already_evaluated if skip_already_evaluated is None else skip_already_evaluated
49
+
50
+ # check the type of the input
51
+ is_individual = isinstance(pop, Individual)
52
+
53
+ # make sure the object is a population
54
+ if is_individual:
55
+ pop = Population().create(pop)
56
+
57
+ # filter the index to have individual where not all attributes have been evaluated
58
+ if skip_already_evaluated:
59
+ I = [i for i, ind in enumerate(pop) if not all([e in ind.evaluated for e in evaluate_values_of])]
60
+
61
+ # if skipping is deactivated simply make the index being all individuals
62
+ else:
63
+ I = np.arange(len(pop))
64
+
65
+ # evaluate the solutions (if there are any)
66
+ if len(I) > 0:
67
+
68
+ # do the actual evaluation - call the sub-function to set the corresponding values to the population
69
+ self._eval(problem, pop[I], evaluate_values_of, **kwargs)
70
+
71
+ # update the function evaluation counter
72
+ if count_evals:
73
+ self.n_eval += len(I)
74
+
75
+ # allow to have a callback registered
76
+ if self.callback:
77
+ self.callback(pop)
78
+
79
+ if is_individual:
80
+ return pop[0]
81
+ else:
82
+ return pop
83
+
84
+ def _eval(self, problem, pop, evaluate_values_of, **kwargs):
85
+
86
+ # get the design space value from the individuals
87
+ X = pop.get("X")
88
+
89
+ # call the problem to evaluate the solutions
90
+ out = problem.evaluate(X, return_values_of=evaluate_values_of, return_as_dictionary=True, **kwargs)
91
+
92
+ # for each of the attributes set it to the problem
93
+ for key, val in out.items():
94
+ if val is not None:
95
+ pop.set(key, val)
96
+
97
+ # finally set all the attributes to be evaluated for all individuals
98
+ pop.apply(lambda ind: ind.evaluated.update(out.keys()))
99
+
100
+
101
+ class VoidEvaluator(Evaluator):
102
+
103
+ def __init__(self, value=np.inf, **kwargs):
104
+ super().__init__(**kwargs)
105
+ self.value = value
106
+
107
+ def eval(self, problem, pop, **kwargs):
108
+ val = self.value
109
+ if val is not None:
110
+ for individual in pop:
111
+ if len(individual.evaluated) == 0:
112
+ individual.F = np.full(problem.n_obj, val)
113
+ individual.G = np.full(problem.n_ieq_constr, val) if problem.n_ieq_constr > 0 else None
114
+ individual.H = np.full(problem.n_eq_constr, val) if problem.n_eq_constr else None
115
+ individual.CV = [-np.inf]
116
+ individual.feas = [False]
@@ -0,0 +1,34 @@
1
+ import abc
2
+
3
+ from pymoo.util.normalization import PreNormalization
4
+
5
+
6
+ class Indicator(PreNormalization):
7
+
8
+ def __init__(self, **kwargs):
9
+ super().__init__(**kwargs)
10
+
11
+ # what should an indicator return if no solutions are provided is defined here
12
+ self.default_if_empty = 0.0
13
+
14
+ def __call__(self, F, *args, **kwargs):
15
+ return self.do(F, *args, **kwargs)
16
+
17
+ def do(self, F, *args, **kwargs):
18
+
19
+ # if it is a 1d array
20
+ if F.ndim == 1:
21
+ F = F[None, :]
22
+
23
+ # if no points have been provided just return the default
24
+ if len(F) == 0:
25
+ return self.default_if_empty
26
+
27
+ # do the normalization - will only be done if zero_to_one is enabled
28
+ F = self.normalization.forward(F)
29
+
30
+ return self._do(F, *args, **kwargs)
31
+
32
+ @abc.abstractmethod
33
+ def _do(self, F, *args, **kwargs):
34
+ return