pymoo 0.6.1.5.dev0__cp313-cp313-manylinux_2_17_x86_64.manylinux2014_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 (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-313-x86_64-linux-gnu.so +0 -0
  91. pymoo/cython/calc_perpendicular_distance.pyx +67 -0
  92. pymoo/cython/decomposition.cpython-313-x86_64-linux-gnu.so +0 -0
  93. pymoo/cython/decomposition.pyx +165 -0
  94. pymoo/cython/hv.cpython-313-x86_64-linux-gnu.so +0 -0
  95. pymoo/cython/hv.pyx +18 -0
  96. pymoo/cython/info.cpython-313-x86_64-linux-gnu.so +0 -0
  97. pymoo/cython/info.pyx +5 -0
  98. pymoo/cython/mnn.cpython-313-x86_64-linux-gnu.so +0 -0
  99. pymoo/cython/mnn.pyx +273 -0
  100. pymoo/cython/non_dominated_sorting.cpython-313-x86_64-linux-gnu.so +0 -0
  101. pymoo/cython/non_dominated_sorting.pyx +645 -0
  102. pymoo/cython/pruning_cd.cpython-313-x86_64-linux-gnu.so +0 -0
  103. pymoo/cython/pruning_cd.pyx +197 -0
  104. pymoo/cython/stochastic_ranking.cpython-313-x86_64-linux-gnu.so +0 -0
  105. pymoo/cython/stochastic_ranking.pyx +49 -0
  106. pymoo/cython/utils.pxd +129 -0
  107. pymoo/cython/vendor/__init__.py +0 -0
  108. pymoo/cython/vendor/hypervolume.cpp +1621 -0
  109. pymoo/cython/vendor/hypervolume.h +63 -0
  110. pymoo/decomposition/__init__.py +0 -0
  111. pymoo/decomposition/aasf.py +24 -0
  112. pymoo/decomposition/asf.py +10 -0
  113. pymoo/decomposition/pbi.py +13 -0
  114. pymoo/decomposition/perp_dist.py +13 -0
  115. pymoo/decomposition/tchebicheff.py +11 -0
  116. pymoo/decomposition/util.py +13 -0
  117. pymoo/decomposition/weighted_sum.py +8 -0
  118. pymoo/docs.py +187 -0
  119. pymoo/experimental/__init__.py +0 -0
  120. pymoo/experimental/algorithms/__init__.py +0 -0
  121. pymoo/experimental/algorithms/gde3.py +57 -0
  122. pymoo/gradient/__init__.py +21 -0
  123. pymoo/gradient/automatic.py +57 -0
  124. pymoo/gradient/grad_autograd.py +105 -0
  125. pymoo/gradient/grad_complex.py +35 -0
  126. pymoo/gradient/grad_jax.py +51 -0
  127. pymoo/gradient/toolbox/__init__.py +6 -0
  128. pymoo/indicators/__init__.py +0 -0
  129. pymoo/indicators/distance_indicator.py +55 -0
  130. pymoo/indicators/gd.py +7 -0
  131. pymoo/indicators/gd_plus.py +7 -0
  132. pymoo/indicators/hv/__init__.py +63 -0
  133. pymoo/indicators/hv/exact.py +71 -0
  134. pymoo/indicators/hv/exact_2d.py +102 -0
  135. pymoo/indicators/hv/monte_carlo.py +74 -0
  136. pymoo/indicators/igd.py +7 -0
  137. pymoo/indicators/igd_plus.py +7 -0
  138. pymoo/indicators/kktpm.py +151 -0
  139. pymoo/indicators/migd.py +55 -0
  140. pymoo/indicators/rmetric.py +203 -0
  141. pymoo/indicators/spacing.py +52 -0
  142. pymoo/mcdm/__init__.py +0 -0
  143. pymoo/mcdm/compromise_programming.py +19 -0
  144. pymoo/mcdm/high_tradeoff.py +40 -0
  145. pymoo/mcdm/pseudo_weights.py +32 -0
  146. pymoo/operators/__init__.py +0 -0
  147. pymoo/operators/control.py +187 -0
  148. pymoo/operators/crossover/__init__.py +0 -0
  149. pymoo/operators/crossover/binx.py +45 -0
  150. pymoo/operators/crossover/dex.py +122 -0
  151. pymoo/operators/crossover/erx.py +162 -0
  152. pymoo/operators/crossover/expx.py +51 -0
  153. pymoo/operators/crossover/hux.py +37 -0
  154. pymoo/operators/crossover/nox.py +13 -0
  155. pymoo/operators/crossover/ox.py +84 -0
  156. pymoo/operators/crossover/pcx.py +82 -0
  157. pymoo/operators/crossover/pntx.py +49 -0
  158. pymoo/operators/crossover/sbx.py +125 -0
  159. pymoo/operators/crossover/spx.py +5 -0
  160. pymoo/operators/crossover/ux.py +20 -0
  161. pymoo/operators/mutation/__init__.py +0 -0
  162. pymoo/operators/mutation/bitflip.py +17 -0
  163. pymoo/operators/mutation/gauss.py +58 -0
  164. pymoo/operators/mutation/inversion.py +42 -0
  165. pymoo/operators/mutation/nom.py +7 -0
  166. pymoo/operators/mutation/pm.py +94 -0
  167. pymoo/operators/mutation/rm.py +23 -0
  168. pymoo/operators/repair/__init__.py +0 -0
  169. pymoo/operators/repair/bounce_back.py +32 -0
  170. pymoo/operators/repair/bounds_repair.py +95 -0
  171. pymoo/operators/repair/inverse_penalty.py +89 -0
  172. pymoo/operators/repair/rounding.py +18 -0
  173. pymoo/operators/repair/to_bound.py +31 -0
  174. pymoo/operators/repair/vtype.py +11 -0
  175. pymoo/operators/sampling/__init__.py +0 -0
  176. pymoo/operators/sampling/lhs.py +73 -0
  177. pymoo/operators/sampling/rnd.py +50 -0
  178. pymoo/operators/selection/__init__.py +0 -0
  179. pymoo/operators/selection/rnd.py +72 -0
  180. pymoo/operators/selection/tournament.py +76 -0
  181. pymoo/operators/survival/__init__.py +0 -0
  182. pymoo/operators/survival/rank_and_crowding/__init__.py +1 -0
  183. pymoo/operators/survival/rank_and_crowding/classes.py +209 -0
  184. pymoo/operators/survival/rank_and_crowding/metrics.py +208 -0
  185. pymoo/optimize.py +72 -0
  186. pymoo/problems/__init__.py +157 -0
  187. pymoo/problems/dyn.py +47 -0
  188. pymoo/problems/dynamic/__init__.py +0 -0
  189. pymoo/problems/dynamic/cec2015.py +108 -0
  190. pymoo/problems/dynamic/df.py +452 -0
  191. pymoo/problems/dynamic/misc.py +167 -0
  192. pymoo/problems/functional.py +48 -0
  193. pymoo/problems/many/__init__.py +5 -0
  194. pymoo/problems/many/cdtlz.py +159 -0
  195. pymoo/problems/many/dcdtlz.py +88 -0
  196. pymoo/problems/many/dtlz.py +264 -0
  197. pymoo/problems/many/wfg.py +550 -0
  198. pymoo/problems/multi/__init__.py +14 -0
  199. pymoo/problems/multi/bnh.py +34 -0
  200. pymoo/problems/multi/carside.py +48 -0
  201. pymoo/problems/multi/clutch.py +104 -0
  202. pymoo/problems/multi/csi.py +55 -0
  203. pymoo/problems/multi/ctp.py +198 -0
  204. pymoo/problems/multi/dascmop.py +213 -0
  205. pymoo/problems/multi/kursawe.py +25 -0
  206. pymoo/problems/multi/modact.py +68 -0
  207. pymoo/problems/multi/mw.py +400 -0
  208. pymoo/problems/multi/omnitest.py +48 -0
  209. pymoo/problems/multi/osy.py +32 -0
  210. pymoo/problems/multi/srn.py +28 -0
  211. pymoo/problems/multi/sympart.py +94 -0
  212. pymoo/problems/multi/tnk.py +24 -0
  213. pymoo/problems/multi/truss2d.py +83 -0
  214. pymoo/problems/multi/welded_beam.py +41 -0
  215. pymoo/problems/multi/wrm.py +36 -0
  216. pymoo/problems/multi/zdt.py +151 -0
  217. pymoo/problems/multi_to_single.py +22 -0
  218. pymoo/problems/single/__init__.py +12 -0
  219. pymoo/problems/single/ackley.py +24 -0
  220. pymoo/problems/single/cantilevered_beam.py +34 -0
  221. pymoo/problems/single/flowshop_scheduling.py +112 -0
  222. pymoo/problems/single/g.py +874 -0
  223. pymoo/problems/single/griewank.py +18 -0
  224. pymoo/problems/single/himmelblau.py +15 -0
  225. pymoo/problems/single/knapsack.py +48 -0
  226. pymoo/problems/single/mopta08.py +26 -0
  227. pymoo/problems/single/multimodal.py +20 -0
  228. pymoo/problems/single/pressure_vessel.py +30 -0
  229. pymoo/problems/single/rastrigin.py +20 -0
  230. pymoo/problems/single/rosenbrock.py +22 -0
  231. pymoo/problems/single/schwefel.py +18 -0
  232. pymoo/problems/single/simple.py +13 -0
  233. pymoo/problems/single/sphere.py +19 -0
  234. pymoo/problems/single/traveling_salesman.py +79 -0
  235. pymoo/problems/single/zakharov.py +19 -0
  236. pymoo/problems/static.py +14 -0
  237. pymoo/problems/util.py +42 -0
  238. pymoo/problems/zero_to_one.py +27 -0
  239. pymoo/termination/__init__.py +23 -0
  240. pymoo/termination/collection.py +12 -0
  241. pymoo/termination/cv.py +48 -0
  242. pymoo/termination/default.py +45 -0
  243. pymoo/termination/delta.py +64 -0
  244. pymoo/termination/fmin.py +16 -0
  245. pymoo/termination/ftol.py +144 -0
  246. pymoo/termination/indicator.py +49 -0
  247. pymoo/termination/max_eval.py +14 -0
  248. pymoo/termination/max_gen.py +15 -0
  249. pymoo/termination/max_time.py +20 -0
  250. pymoo/termination/robust.py +34 -0
  251. pymoo/termination/xtol.py +33 -0
  252. pymoo/util/__init__.py +0 -0
  253. pymoo/util/archive.py +150 -0
  254. pymoo/util/cache.py +29 -0
  255. pymoo/util/clearing.py +82 -0
  256. pymoo/util/display/__init__.py +0 -0
  257. pymoo/util/display/column.py +52 -0
  258. pymoo/util/display/display.py +34 -0
  259. pymoo/util/display/multi.py +96 -0
  260. pymoo/util/display/output.py +53 -0
  261. pymoo/util/display/progress.py +54 -0
  262. pymoo/util/display/single.py +67 -0
  263. pymoo/util/dominator.py +67 -0
  264. pymoo/util/function_loader.py +129 -0
  265. pymoo/util/hv.py +23 -0
  266. pymoo/util/matlab_engine.py +39 -0
  267. pymoo/util/misc.py +460 -0
  268. pymoo/util/mnn.py +70 -0
  269. pymoo/util/nds/__init__.py +0 -0
  270. pymoo/util/nds/dominance_degree_non_dominated_sort.py +159 -0
  271. pymoo/util/nds/efficient_non_dominated_sort.py +152 -0
  272. pymoo/util/nds/fast_non_dominated_sort.py +70 -0
  273. pymoo/util/nds/naive_non_dominated_sort.py +36 -0
  274. pymoo/util/nds/non_dominated_sorting.py +67 -0
  275. pymoo/util/nds/tree_based_non_dominated_sort.py +133 -0
  276. pymoo/util/normalization.py +312 -0
  277. pymoo/util/optimum.py +42 -0
  278. pymoo/util/plotting.py +177 -0
  279. pymoo/util/pruning_cd.py +89 -0
  280. pymoo/util/randomized_argsort.py +60 -0
  281. pymoo/util/ref_dirs/__init__.py +24 -0
  282. pymoo/util/ref_dirs/construction.py +88 -0
  283. pymoo/util/ref_dirs/das_dennis.py +52 -0
  284. pymoo/util/ref_dirs/energy.py +319 -0
  285. pymoo/util/ref_dirs/energy_layer.py +119 -0
  286. pymoo/util/ref_dirs/genetic_algorithm.py +63 -0
  287. pymoo/util/ref_dirs/incremental.py +68 -0
  288. pymoo/util/ref_dirs/misc.py +128 -0
  289. pymoo/util/ref_dirs/optimizer.py +59 -0
  290. pymoo/util/ref_dirs/performance.py +162 -0
  291. pymoo/util/ref_dirs/reduction.py +85 -0
  292. pymoo/util/ref_dirs/sample_and_map.py +24 -0
  293. pymoo/util/reference_direction.py +260 -0
  294. pymoo/util/remote.py +55 -0
  295. pymoo/util/roulette.py +27 -0
  296. pymoo/util/running_metric.py +128 -0
  297. pymoo/util/sliding_window.py +25 -0
  298. pymoo/util/stochastic_ranking.py +32 -0
  299. pymoo/util/value_functions.py +719 -0
  300. pymoo/util/vectors.py +40 -0
  301. pymoo/util/vf_dominator.py +99 -0
  302. pymoo/vendor/__init__.py +0 -0
  303. pymoo/vendor/cec2018.py +398 -0
  304. pymoo/vendor/gta.py +617 -0
  305. pymoo/vendor/hv.py +267 -0
  306. pymoo/vendor/vendor_cmaes.py +412 -0
  307. pymoo/vendor/vendor_coco.py +81 -0
  308. pymoo/vendor/vendor_scipy.py +232 -0
  309. pymoo/version.py +1 -0
  310. pymoo/visualization/__init__.py +8 -0
  311. pymoo/visualization/fitness_landscape.py +127 -0
  312. pymoo/visualization/heatmap.py +123 -0
  313. pymoo/visualization/pcp.py +120 -0
  314. pymoo/visualization/petal.py +91 -0
  315. pymoo/visualization/radar.py +108 -0
  316. pymoo/visualization/radviz.py +68 -0
  317. pymoo/visualization/scatter.py +150 -0
  318. pymoo/visualization/star_coordinate.py +75 -0
  319. pymoo/visualization/util.py +123 -0
  320. pymoo/visualization/video/__init__.py +0 -0
  321. pymoo/visualization/video/callback_video.py +82 -0
  322. pymoo/visualization/video/one_var_one_obj.py +57 -0
  323. pymoo/visualization/video/two_var_one_obj.py +62 -0
  324. pymoo-0.6.1.5.dev0.dist-info/METADATA +187 -0
  325. pymoo-0.6.1.5.dev0.dist-info/RECORD +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,645 @@
1
+ # distutils: language = c++
2
+ # cython: language_level=2, boundscheck=False, wraparound=False, cdivision=True
3
+
4
+
5
+ import numpy as np
6
+ from libcpp cimport bool
7
+ from libcpp.vector cimport vector
8
+
9
+
10
+ cdef extern from "math.h":
11
+ cpdef double floor(double x)
12
+
13
+ cdef extern from "limits.h":
14
+ int INT_MAX
15
+
16
+
17
+ # ---------------------------------------------------------------------------------------------------------
18
+ # Interface
19
+ # ---------------------------------------------------------------------------------------------------------
20
+
21
+
22
+
23
+ def fast_non_dominated_sort(double[:,:] F, double epsilon = 0.0, int n_stop_if_ranked=INT_MAX):
24
+ return c_fast_non_dominated_sort(F, epsilon, n_stop_if_ranked)
25
+
26
+ def best_order_sort(double[:,:] F):
27
+ return c_best_order_sort(F)
28
+
29
+ def get_relation(F, a, b):
30
+ return c_get_relation(F, a, b)
31
+
32
+ def fast_best_order_sort(double[:,:] F):
33
+ return c_fast_best_order_sort(F)
34
+
35
+ def efficient_non_dominated_sort(double[:,:] F, strategy="sequential"):
36
+ assert (strategy in ["sequential", 'binary']), "Invalid search strategy"
37
+ return c_efficient_non_dominated_sort(F, strategy)
38
+
39
+ def dominance_degree_non_dominated_sort(double[:, :] F, strategy="efficient"):
40
+ if strategy not in ["fast", "efficient"]:
41
+ raise ValueError("Invalid search strategy")
42
+ return c_dominance_degree_non_dominated_sort(F, strategy)
43
+
44
+
45
+
46
+
47
+ # ---------------------------------------------------------------------------------------------------------
48
+ # Fast Non-Dominated Sort
49
+ # ---------------------------------------------------------------------------------------------------------
50
+
51
+
52
+
53
+ cdef vector[vector[int]] c_fast_non_dominated_sort(double[:,:] F, double epsilon = 0.0, int n_stop_if_ranked=INT_MAX):
54
+
55
+ cdef:
56
+ int n_points, i, j, rel, n_ranked
57
+ vector[int] current_front, next_front, n_dominated
58
+ vector[vector[int]] fronts, is_dominating
59
+
60
+ # calculate the dominance matrix
61
+ n_points = F.shape[0]
62
+
63
+ fronts = vector[vector[int]]()
64
+
65
+ if n_points == 0:
66
+ return fronts
67
+
68
+ # final rank that will be returned
69
+ n_ranked = 0
70
+
71
+ # for each individual a list of all individuals that are dominated by this one
72
+ is_dominating = vector[vector[int]](n_points)
73
+ for _ in range(n_points):
74
+ is_dominating.push_back(vector[int](n_points))
75
+
76
+ n_dominated = vector[int]()
77
+ for i in range(n_points):
78
+ n_dominated.push_back(0)
79
+
80
+ current_front = vector[int]()
81
+
82
+ for i in range(n_points):
83
+
84
+ for j in range(i + 1, n_points):
85
+
86
+ rel = c_get_relation(F, i, j, epsilon)
87
+
88
+ if rel == 1:
89
+ is_dominating[i].push_back(j)
90
+ n_dominated[j] += 1
91
+
92
+ elif rel == -1:
93
+ is_dominating[j].push_back(i)
94
+ n_dominated[i] += 1
95
+
96
+ if n_dominated[i] == 0:
97
+ current_front.push_back(i)
98
+ n_ranked += 1
99
+
100
+ # append the first front to the current front
101
+ fronts.push_back(current_front)
102
+
103
+ # while not all solutions are assigned to a pareto front or we can stop early because of stop criterion
104
+ while (n_ranked < n_points) and (n_ranked < n_stop_if_ranked):
105
+
106
+ next_front = vector[int]()
107
+
108
+ # for each individual in the current front
109
+ for i in current_front:
110
+
111
+ # all solutions that are dominated by this individuals
112
+ for j in is_dominating[i]:
113
+
114
+ n_dominated[j] -= 1
115
+ if n_dominated[j] == 0:
116
+ next_front.push_back(j)
117
+ n_ranked += 1
118
+
119
+ fronts.push_back(next_front)
120
+ current_front = next_front
121
+
122
+ return fronts
123
+
124
+
125
+ cdef vector[vector[int]] c_best_order_sort(double[:,:] F):
126
+
127
+ cdef:
128
+ int n_points, n_obj, n_fronts, n_ranked, i, j, s, e, l, z
129
+ vector[int] rank
130
+ int[:,:] Q
131
+ bool is_dominated
132
+ vector[vector[int]] fronts, empty
133
+ vector[vector[vector[int]]] L
134
+
135
+ n_points = F.shape[0]
136
+ n_obj = F.shape[1]
137
+ fronts = vector[vector[int]]()
138
+
139
+ _Q = np.zeros((n_points, n_obj), dtype=np.intc)
140
+ for j in range(n_obj):
141
+ _Q[:, j] = np.lexsort(F[:, j:][:, ::-1].T, axis=0)
142
+ Q = _Q[:,:]
143
+
144
+ rank = vector[int]()
145
+ for i in range(n_points):
146
+ rank.push_back(-1)
147
+
148
+ L = vector[vector[vector[int]]]()
149
+ for j in range(n_obj):
150
+ empty = vector[vector[int]]()
151
+ L.push_back(empty)
152
+
153
+ n_fronts = 0
154
+ n_ranked = 0
155
+
156
+ # the outer loop iterates through all solutions
157
+ for i in range(n_points):
158
+
159
+ # the inner loop through each objective values (sorted)
160
+ for j in range(n_obj):
161
+
162
+ # index of the current solution
163
+ s = Q[i, j]
164
+
165
+ # if solution was already ranked before - just append it to the corresponding front
166
+ if rank[s] != -1:
167
+ L[j][rank[s]].push_back(s)
168
+
169
+ # otherwise we rank it for the first time
170
+ else:
171
+
172
+ # the rank of this solution is stored here
173
+ s_rank = -1
174
+
175
+ # for each front ranked for this objective
176
+ for k in range(n_fronts):
177
+
178
+ is_dominated = False
179
+
180
+ # for each entry in that front
181
+ for e in L[j][k]:
182
+
183
+ is_dominated = c_get_relation(F, s, e) == -1
184
+
185
+ # if one solution dominates the current one - go to the next front
186
+ if is_dominated:
187
+ break
188
+
189
+ # if no solutions in the front dominates this one we found the rank
190
+ if not is_dominated:
191
+ s_rank = k
192
+ break
193
+
194
+ # we need to add a new front for each objective
195
+ if s_rank == -1:
196
+
197
+ s_rank = n_fronts
198
+ n_fronts += 1
199
+
200
+ fronts.push_back(vector[int]())
201
+ for l in range(n_obj):
202
+ L[l].push_back(vector[int]())
203
+
204
+ L[j][s_rank].push_back(s)
205
+ fronts[s_rank].push_back(s)
206
+ rank[s] = s_rank
207
+ n_ranked += 1
208
+
209
+ if n_ranked == n_points:
210
+ break
211
+
212
+ return fronts
213
+
214
+
215
+ cdef vector[vector[int]] c_fast_best_order_sort(double[:,:] F):
216
+
217
+ cdef:
218
+ int n_points, n_obj, n_fronts, n_ranked, i, j, s, e, l, z, s_next
219
+ vector[int] rank, counter, check_if_equal
220
+ int[:,:] Q
221
+ bool is_dominated
222
+ vector[vector[int]] fronts, empty ,C
223
+ vector[vector[vector[int]]] L
224
+
225
+ n_points = F.shape[0]
226
+ n_obj = F.shape[1]
227
+ fronts = vector[vector[int]]()
228
+
229
+
230
+ _Q = np.zeros((n_points, n_obj), dtype=np.intc)
231
+ _Q[:, 0] = np.lexsort(F[:, ::-1].T, axis=0)
232
+ for j in range(1, n_obj):
233
+ _Q[:, j] = np.lexsort(np.vstack([_Q[:, 0], F[:, j]]), axis=0)
234
+ Q = _Q[:,:]
235
+
236
+
237
+ counter = vector[int](n_points)
238
+ C = vector[vector[int]]()
239
+ for j in range(n_points):
240
+ C.push_back(vector[int](n_obj))
241
+ for i in range(n_points):
242
+ for j in range(n_obj):
243
+ s = Q[i, j]
244
+ C[s][counter[s]] = j
245
+ counter[s] += 1
246
+ counter = vector[int](n_points)
247
+
248
+ check_if_equal = vector[int]()
249
+ for j in range(n_points):
250
+ check_if_equal.push_back(-1)
251
+
252
+ rank = vector[int]()
253
+ for i in range(n_points):
254
+ rank.push_back(-1)
255
+
256
+ L = vector[vector[vector[int]]]()
257
+ for j in range(n_obj):
258
+ empty = vector[vector[int]]()
259
+ L.push_back(empty)
260
+
261
+ n_fronts = 0
262
+ n_ranked = 0
263
+
264
+ # the outer loop iterates through all solutions
265
+ for i in range(n_points):
266
+
267
+ # the inner loop through each objective values (sorted)
268
+ for j in range(n_obj):
269
+
270
+ # index of the current solution
271
+ s = Q[i, j]
272
+ s_next = Q[i + 1, j]
273
+
274
+ # increase the counter for comparing this objective
275
+ counter[s] += 1
276
+
277
+ # if not the last solution
278
+ if i < n_points - 1:
279
+ if check_if_equal[s] == -1:
280
+ check_if_equal[s] = s_next
281
+ elif check_if_equal[s] != s_next:
282
+ check_if_equal[s] = -2
283
+
284
+ # if solution was already ranked before - just append it to the corresponding front
285
+ if rank[s] != -1:
286
+ L[j][rank[s]].push_back(s)
287
+
288
+ # otherwise we rank it for the first time
289
+ else:
290
+
291
+ # the rank of this solution is stored here
292
+ s_rank = -1
293
+
294
+ # for each front ranked for this objective
295
+ for k in range(n_fronts):
296
+
297
+ # just necessary if no fronts exists
298
+ is_dominated = False
299
+ is_equal = False
300
+
301
+ # for each entry in that front
302
+ for e in L[j][k]:
303
+
304
+ # get the domination relation - might return true even if equal
305
+ is_dominated = c_is_dominating_or_equal(F, e, s, C, counter[s])
306
+
307
+ if is_dominated and check_if_equal[e] == s:
308
+ is_equal = c_is_equal(F, s, e)
309
+
310
+ # if just one solution dominates the current one - go to the next front
311
+ if is_dominated or is_equal:
312
+ break
313
+
314
+ # if no solutions in the front dominates this one we found the rank
315
+ if not is_dominated or is_equal:
316
+ s_rank = k
317
+ break
318
+
319
+ # we need to add a new front for each objective
320
+ if s_rank == -1:
321
+
322
+ s_rank = n_fronts
323
+ n_fronts += 1
324
+
325
+ fronts.push_back(vector[int]())
326
+ for l in range(n_obj):
327
+ L[l].push_back(vector[int]())
328
+
329
+ L[j][s_rank].push_back(s)
330
+ fronts[s_rank].push_back(s)
331
+ rank[s] = s_rank
332
+ n_ranked += 1
333
+
334
+ if n_ranked == n_points:
335
+ break
336
+
337
+ return fronts
338
+
339
+
340
+
341
+
342
+
343
+ # ---------------------------------------------------------------------------------------------------------
344
+ # Dominance Degree Approach Non-dominated Sort
345
+ # ---------------------------------------------------------------------------------------------------------
346
+
347
+ cdef vector[vector[int]] c_dominance_degree_non_dominated_sort(double[:, :] F, str strategy):
348
+ if strategy == "efficient":
349
+ # return c_dda_ens_get_fronts(c_construct_domination_matrix(F), F.shape[0], np.lexsort(F))
350
+ return c_dda_ens_get_fronts(c_construct_domination_matrix(F), F.shape[1], np.lexsort(F.T))
351
+ elif strategy == "fast":
352
+ # return c_dda_ns_get_fronts(c_construct_domination_matrix(F), F.shape[1], F.shape[0])
353
+ return c_dda_ns_get_fronts(c_construct_domination_matrix(F), F.shape[0], F.shape[1])
354
+
355
+
356
+
357
+
358
+ # ---------------------------------------------------------------------------------------------------------
359
+ # Efficient Non-dominated Sort
360
+ # ---------------------------------------------------------------------------------------------------------
361
+
362
+
363
+ cdef vector[vector[int]] c_efficient_non_dominated_sort(double[:,:] F, str strategy):
364
+ cdef:
365
+ long unsigned int i, j, k, n, val
366
+ vector[int] empty, e
367
+ vector[vector[int]] fronts, ret
368
+
369
+ # number of individuals
370
+ n = len(F)
371
+
372
+ # sort the input lexicographically
373
+ indices = np.lexsort(F.T[::-1])
374
+ F = np.asarray(F)[indices]
375
+
376
+ # the fronts to be set for each iteration
377
+ fronts = vector[vector[int]]()
378
+
379
+ for i in range(n):
380
+
381
+ if strategy == "sequential":
382
+ k = sequential_search(F, i, fronts)
383
+ else:
384
+ k = binary_search(F, i, fronts)
385
+
386
+ if k >= fronts.size():
387
+ empty = vector[int]()
388
+ fronts.push_back(empty)
389
+
390
+ fronts[k].push_back(i)
391
+
392
+ # convert to the return array
393
+ ret = vector[vector[int]]()
394
+ for i in range(fronts.size()):
395
+ e = vector[int]()
396
+ for j in range(fronts[i].size()):
397
+ k = fronts[i][j]
398
+ val = indices[k]
399
+ e.push_back(val)
400
+ ret.push_back(e)
401
+
402
+ return ret
403
+
404
+
405
+
406
+ cdef int sequential_search(double[:,:] F, int i, vector[vector[int]] fronts):
407
+
408
+ cdef:
409
+ int k, j, n_fronts
410
+ bool non_dominated
411
+
412
+ n_fronts = fronts.size()
413
+ if n_fronts == 0:
414
+ return 0
415
+
416
+ k = 0
417
+ while True:
418
+
419
+ non_dominated = True
420
+
421
+ # solutions in the k-th front, examine in reverse order
422
+ j = fronts[k].size() - 1
423
+
424
+ while j >= 0:
425
+ relation = c_get_relation(F, i, fronts[k][j])
426
+ if relation == -1:
427
+ non_dominated = False
428
+ break
429
+ j = j - 1
430
+
431
+ if non_dominated:
432
+ return k
433
+
434
+ # move the individual to a new front
435
+ else:
436
+ k += 1
437
+ if k >= n_fronts:
438
+ return n_fronts
439
+
440
+
441
+ cdef int binary_search(double[:,:] F, int i, vector[vector[int]] fronts):
442
+
443
+ cdef:
444
+ int n_fronts, k, k_min, k_max, j
445
+ bool non_dominated
446
+
447
+ n_fronts = fronts.size()
448
+ if n_fronts == 0:
449
+ return 0
450
+
451
+ k_min = 0 # the lower bound for checking
452
+ k_max = n_fronts # the upper bound for checking
453
+ k = int(floor((k_max + k_min) / 2.0 + 0.5)) # the front now checked
454
+
455
+ while True:
456
+
457
+ non_dominated = True
458
+
459
+ # solutions in the k-th front, examine in reverse order
460
+ j = fronts[k-1].size() - 1
461
+
462
+ while j >= 0:
463
+ relation = c_get_relation(F, i, fronts[k-1][j])
464
+ if relation == -1:
465
+ non_dominated = False
466
+ break
467
+ j = j - 1
468
+
469
+ # binary search
470
+ if non_dominated:
471
+ if k == k_min + 1:
472
+ return k - 1
473
+ else:
474
+ k_max = k
475
+ k = int(floor((k_max + k_min) / 2.0 + 0.5))
476
+
477
+ else:
478
+ k_min = k
479
+ if k_max == k_min + 1 and k_max < n_fronts:
480
+ return k_max - 1
481
+ elif k_min == n_fronts:
482
+ return n_fronts
483
+ else:
484
+ k = int(floor((k_max + k_min) / 2.0 + 0.5))
485
+
486
+
487
+
488
+
489
+
490
+
491
+ # ---------------------------------------------------------------------------------------------------------
492
+ # Util
493
+ # ---------------------------------------------------------------------------------------------------------
494
+
495
+
496
+ cdef int c_get_relation(double[:,:] F, int a, int b, double epsilon = 0.0):
497
+
498
+ cdef int size = F.shape[1]
499
+ cdef int val
500
+ cdef int i
501
+
502
+ val = 0
503
+
504
+ for i in range(size):
505
+
506
+ if F[a,i] + epsilon < F[b,i]:
507
+ # indifferent because once better and once worse
508
+ if val == -1:
509
+ return 0
510
+ val = 1
511
+
512
+ elif F[a,i] > F[b,i] + epsilon:
513
+
514
+ # indifferent because once better and once worse
515
+ if val == 1:
516
+ return 0
517
+ val = -1
518
+
519
+ return val
520
+
521
+ cdef bool c_is_dominating_or_equal(double[:,:] F, int a, int b, vector[vector[int]]& C, int k):
522
+ cdef unsigned int i, j
523
+ for i in range(k, C[0].size()):
524
+ j = C[b][i]
525
+ if F[b, j] < F[a, j]:
526
+ return False
527
+ return True
528
+
529
+ cdef bool c_is_equal(double[:,:] F, int a, int b):
530
+ cdef int i, n_obj = F.shape[1]
531
+ for i in range(n_obj):
532
+ if F[a, i] != F[b, i]:
533
+ return False
534
+ return True
535
+
536
+ cdef vector[vector[int]] c_construct_domination_matrix(double[:, :]& F):
537
+ cdef:
538
+ long i
539
+ int n = F.shape[0]
540
+ int m = F.shape[1]
541
+ long [:, ::1] b = np.apply_over_axes(np.argsort, F.T, axes=1)
542
+
543
+ vector[vector[int]] C = vector[vector[int]](n, vector[int](n, 0))
544
+ vector[vector[int]] D = vector[vector[int]](n, vector[int](n, 0))
545
+
546
+ for i in range(m):
547
+ c_construct_comparison_matrix(F[:, i], b[i], C, D, n)
548
+
549
+ c_remove_dominators(D, n, m)
550
+ return D
551
+
552
+ cdef void c_construct_comparison_matrix(double[:]& v, long[:]& b, vector[vector[int]] &C, vector[vector[int]]& D, int n):
553
+ cdef:
554
+ int i, j
555
+
556
+ for i in range(n):
557
+ C[b[0]][i] = 1
558
+ for i in range(1, n):
559
+ if v[b[i]] == v[b[i - 1]]:
560
+ for j in range(n):
561
+ C[b[i]][j] = C[b[i - 1]][j]
562
+ else:
563
+ for j in range(i, n):
564
+ C[b[i]][b[j]] = 1
565
+
566
+ # increment the DD matrix while also resetting the comparison matrix
567
+ for i in range(n):
568
+ for j in range(n):
569
+ D[i][j] += C[i][j]
570
+ C[i][j] = 0
571
+
572
+ cdef void c_remove_dominators(vector[vector[int]] &D, int n, int m):
573
+ cdef int i, j
574
+ for i in range(n):
575
+ for j in range(i, n):
576
+ if D[i][j] == m:
577
+ # only perform the row-wise check if the column-wise check fails (C=row major)
578
+ if D[j][i] == m:
579
+ D[j][i] = 0
580
+ D[i][j] = 0
581
+
582
+ cdef void c_remove_front_members(vector[vector[int]] &D, vector[int]& front, int n):
583
+ cdef:
584
+ int i, j
585
+
586
+ for i in front:
587
+ for j in range(n):
588
+ # set to -1 so not-yet-added members are preferred by max()
589
+ D[i][j] = -1
590
+ D[j][i] = -1
591
+
592
+ cdef void c_dda_ns_build_front(vector[int]& max_D, vector[int]& front, int n, int m):
593
+ cdef int i = 0, md
594
+ for md in max_D:
595
+ if 0 <= md < m:
596
+ front.push_back(i)
597
+ i += 1
598
+
599
+ cdef void c_max(vector[vector[int]]& D, vector[int]& vec_max, int n):
600
+ cdef int i, j, m
601
+ for i in range(n):
602
+ m = -1
603
+ for j in range(n):
604
+ m = max(m, D[j][i])
605
+ vec_max[i] = m
606
+
607
+ cdef vector[vector[int]] c_dda_ns_get_fronts(vector[vector[int]]& D, int n, int m):
608
+ cdef:
609
+ vector[vector[int]] fronts = vector[vector[int]]()
610
+ vector[int] vec_max = vector[int](n)
611
+ long count = 0
612
+
613
+ while count < n:
614
+ front = vector[int]()
615
+ c_max(D, vec_max, n)
616
+ c_dda_ns_build_front(vec_max, front, n, m)
617
+ c_remove_front_members(D, front, n)
618
+ fronts.push_back(front)
619
+ count += front.size()
620
+ return fronts
621
+
622
+ cdef vector[vector[int]] c_dda_ens_get_fronts(vector[vector[int]]& D, int m, long[::1]& sorted_indices):
623
+ cdef:
624
+ int k, sd, s, n_fronts = 0
625
+ vector[int] fk
626
+ vector[vector[int]] fronts
627
+
628
+ for s in range(sorted_indices.shape[0]):
629
+ isinserted = False
630
+ k = 0
631
+ for fk in fronts:
632
+ isdominated = False
633
+ for sd in fk:
634
+ if D[sd][sorted_indices[s]] == m:
635
+ isdominated = True
636
+ break
637
+ if not isdominated:
638
+ fronts[k].push_back(sorted_indices[s])
639
+ isinserted = True
640
+ break
641
+ k+= 1
642
+ if not isinserted:
643
+ n_fronts += 1
644
+ fronts.push_back(vector[int](1, sorted_indices[s]))
645
+ return fronts