pymoo 0.6.1.6__cp312-cp312-macosx_10_13_universal2.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +110 -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 +91 -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/cmopso.py +239 -0
- pymoo/algorithms/moo/ctaea.py +305 -0
- pymoo/algorithms/moo/dnsga2.py +80 -0
- pymoo/algorithms/moo/kgb.py +450 -0
- pymoo/algorithms/moo/moead.py +183 -0
- pymoo/algorithms/moo/mopso_cd.py +309 -0
- pymoo/algorithms/moo/nsga2.py +113 -0
- pymoo/algorithms/moo/nsga3.py +361 -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 +196 -0
- pymoo/algorithms/moo/spea2.py +191 -0
- pymoo/algorithms/moo/unsga3.py +49 -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 +162 -0
- pymoo/algorithms/soo/nonconvex/cmaes.py +556 -0
- pymoo/algorithms/soo/nonconvex/de.py +283 -0
- pymoo/algorithms/soo/nonconvex/direct.py +148 -0
- pymoo/algorithms/soo/nonconvex/es.py +213 -0
- pymoo/algorithms/soo/nonconvex/g3pcx.py +94 -0
- pymoo/algorithms/soo/nonconvex/ga.py +95 -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/nrbo.py +191 -0
- pymoo/algorithms/soo/nonconvex/optuna.py +80 -0
- pymoo/algorithms/soo/nonconvex/pattern.py +185 -0
- pymoo/algorithms/soo/nonconvex/pso.py +337 -0
- pymoo/algorithms/soo/nonconvex/pso_ep.py +307 -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/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 +66 -0
- pymoo/constraints/as_obj.py +56 -0
- pymoo/constraints/as_penalty.py +41 -0
- pymoo/constraints/eps.py +34 -0
- pymoo/constraints/from_bounds.py +36 -0
- pymoo/core/__init__.py +0 -0
- pymoo/core/algorithm.py +408 -0
- pymoo/core/callback.py +38 -0
- pymoo/core/crossover.py +79 -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 +65 -0
- pymoo/core/initialization.py +44 -0
- pymoo/core/mating.py +39 -0
- pymoo/core/meta.py +21 -0
- pymoo/core/mixed.py +164 -0
- pymoo/core/mutation.py +44 -0
- pymoo/core/operator.py +46 -0
- pymoo/core/parameters.py +134 -0
- pymoo/core/plot.py +208 -0
- pymoo/core/population.py +180 -0
- pymoo/core/problem.py +373 -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 +45 -0
- pymoo/core/selection.py +61 -0
- pymoo/core/solution.py +10 -0
- pymoo/core/survival.py +107 -0
- pymoo/core/termination.py +70 -0
- pymoo/core/variable.py +415 -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/functions/__init__.py +135 -0
- pymoo/functions/compiled/__init__.py +0 -0
- pymoo/functions/compiled/calc_perpendicular_distance.cpp +27464 -0
- pymoo/functions/compiled/calc_perpendicular_distance.cpython-312-darwin.so +0 -0
- pymoo/functions/compiled/decomposition.cpp +28853 -0
- pymoo/functions/compiled/decomposition.cpython-312-darwin.so +0 -0
- pymoo/functions/compiled/info.cpp +7058 -0
- pymoo/functions/compiled/info.cpython-312-darwin.so +0 -0
- pymoo/functions/compiled/mnn.cpp +30095 -0
- pymoo/functions/compiled/mnn.cpython-312-darwin.so +0 -0
- pymoo/functions/compiled/non_dominated_sorting.cpp +35692 -0
- pymoo/functions/compiled/non_dominated_sorting.cpython-312-darwin.so +0 -0
- pymoo/functions/compiled/pruning_cd.cpp +29248 -0
- pymoo/functions/compiled/pruning_cd.cpython-312-darwin.so +0 -0
- pymoo/functions/compiled/stochastic_ranking.cpp +28042 -0
- pymoo/functions/compiled/stochastic_ranking.cpython-312-darwin.so +0 -0
- pymoo/functions/standard/__init__.py +1 -0
- pymoo/functions/standard/calc_perpendicular_distance.py +20 -0
- pymoo/functions/standard/decomposition.py +18 -0
- pymoo/functions/standard/hv.py +5 -0
- pymoo/functions/standard/mnn.py +78 -0
- pymoo/functions/standard/non_dominated_sorting.py +474 -0
- pymoo/functions/standard/pruning_cd.py +93 -0
- pymoo/functions/standard/stochastic_ranking.py +42 -0
- pymoo/gradient/__init__.py +24 -0
- pymoo/gradient/automatic.py +85 -0
- pymoo/gradient/grad_autograd.py +105 -0
- pymoo/gradient/grad_complex.py +35 -0
- pymoo/gradient/grad_jax.py +51 -0
- pymoo/gradient/numpy.py +22 -0
- pymoo/gradient/toolbox/__init__.py +19 -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 +59 -0
- pymoo/indicators/hv/approximate.py +105 -0
- pymoo/indicators/hv/exact.py +68 -0
- pymoo/indicators/hv/exact_2d.py +102 -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 +190 -0
- pymoo/operators/crossover/__init__.py +0 -0
- pymoo/operators/crossover/binx.py +47 -0
- pymoo/operators/crossover/dex.py +125 -0
- pymoo/operators/crossover/erx.py +164 -0
- pymoo/operators/crossover/expx.py +53 -0
- pymoo/operators/crossover/hux.py +37 -0
- pymoo/operators/crossover/nox.py +25 -0
- pymoo/operators/crossover/ox.py +88 -0
- pymoo/operators/crossover/pcx.py +84 -0
- pymoo/operators/crossover/pntx.py +49 -0
- pymoo/operators/crossover/sbx.py +137 -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 +60 -0
- pymoo/operators/mutation/inversion.py +42 -0
- pymoo/operators/mutation/nom.py +7 -0
- pymoo/operators/mutation/pm.py +96 -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 +97 -0
- pymoo/operators/repair/inverse_penalty.py +91 -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 +76 -0
- pymoo/operators/sampling/rnd.py +52 -0
- pymoo/operators/selection/__init__.py +0 -0
- pymoo/operators/selection/rnd.py +75 -0
- pymoo/operators/selection/tournament.py +78 -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 +212 -0
- pymoo/operators/survival/rank_and_crowding/metrics.py +208 -0
- pymoo/optimize.py +72 -0
- pymoo/parallelization/__init__.py +15 -0
- pymoo/parallelization/dask.py +25 -0
- pymoo/parallelization/joblib.py +28 -0
- pymoo/parallelization/ray.py +31 -0
- pymoo/parallelization/starmap.py +24 -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 +451 -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 +553 -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 +113 -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 +49 -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 +33 -0
- pymoo/util/archive.py +152 -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 +100 -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/hv.py +21 -0
- pymoo/util/matlab_engine.py +39 -0
- pymoo/util/misc.py +447 -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/find_non_dominated.py +54 -0
- pymoo/util/nds/naive_non_dominated_sort.py +36 -0
- pymoo/util/nds/non_dominated_sorting.py +94 -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/randomized_argsort.py +63 -0
- pymoo/util/ref_dirs/__init__.py +24 -0
- pymoo/util/ref_dirs/construction.py +89 -0
- pymoo/util/ref_dirs/das_dennis.py +52 -0
- pymoo/util/ref_dirs/energy.py +317 -0
- pymoo/util/ref_dirs/energy_layer.py +119 -0
- pymoo/util/ref_dirs/genetic_algorithm.py +64 -0
- pymoo/util/ref_dirs/incremental.py +69 -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 +258 -0
- pymoo/util/remote.py +55 -0
- pymoo/util/roulette.py +29 -0
- pymoo/util/running_metric.py +128 -0
- pymoo/util/sliding_window.py +25 -0
- pymoo/util/value_functions.py +720 -0
- pymoo/util/vectors.py +40 -0
- pymoo/util/vf_dominator.py +102 -0
- pymoo/vendor/__init__.py +0 -0
- pymoo/vendor/cec2018.py +398 -0
- pymoo/vendor/gta.py +617 -0
- pymoo/vendor/vendor_cmaes.py +421 -0
- pymoo/vendor/vendor_coco.py +81 -0
- pymoo/vendor/vendor_scipy.py +232 -0
- pymoo/version.py +1 -0
- pymoo/visualization/__init__.py +21 -0
- pymoo/visualization/app/__init__.py +0 -0
- pymoo/visualization/app/pso.py +61 -0
- pymoo/visualization/fitness_landscape.py +128 -0
- pymoo/visualization/heatmap.py +123 -0
- pymoo/visualization/matplotlib.py +61 -0
- pymoo/visualization/pcp.py +121 -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 +296 -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.6.dist-info/METADATA +209 -0
- pymoo-0.6.1.6.dist-info/RECORD +337 -0
- pymoo-0.6.1.6.dist-info/WHEEL +6 -0
- pymoo-0.6.1.6.dist-info/licenses/LICENSE +191 -0
- pymoo-0.6.1.6.dist-info/top_level.txt +1 -0
pymoo/core/duplicate.py
ADDED
|
@@ -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
|
pymoo/core/evaluator.py
ADDED
|
@@ -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]
|
pymoo/core/indicator.py
ADDED
|
@@ -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
|