pymoo 0.6.1.5.dev0__cp39-cp39-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymoo might be problematic. Click here for more details.
- pymoo/__init__.py +3 -0
- pymoo/algorithms/__init__.py +0 -0
- pymoo/algorithms/base/__init__.py +0 -0
- pymoo/algorithms/base/bracket.py +38 -0
- pymoo/algorithms/base/genetic.py +109 -0
- pymoo/algorithms/base/line.py +62 -0
- pymoo/algorithms/base/local.py +39 -0
- pymoo/algorithms/base/meta.py +79 -0
- pymoo/algorithms/hyperparameters.py +89 -0
- pymoo/algorithms/moo/__init__.py +0 -0
- pymoo/algorithms/moo/age.py +310 -0
- pymoo/algorithms/moo/age2.py +194 -0
- pymoo/algorithms/moo/ctaea.py +298 -0
- pymoo/algorithms/moo/dnsga2.py +76 -0
- pymoo/algorithms/moo/kgb.py +446 -0
- pymoo/algorithms/moo/moead.py +183 -0
- pymoo/algorithms/moo/nsga2.py +113 -0
- pymoo/algorithms/moo/nsga3.py +358 -0
- pymoo/algorithms/moo/pinsga2.py +370 -0
- pymoo/algorithms/moo/rnsga2.py +188 -0
- pymoo/algorithms/moo/rnsga3.py +246 -0
- pymoo/algorithms/moo/rvea.py +214 -0
- pymoo/algorithms/moo/sms.py +195 -0
- pymoo/algorithms/moo/spea2.py +190 -0
- pymoo/algorithms/moo/unsga3.py +47 -0
- pymoo/algorithms/soo/__init__.py +0 -0
- pymoo/algorithms/soo/convex/__init__.py +0 -0
- pymoo/algorithms/soo/nonconvex/__init__.py +0 -0
- pymoo/algorithms/soo/nonconvex/brkga.py +161 -0
- pymoo/algorithms/soo/nonconvex/cmaes.py +554 -0
- pymoo/algorithms/soo/nonconvex/de.py +279 -0
- pymoo/algorithms/soo/nonconvex/direct.py +149 -0
- pymoo/algorithms/soo/nonconvex/es.py +203 -0
- pymoo/algorithms/soo/nonconvex/g3pcx.py +94 -0
- pymoo/algorithms/soo/nonconvex/ga.py +93 -0
- pymoo/algorithms/soo/nonconvex/ga_niching.py +223 -0
- pymoo/algorithms/soo/nonconvex/isres.py +74 -0
- pymoo/algorithms/soo/nonconvex/nelder.py +251 -0
- pymoo/algorithms/soo/nonconvex/optuna.py +80 -0
- pymoo/algorithms/soo/nonconvex/pattern.py +183 -0
- pymoo/algorithms/soo/nonconvex/pso.py +399 -0
- pymoo/algorithms/soo/nonconvex/pso_ep.py +297 -0
- pymoo/algorithms/soo/nonconvex/random_search.py +25 -0
- pymoo/algorithms/soo/nonconvex/sres.py +56 -0
- pymoo/algorithms/soo/univariate/__init__.py +0 -0
- pymoo/algorithms/soo/univariate/backtracking.py +59 -0
- pymoo/algorithms/soo/univariate/exp.py +46 -0
- pymoo/algorithms/soo/univariate/golden.py +65 -0
- pymoo/algorithms/soo/univariate/quadr_interp.py +81 -0
- pymoo/algorithms/soo/univariate/wolfe.py +163 -0
- pymoo/config.py +33 -0
- pymoo/constraints/__init__.py +3 -0
- pymoo/constraints/adaptive.py +62 -0
- pymoo/constraints/as_obj.py +56 -0
- pymoo/constraints/as_penalty.py +41 -0
- pymoo/constraints/eps.py +26 -0
- pymoo/constraints/from_bounds.py +36 -0
- pymoo/core/__init__.py +0 -0
- pymoo/core/algorithm.py +394 -0
- pymoo/core/callback.py +38 -0
- pymoo/core/crossover.py +77 -0
- pymoo/core/decision_making.py +102 -0
- pymoo/core/decomposition.py +76 -0
- pymoo/core/duplicate.py +163 -0
- pymoo/core/evaluator.py +116 -0
- pymoo/core/indicator.py +34 -0
- pymoo/core/individual.py +784 -0
- pymoo/core/infill.py +64 -0
- pymoo/core/initialization.py +42 -0
- pymoo/core/mating.py +39 -0
- pymoo/core/meta.py +21 -0
- pymoo/core/mixed.py +165 -0
- pymoo/core/mutation.py +44 -0
- pymoo/core/operator.py +40 -0
- pymoo/core/parameters.py +134 -0
- pymoo/core/plot.py +210 -0
- pymoo/core/population.py +180 -0
- pymoo/core/problem.py +460 -0
- pymoo/core/recorder.py +99 -0
- pymoo/core/repair.py +23 -0
- pymoo/core/replacement.py +96 -0
- pymoo/core/result.py +52 -0
- pymoo/core/sampling.py +43 -0
- pymoo/core/selection.py +61 -0
- pymoo/core/solution.py +10 -0
- pymoo/core/survival.py +103 -0
- pymoo/core/termination.py +70 -0
- pymoo/core/variable.py +399 -0
- pymoo/cython/__init__.py +0 -0
- pymoo/cython/calc_perpendicular_distance.cpython-39-x86_64-linux-gnu.so +0 -0
- pymoo/cython/calc_perpendicular_distance.pyx +67 -0
- pymoo/cython/decomposition.cpython-39-x86_64-linux-gnu.so +0 -0
- pymoo/cython/decomposition.pyx +165 -0
- pymoo/cython/hv.cpython-39-x86_64-linux-gnu.so +0 -0
- pymoo/cython/hv.pyx +18 -0
- pymoo/cython/info.cpython-39-x86_64-linux-gnu.so +0 -0
- pymoo/cython/info.pyx +5 -0
- pymoo/cython/mnn.cpython-39-x86_64-linux-gnu.so +0 -0
- pymoo/cython/mnn.pyx +273 -0
- pymoo/cython/non_dominated_sorting.cpython-39-x86_64-linux-gnu.so +0 -0
- pymoo/cython/non_dominated_sorting.pyx +645 -0
- pymoo/cython/pruning_cd.cpython-39-x86_64-linux-gnu.so +0 -0
- pymoo/cython/pruning_cd.pyx +197 -0
- pymoo/cython/stochastic_ranking.cpython-39-x86_64-linux-gnu.so +0 -0
- pymoo/cython/stochastic_ranking.pyx +49 -0
- pymoo/cython/utils.pxd +129 -0
- pymoo/cython/vendor/__init__.py +0 -0
- pymoo/cython/vendor/hypervolume.cpp +1621 -0
- pymoo/cython/vendor/hypervolume.h +63 -0
- pymoo/decomposition/__init__.py +0 -0
- pymoo/decomposition/aasf.py +24 -0
- pymoo/decomposition/asf.py +10 -0
- pymoo/decomposition/pbi.py +13 -0
- pymoo/decomposition/perp_dist.py +13 -0
- pymoo/decomposition/tchebicheff.py +11 -0
- pymoo/decomposition/util.py +13 -0
- pymoo/decomposition/weighted_sum.py +8 -0
- pymoo/docs.py +187 -0
- pymoo/experimental/__init__.py +0 -0
- pymoo/experimental/algorithms/__init__.py +0 -0
- pymoo/experimental/algorithms/gde3.py +57 -0
- pymoo/gradient/__init__.py +21 -0
- pymoo/gradient/automatic.py +57 -0
- pymoo/gradient/grad_autograd.py +105 -0
- pymoo/gradient/grad_complex.py +35 -0
- pymoo/gradient/grad_jax.py +51 -0
- pymoo/gradient/toolbox/__init__.py +6 -0
- pymoo/indicators/__init__.py +0 -0
- pymoo/indicators/distance_indicator.py +55 -0
- pymoo/indicators/gd.py +7 -0
- pymoo/indicators/gd_plus.py +7 -0
- pymoo/indicators/hv/__init__.py +63 -0
- pymoo/indicators/hv/exact.py +71 -0
- pymoo/indicators/hv/exact_2d.py +102 -0
- pymoo/indicators/hv/monte_carlo.py +74 -0
- pymoo/indicators/igd.py +7 -0
- pymoo/indicators/igd_plus.py +7 -0
- pymoo/indicators/kktpm.py +151 -0
- pymoo/indicators/migd.py +55 -0
- pymoo/indicators/rmetric.py +203 -0
- pymoo/indicators/spacing.py +52 -0
- pymoo/mcdm/__init__.py +0 -0
- pymoo/mcdm/compromise_programming.py +19 -0
- pymoo/mcdm/high_tradeoff.py +40 -0
- pymoo/mcdm/pseudo_weights.py +32 -0
- pymoo/operators/__init__.py +0 -0
- pymoo/operators/control.py +187 -0
- pymoo/operators/crossover/__init__.py +0 -0
- pymoo/operators/crossover/binx.py +45 -0
- pymoo/operators/crossover/dex.py +122 -0
- pymoo/operators/crossover/erx.py +162 -0
- pymoo/operators/crossover/expx.py +51 -0
- pymoo/operators/crossover/hux.py +37 -0
- pymoo/operators/crossover/nox.py +13 -0
- pymoo/operators/crossover/ox.py +84 -0
- pymoo/operators/crossover/pcx.py +82 -0
- pymoo/operators/crossover/pntx.py +49 -0
- pymoo/operators/crossover/sbx.py +125 -0
- pymoo/operators/crossover/spx.py +5 -0
- pymoo/operators/crossover/ux.py +20 -0
- pymoo/operators/mutation/__init__.py +0 -0
- pymoo/operators/mutation/bitflip.py +17 -0
- pymoo/operators/mutation/gauss.py +58 -0
- pymoo/operators/mutation/inversion.py +42 -0
- pymoo/operators/mutation/nom.py +7 -0
- pymoo/operators/mutation/pm.py +94 -0
- pymoo/operators/mutation/rm.py +23 -0
- pymoo/operators/repair/__init__.py +0 -0
- pymoo/operators/repair/bounce_back.py +32 -0
- pymoo/operators/repair/bounds_repair.py +95 -0
- pymoo/operators/repair/inverse_penalty.py +89 -0
- pymoo/operators/repair/rounding.py +18 -0
- pymoo/operators/repair/to_bound.py +31 -0
- pymoo/operators/repair/vtype.py +11 -0
- pymoo/operators/sampling/__init__.py +0 -0
- pymoo/operators/sampling/lhs.py +73 -0
- pymoo/operators/sampling/rnd.py +50 -0
- pymoo/operators/selection/__init__.py +0 -0
- pymoo/operators/selection/rnd.py +72 -0
- pymoo/operators/selection/tournament.py +76 -0
- pymoo/operators/survival/__init__.py +0 -0
- pymoo/operators/survival/rank_and_crowding/__init__.py +1 -0
- pymoo/operators/survival/rank_and_crowding/classes.py +209 -0
- pymoo/operators/survival/rank_and_crowding/metrics.py +208 -0
- pymoo/optimize.py +72 -0
- pymoo/problems/__init__.py +157 -0
- pymoo/problems/dyn.py +47 -0
- pymoo/problems/dynamic/__init__.py +0 -0
- pymoo/problems/dynamic/cec2015.py +108 -0
- pymoo/problems/dynamic/df.py +452 -0
- pymoo/problems/dynamic/misc.py +167 -0
- pymoo/problems/functional.py +48 -0
- pymoo/problems/many/__init__.py +5 -0
- pymoo/problems/many/cdtlz.py +159 -0
- pymoo/problems/many/dcdtlz.py +88 -0
- pymoo/problems/many/dtlz.py +264 -0
- pymoo/problems/many/wfg.py +550 -0
- pymoo/problems/multi/__init__.py +14 -0
- pymoo/problems/multi/bnh.py +34 -0
- pymoo/problems/multi/carside.py +48 -0
- pymoo/problems/multi/clutch.py +104 -0
- pymoo/problems/multi/csi.py +55 -0
- pymoo/problems/multi/ctp.py +198 -0
- pymoo/problems/multi/dascmop.py +213 -0
- pymoo/problems/multi/kursawe.py +25 -0
- pymoo/problems/multi/modact.py +68 -0
- pymoo/problems/multi/mw.py +400 -0
- pymoo/problems/multi/omnitest.py +48 -0
- pymoo/problems/multi/osy.py +32 -0
- pymoo/problems/multi/srn.py +28 -0
- pymoo/problems/multi/sympart.py +94 -0
- pymoo/problems/multi/tnk.py +24 -0
- pymoo/problems/multi/truss2d.py +83 -0
- pymoo/problems/multi/welded_beam.py +41 -0
- pymoo/problems/multi/wrm.py +36 -0
- pymoo/problems/multi/zdt.py +151 -0
- pymoo/problems/multi_to_single.py +22 -0
- pymoo/problems/single/__init__.py +12 -0
- pymoo/problems/single/ackley.py +24 -0
- pymoo/problems/single/cantilevered_beam.py +34 -0
- pymoo/problems/single/flowshop_scheduling.py +112 -0
- pymoo/problems/single/g.py +874 -0
- pymoo/problems/single/griewank.py +18 -0
- pymoo/problems/single/himmelblau.py +15 -0
- pymoo/problems/single/knapsack.py +48 -0
- pymoo/problems/single/mopta08.py +26 -0
- pymoo/problems/single/multimodal.py +20 -0
- pymoo/problems/single/pressure_vessel.py +30 -0
- pymoo/problems/single/rastrigin.py +20 -0
- pymoo/problems/single/rosenbrock.py +22 -0
- pymoo/problems/single/schwefel.py +18 -0
- pymoo/problems/single/simple.py +13 -0
- pymoo/problems/single/sphere.py +19 -0
- pymoo/problems/single/traveling_salesman.py +79 -0
- pymoo/problems/single/zakharov.py +19 -0
- pymoo/problems/static.py +14 -0
- pymoo/problems/util.py +42 -0
- pymoo/problems/zero_to_one.py +27 -0
- pymoo/termination/__init__.py +23 -0
- pymoo/termination/collection.py +12 -0
- pymoo/termination/cv.py +48 -0
- pymoo/termination/default.py +45 -0
- pymoo/termination/delta.py +64 -0
- pymoo/termination/fmin.py +16 -0
- pymoo/termination/ftol.py +144 -0
- pymoo/termination/indicator.py +49 -0
- pymoo/termination/max_eval.py +14 -0
- pymoo/termination/max_gen.py +15 -0
- pymoo/termination/max_time.py +20 -0
- pymoo/termination/robust.py +34 -0
- pymoo/termination/xtol.py +33 -0
- pymoo/util/__init__.py +0 -0
- pymoo/util/archive.py +150 -0
- pymoo/util/cache.py +29 -0
- pymoo/util/clearing.py +82 -0
- pymoo/util/display/__init__.py +0 -0
- pymoo/util/display/column.py +52 -0
- pymoo/util/display/display.py +34 -0
- pymoo/util/display/multi.py +96 -0
- pymoo/util/display/output.py +53 -0
- pymoo/util/display/progress.py +54 -0
- pymoo/util/display/single.py +67 -0
- pymoo/util/dominator.py +67 -0
- pymoo/util/function_loader.py +129 -0
- pymoo/util/hv.py +23 -0
- pymoo/util/matlab_engine.py +39 -0
- pymoo/util/misc.py +460 -0
- pymoo/util/mnn.py +70 -0
- pymoo/util/nds/__init__.py +0 -0
- pymoo/util/nds/dominance_degree_non_dominated_sort.py +159 -0
- pymoo/util/nds/efficient_non_dominated_sort.py +152 -0
- pymoo/util/nds/fast_non_dominated_sort.py +70 -0
- pymoo/util/nds/naive_non_dominated_sort.py +36 -0
- pymoo/util/nds/non_dominated_sorting.py +67 -0
- pymoo/util/nds/tree_based_non_dominated_sort.py +133 -0
- pymoo/util/normalization.py +312 -0
- pymoo/util/optimum.py +42 -0
- pymoo/util/plotting.py +177 -0
- pymoo/util/pruning_cd.py +89 -0
- pymoo/util/randomized_argsort.py +60 -0
- pymoo/util/ref_dirs/__init__.py +24 -0
- pymoo/util/ref_dirs/construction.py +88 -0
- pymoo/util/ref_dirs/das_dennis.py +52 -0
- pymoo/util/ref_dirs/energy.py +319 -0
- pymoo/util/ref_dirs/energy_layer.py +119 -0
- pymoo/util/ref_dirs/genetic_algorithm.py +63 -0
- pymoo/util/ref_dirs/incremental.py +68 -0
- pymoo/util/ref_dirs/misc.py +128 -0
- pymoo/util/ref_dirs/optimizer.py +59 -0
- pymoo/util/ref_dirs/performance.py +162 -0
- pymoo/util/ref_dirs/reduction.py +85 -0
- pymoo/util/ref_dirs/sample_and_map.py +24 -0
- pymoo/util/reference_direction.py +260 -0
- pymoo/util/remote.py +55 -0
- pymoo/util/roulette.py +27 -0
- pymoo/util/running_metric.py +128 -0
- pymoo/util/sliding_window.py +25 -0
- pymoo/util/stochastic_ranking.py +32 -0
- pymoo/util/value_functions.py +719 -0
- pymoo/util/vectors.py +40 -0
- pymoo/util/vf_dominator.py +99 -0
- pymoo/vendor/__init__.py +0 -0
- pymoo/vendor/cec2018.py +398 -0
- pymoo/vendor/gta.py +617 -0
- pymoo/vendor/hv.py +267 -0
- pymoo/vendor/vendor_cmaes.py +412 -0
- pymoo/vendor/vendor_coco.py +81 -0
- pymoo/vendor/vendor_scipy.py +232 -0
- pymoo/version.py +1 -0
- pymoo/visualization/__init__.py +8 -0
- pymoo/visualization/fitness_landscape.py +127 -0
- pymoo/visualization/heatmap.py +123 -0
- pymoo/visualization/pcp.py +120 -0
- pymoo/visualization/petal.py +91 -0
- pymoo/visualization/radar.py +108 -0
- pymoo/visualization/radviz.py +68 -0
- pymoo/visualization/scatter.py +150 -0
- pymoo/visualization/star_coordinate.py +75 -0
- pymoo/visualization/util.py +123 -0
- pymoo/visualization/video/__init__.py +0 -0
- pymoo/visualization/video/callback_video.py +82 -0
- pymoo/visualization/video/one_var_one_obj.py +57 -0
- pymoo/visualization/video/two_var_one_obj.py +62 -0
- pymoo-0.6.1.5.dev0.dist-info/METADATA +187 -0
- pymoo-0.6.1.5.dev0.dist-info/RECORD +330 -0
- pymoo-0.6.1.5.dev0.dist-info/WHEEL +5 -0
- pymoo-0.6.1.5.dev0.dist-info/licenses/LICENSE +191 -0
- pymoo-0.6.1.5.dev0.dist-info/top_level.txt +1 -0
- pymoo.libs/libgcc_s-2298274a.so.1 +0 -0
- pymoo.libs/libstdc++-08d5c7eb.so.6.0.33 +0 -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
|
|
Binary file
|