pymoo 0.6.1.5.dev0__cp312-cp312-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.
- 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-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/calc_perpendicular_distance.pyx +67 -0
- pymoo/cython/decomposition.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/decomposition.pyx +165 -0
- pymoo/cython/hv.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/hv.pyx +18 -0
- pymoo/cython/info.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/info.pyx +5 -0
- pymoo/cython/mnn.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/mnn.pyx +273 -0
- pymoo/cython/non_dominated_sorting.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/non_dominated_sorting.pyx +645 -0
- pymoo/cython/pruning_cd.cpython-312-x86_64-linux-gnu.so +0 -0
- pymoo/cython/pruning_cd.pyx +197 -0
- pymoo/cython/stochastic_ranking.cpython-312-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 +328 -0
- pymoo-0.6.1.5.dev0.dist-info/WHEEL +6 -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
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from pymoo.indicators.gd import GD
|
|
2
|
+
from pymoo.indicators.hv import Hypervolume
|
|
3
|
+
from pymoo.indicators.igd import IGD
|
|
4
|
+
from pymoo.termination.ftol import MultiObjectiveSpaceTermination
|
|
5
|
+
|
|
6
|
+
from pymoo.util.display.column import Column
|
|
7
|
+
from pymoo.util.display.output import Output, pareto_front_if_possible
|
|
8
|
+
from pymoo.util.display.single import MinimumConstraintViolation, AverageConstraintViolation
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class NumberOfNondominatedSolutions(Column):
|
|
12
|
+
|
|
13
|
+
def __init__(self, width=6, **kwargs) -> None:
|
|
14
|
+
super().__init__("n_nds", width=width, **kwargs)
|
|
15
|
+
|
|
16
|
+
def update(self, algorithm):
|
|
17
|
+
self.value = len(algorithm.opt)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class MultiObjectiveOutput(Output):
|
|
21
|
+
|
|
22
|
+
def __init__(self):
|
|
23
|
+
super().__init__()
|
|
24
|
+
self.cv_min = MinimumConstraintViolation()
|
|
25
|
+
self.cv_avg = AverageConstraintViolation()
|
|
26
|
+
self.n_nds = NumberOfNondominatedSolutions()
|
|
27
|
+
|
|
28
|
+
self.igd = Column("igd")
|
|
29
|
+
self.gd = Column("gd")
|
|
30
|
+
self.hv = Column("hv")
|
|
31
|
+
self.eps = Column("eps")
|
|
32
|
+
self.indicator = Column("indicator")
|
|
33
|
+
|
|
34
|
+
self.pf = None
|
|
35
|
+
self.indicator_no_pf = None
|
|
36
|
+
|
|
37
|
+
def initialize(self, algorithm):
|
|
38
|
+
problem = algorithm.problem
|
|
39
|
+
|
|
40
|
+
self.columns += [self.n_nds]
|
|
41
|
+
|
|
42
|
+
if problem.has_constraints():
|
|
43
|
+
self.columns += [self.cv_min, self.cv_avg]
|
|
44
|
+
|
|
45
|
+
self.pf = pareto_front_if_possible(problem)
|
|
46
|
+
if self.pf is not None:
|
|
47
|
+
self.columns += [self.igd, self.gd]
|
|
48
|
+
|
|
49
|
+
if problem.n_obj == 2:
|
|
50
|
+
self.columns += [self.hv]
|
|
51
|
+
|
|
52
|
+
else:
|
|
53
|
+
self.indicator_no_pf = MultiObjectiveSpaceTermination()
|
|
54
|
+
self.columns += [self.eps, self.indicator]
|
|
55
|
+
|
|
56
|
+
def update(self, algorithm):
|
|
57
|
+
super().update(algorithm)
|
|
58
|
+
|
|
59
|
+
for col in [self.igd, self.gd, self.hv, self.eps, self.indicator]:
|
|
60
|
+
col.set(None)
|
|
61
|
+
|
|
62
|
+
F, feas = algorithm.opt.get("F", "feas")
|
|
63
|
+
F = F[feas]
|
|
64
|
+
|
|
65
|
+
if len(F) > 0:
|
|
66
|
+
|
|
67
|
+
if self.pf is not None:
|
|
68
|
+
|
|
69
|
+
if feas.sum() > 0:
|
|
70
|
+
self.igd.set(IGD(self.pf, zero_to_one=True).do(F))
|
|
71
|
+
self.gd.set(GD(self.pf, zero_to_one=True).do(F))
|
|
72
|
+
|
|
73
|
+
if self.hv in self.columns:
|
|
74
|
+
self.hv.set(Hypervolume(pf=self.pf, zero_to_one=True).do(F))
|
|
75
|
+
|
|
76
|
+
if self.indicator_no_pf is not None:
|
|
77
|
+
|
|
78
|
+
ind = self.indicator_no_pf
|
|
79
|
+
ind.update(algorithm)
|
|
80
|
+
|
|
81
|
+
valid = ind.delta_ideal is not None
|
|
82
|
+
|
|
83
|
+
if valid:
|
|
84
|
+
|
|
85
|
+
if ind.delta_ideal > ind.tol:
|
|
86
|
+
max_from = "ideal"
|
|
87
|
+
eps = ind.delta_ideal
|
|
88
|
+
elif ind.delta_nadir > ind.tol:
|
|
89
|
+
max_from = "nadir"
|
|
90
|
+
eps = ind.delta_nadir
|
|
91
|
+
else:
|
|
92
|
+
max_from = "f"
|
|
93
|
+
eps = ind.delta_f
|
|
94
|
+
|
|
95
|
+
self.eps.set(eps)
|
|
96
|
+
self.indicator.set(max_from)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from pymoo.core.callback import Callback
|
|
2
|
+
from pymoo.util.display.column import Column
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def pareto_front_if_possible(problem):
|
|
6
|
+
try:
|
|
7
|
+
return problem.pareto_front()
|
|
8
|
+
except:
|
|
9
|
+
return None
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class NumberOfGenerations(Column):
|
|
13
|
+
|
|
14
|
+
def __init__(self, **kwargs) -> None:
|
|
15
|
+
super().__init__("n_gen", **kwargs)
|
|
16
|
+
|
|
17
|
+
def update(self, algorithm):
|
|
18
|
+
self.value = algorithm.n_gen
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class NumberOfEvaluations(Column):
|
|
22
|
+
|
|
23
|
+
def __init__(self, **kwargs) -> None:
|
|
24
|
+
super().__init__("n_eval", **kwargs)
|
|
25
|
+
|
|
26
|
+
def update(self, algorithm):
|
|
27
|
+
self.value = algorithm.evaluator.n_eval
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Output(Callback):
|
|
31
|
+
|
|
32
|
+
def __init__(self):
|
|
33
|
+
super().__init__()
|
|
34
|
+
self.n_gen = NumberOfGenerations(width=6)
|
|
35
|
+
self.n_eval = NumberOfEvaluations(width=8)
|
|
36
|
+
self.columns = [self.n_gen, self.n_eval]
|
|
37
|
+
|
|
38
|
+
def update(self, algorithm):
|
|
39
|
+
[col.update(algorithm) for col in self.columns]
|
|
40
|
+
|
|
41
|
+
def header(self, border=False):
|
|
42
|
+
regex = " | ".join(["{}"] * len(self.columns))
|
|
43
|
+
header = regex.format(*[col.name.center(col.width) for col in self.columns])
|
|
44
|
+
|
|
45
|
+
if border:
|
|
46
|
+
line = "=" * len(header)
|
|
47
|
+
header = line + '\n' + header + '\n' + line
|
|
48
|
+
|
|
49
|
+
return header
|
|
50
|
+
|
|
51
|
+
def text(self):
|
|
52
|
+
regex = " | ".join(["{}"] * len(self.columns))
|
|
53
|
+
return regex.format(*[col.text() for col in self.columns])
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
from alive_progress import alive_bar
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ProgressBar:
|
|
7
|
+
|
|
8
|
+
def __init__(self, *args, start=True, non_decreasing=True, **kwargs):
|
|
9
|
+
self.args = args
|
|
10
|
+
self.kwargs = kwargs
|
|
11
|
+
|
|
12
|
+
for key, default in [("manual", True), ("force_tty", True)]:
|
|
13
|
+
if key not in kwargs:
|
|
14
|
+
kwargs[key] = default
|
|
15
|
+
|
|
16
|
+
self.func = None
|
|
17
|
+
self.obj = None
|
|
18
|
+
self.non_decreasing = non_decreasing
|
|
19
|
+
self._max = 0.0
|
|
20
|
+
|
|
21
|
+
if start:
|
|
22
|
+
self.start()
|
|
23
|
+
|
|
24
|
+
def set(self, value, *args, **kwargs):
|
|
25
|
+
if self.non_decreasing:
|
|
26
|
+
self._max = max(self._max, value)
|
|
27
|
+
value = self._max
|
|
28
|
+
|
|
29
|
+
prec = 100
|
|
30
|
+
value = math.floor(value * prec) / prec
|
|
31
|
+
|
|
32
|
+
self.obj(value, *args, **kwargs)
|
|
33
|
+
|
|
34
|
+
def start(self):
|
|
35
|
+
|
|
36
|
+
if not self.obj:
|
|
37
|
+
# save the generator to this object
|
|
38
|
+
self.func = alive_bar(*self.args, **self.kwargs).gen
|
|
39
|
+
|
|
40
|
+
# create the bar
|
|
41
|
+
self.obj = next(self.func)
|
|
42
|
+
|
|
43
|
+
def close(self):
|
|
44
|
+
if self.obj:
|
|
45
|
+
try:
|
|
46
|
+
next(self.func)
|
|
47
|
+
except:
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
def __enter__(self):
|
|
51
|
+
self.start()
|
|
52
|
+
|
|
53
|
+
def __exit__(self, type, value, traceback):
|
|
54
|
+
self.close()
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from pymoo.util.display.column import Column
|
|
2
|
+
from pymoo.util.display.output import Output, pareto_front_if_possible
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class MinimumConstraintViolation(Column):
|
|
6
|
+
|
|
7
|
+
def __init__(self, **kwargs) -> None:
|
|
8
|
+
super().__init__("cv_min", **kwargs)
|
|
9
|
+
|
|
10
|
+
def update(self, algorithm):
|
|
11
|
+
self.value = algorithm.opt.get("cv").min()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AverageConstraintViolation(Column):
|
|
15
|
+
|
|
16
|
+
def __init__(self, **kwargs) -> None:
|
|
17
|
+
super().__init__("cv_avg", **kwargs)
|
|
18
|
+
|
|
19
|
+
def update(self, algorithm):
|
|
20
|
+
self.value = algorithm.pop.get("cv").mean()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class SingleObjectiveOutput(Output):
|
|
24
|
+
|
|
25
|
+
def __init__(self):
|
|
26
|
+
super().__init__()
|
|
27
|
+
self.cv_min = MinimumConstraintViolation()
|
|
28
|
+
self.cv_avg = AverageConstraintViolation()
|
|
29
|
+
|
|
30
|
+
self.f_min = Column(name="f_min")
|
|
31
|
+
self.f_avg = Column(name="f_avg")
|
|
32
|
+
self.f_gap = Column(name="f_gap")
|
|
33
|
+
|
|
34
|
+
self.best = None
|
|
35
|
+
|
|
36
|
+
def initialize(self, algorithm):
|
|
37
|
+
problem = algorithm.problem
|
|
38
|
+
|
|
39
|
+
if problem.has_constraints():
|
|
40
|
+
self.columns += [self.cv_min, self.cv_avg]
|
|
41
|
+
|
|
42
|
+
self.columns += [self.f_avg, self.f_min]
|
|
43
|
+
|
|
44
|
+
pf = pareto_front_if_possible(problem)
|
|
45
|
+
if pf is not None:
|
|
46
|
+
self.best = pf.flatten()[0]
|
|
47
|
+
self.columns += [self.f_gap]
|
|
48
|
+
|
|
49
|
+
def update(self, algorithm):
|
|
50
|
+
super().update(algorithm)
|
|
51
|
+
|
|
52
|
+
f, cv, feas = algorithm.pop.get("f", "cv", "feas")
|
|
53
|
+
|
|
54
|
+
if feas.sum() > 0:
|
|
55
|
+
self.f_avg.set(f[feas].mean())
|
|
56
|
+
else:
|
|
57
|
+
self.f_avg.set(None)
|
|
58
|
+
|
|
59
|
+
opt = algorithm.opt[0]
|
|
60
|
+
|
|
61
|
+
if opt.feas:
|
|
62
|
+
self.f_min.set(opt.f)
|
|
63
|
+
if self.best is not None:
|
|
64
|
+
self.f_gap.set(opt.f - self.best)
|
|
65
|
+
else:
|
|
66
|
+
self.f_min.set(None)
|
|
67
|
+
self.f_gap.set(None)
|
pymoo/util/dominator.py
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def get_relation(ind_a, ind_b):
|
|
5
|
+
return Dominator.get_relation(ind_a.F, ind_b.F, ind_a.CV[0], ind_b.CV[0])
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Dominator:
|
|
9
|
+
|
|
10
|
+
@staticmethod
|
|
11
|
+
def get_relation(a, b, cva=None, cvb=None):
|
|
12
|
+
|
|
13
|
+
if cva is not None and cvb is not None:
|
|
14
|
+
if cva < cvb:
|
|
15
|
+
return 1
|
|
16
|
+
elif cvb < cva:
|
|
17
|
+
return -1
|
|
18
|
+
|
|
19
|
+
val = 0
|
|
20
|
+
for i in range(len(a)):
|
|
21
|
+
if a[i] < b[i]:
|
|
22
|
+
# indifferent because once better and once worse
|
|
23
|
+
if val == -1:
|
|
24
|
+
return 0
|
|
25
|
+
val = 1
|
|
26
|
+
elif b[i] < a[i]:
|
|
27
|
+
# indifferent because once better and once worse
|
|
28
|
+
if val == 1:
|
|
29
|
+
return 0
|
|
30
|
+
val = -1
|
|
31
|
+
return val
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def calc_domination_matrix_loop(F, G):
|
|
35
|
+
n = F.shape[0]
|
|
36
|
+
CV = np.sum(G * (G > 0).astype(float), axis=1)
|
|
37
|
+
M = np.zeros((n, n))
|
|
38
|
+
for i in range(n):
|
|
39
|
+
for j in range(i + 1, n):
|
|
40
|
+
M[i, j] = Dominator.get_relation(F[i, :], F[j, :], CV[i], CV[j])
|
|
41
|
+
M[j, i] = -M[i, j]
|
|
42
|
+
|
|
43
|
+
return M
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def calc_domination_matrix(F, _F=None, epsilon=0.0):
|
|
47
|
+
|
|
48
|
+
if _F is None:
|
|
49
|
+
_F = F
|
|
50
|
+
|
|
51
|
+
# look at the obj for dom
|
|
52
|
+
n = F.shape[0]
|
|
53
|
+
m = _F.shape[0]
|
|
54
|
+
|
|
55
|
+
L = np.repeat(F, m, axis=0)
|
|
56
|
+
R = np.tile(_F, (n, 1))
|
|
57
|
+
|
|
58
|
+
smaller = np.reshape(np.any(L + epsilon < R, axis=1), (n, m))
|
|
59
|
+
larger = np.reshape(np.any(L > R + epsilon, axis=1), (n, m))
|
|
60
|
+
|
|
61
|
+
M = np.logical_and(smaller, np.logical_not(larger)) * 1 \
|
|
62
|
+
+ np.logical_and(larger, np.logical_not(smaller)) * -1
|
|
63
|
+
|
|
64
|
+
# if cv equal then look at dom
|
|
65
|
+
# M = constr + (constr == 0) * dom
|
|
66
|
+
|
|
67
|
+
return M
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
|
|
3
|
+
from pymoo.config import Config
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_functions():
|
|
7
|
+
from pymoo.util.nds.fast_non_dominated_sort import fast_non_dominated_sort
|
|
8
|
+
from pymoo.util.nds.efficient_non_dominated_sort import efficient_non_dominated_sort
|
|
9
|
+
from pymoo.util.nds.tree_based_non_dominated_sort import (
|
|
10
|
+
tree_based_non_dominated_sort,
|
|
11
|
+
)
|
|
12
|
+
from pymoo.util.nds.dominance_degree_non_dominated_sort import (
|
|
13
|
+
dominance_degree_non_dominated_sort,
|
|
14
|
+
)
|
|
15
|
+
from pymoo.decomposition.util import calc_distance_to_weights
|
|
16
|
+
from pymoo.util.misc import calc_perpendicular_distance
|
|
17
|
+
from pymoo.util.hv import hv
|
|
18
|
+
from pymoo.util.stochastic_ranking import stochastic_ranking
|
|
19
|
+
from pymoo.util.mnn import calc_mnn, calc_2nn
|
|
20
|
+
from pymoo.util.pruning_cd import calc_pcd
|
|
21
|
+
|
|
22
|
+
FUNCTIONS = {
|
|
23
|
+
"fast_non_dominated_sort": {
|
|
24
|
+
"python": fast_non_dominated_sort,
|
|
25
|
+
"cython": "pymoo.cython.non_dominated_sorting",
|
|
26
|
+
},
|
|
27
|
+
"efficient_non_dominated_sort": {
|
|
28
|
+
"python": efficient_non_dominated_sort,
|
|
29
|
+
"cython": "pymoo.cython.non_dominated_sorting",
|
|
30
|
+
},
|
|
31
|
+
"fast_best_order_sort": {
|
|
32
|
+
"python": None,
|
|
33
|
+
"cython": "pymoo.cython.non_dominated_sorting",
|
|
34
|
+
},
|
|
35
|
+
"tree_based_non_dominated_sort": {
|
|
36
|
+
"python": tree_based_non_dominated_sort,
|
|
37
|
+
"cython": "pymoo.cython.non_dominated_sorting",
|
|
38
|
+
},
|
|
39
|
+
"dominance_degree_non_dominated_sort": {
|
|
40
|
+
"python": dominance_degree_non_dominated_sort,
|
|
41
|
+
"cython": "pymoo.cython.non_dominated_sorting",
|
|
42
|
+
},
|
|
43
|
+
"calc_distance_to_weights": {
|
|
44
|
+
"python": calc_distance_to_weights,
|
|
45
|
+
"cython": "pymoo.cython.decomposition",
|
|
46
|
+
},
|
|
47
|
+
"calc_perpendicular_distance": {
|
|
48
|
+
"python": calc_perpendicular_distance,
|
|
49
|
+
"cython": "pymoo.cython.calc_perpendicular_distance",
|
|
50
|
+
},
|
|
51
|
+
"stochastic_ranking": {
|
|
52
|
+
"python": stochastic_ranking,
|
|
53
|
+
"cython": "pymoo.cython.stochastic_ranking",
|
|
54
|
+
},
|
|
55
|
+
"hv": {"python": hv, "cython": "pymoo.cython.hv"},
|
|
56
|
+
"calc_mnn": {"python": calc_mnn, "cython": "pymoo.cython.mnn"},
|
|
57
|
+
"calc_2nn": {"python": calc_2nn, "cython": "pymoo.cython.mnn"},
|
|
58
|
+
"calc_pcd": {"python": calc_pcd, "cython": "pymoo.cython.pruning_cd"},
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return FUNCTIONS
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class FunctionLoader:
|
|
65
|
+
# -------------------------------------------------
|
|
66
|
+
# Singleton Pattern
|
|
67
|
+
# -------------------------------------------------
|
|
68
|
+
__instance = None
|
|
69
|
+
|
|
70
|
+
@staticmethod
|
|
71
|
+
def get_instance():
|
|
72
|
+
if FunctionLoader.__instance is None:
|
|
73
|
+
FunctionLoader.__instance = FunctionLoader()
|
|
74
|
+
return FunctionLoader.__instance
|
|
75
|
+
|
|
76
|
+
# -------------------------------------------------
|
|
77
|
+
|
|
78
|
+
def __init__(self) -> None:
|
|
79
|
+
super().__init__()
|
|
80
|
+
self.is_compiled = is_compiled()
|
|
81
|
+
self.mode = "auto"
|
|
82
|
+
|
|
83
|
+
if Config.warnings["not_compiled"] and not self.is_compiled:
|
|
84
|
+
print("\nCompiled modules for significant speedup can not be used!")
|
|
85
|
+
print("https://pymoo.org/installation.html#installation")
|
|
86
|
+
print()
|
|
87
|
+
print("To disable this warning:")
|
|
88
|
+
print("from pymoo.config import Config")
|
|
89
|
+
print("Config.warnings['not_compiled'] = False\n")
|
|
90
|
+
|
|
91
|
+
def load(self, func_name=None, mode=None):
|
|
92
|
+
if mode is None:
|
|
93
|
+
mode = self.mode
|
|
94
|
+
|
|
95
|
+
FUNCTIONS = get_functions()
|
|
96
|
+
|
|
97
|
+
if mode == "auto":
|
|
98
|
+
mode = "cython" if self.is_compiled else "python"
|
|
99
|
+
|
|
100
|
+
if func_name not in FUNCTIONS:
|
|
101
|
+
raise Exception("Function %s not found: %s" % (func_name, FUNCTIONS.keys()))
|
|
102
|
+
|
|
103
|
+
func = FUNCTIONS[func_name]
|
|
104
|
+
if mode not in func:
|
|
105
|
+
raise Exception("Module not available in %s." % mode)
|
|
106
|
+
func = func[mode]
|
|
107
|
+
|
|
108
|
+
# either provide a function or a string to the module (used for cython)
|
|
109
|
+
if not callable(func):
|
|
110
|
+
module = importlib.import_module(func)
|
|
111
|
+
func = getattr(module, func_name)
|
|
112
|
+
|
|
113
|
+
return func
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def load_function(func_name=None, _type="auto"):
|
|
117
|
+
return FunctionLoader.get_instance().load(func_name, mode=_type)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def is_compiled():
|
|
121
|
+
try:
|
|
122
|
+
from pymoo.cython.info import info
|
|
123
|
+
|
|
124
|
+
if info() == "yes":
|
|
125
|
+
return True
|
|
126
|
+
else:
|
|
127
|
+
return False
|
|
128
|
+
except:
|
|
129
|
+
return False
|
pymoo/util/hv.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.vendor.hv import HyperVolume
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def hv(ref_point, F):
|
|
7
|
+
hv = HyperVolume(ref_point)
|
|
8
|
+
return hv.compute(F)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def calc_hvc_looped(ref_point, F, func=hv):
|
|
12
|
+
hv = func(F, ref_point)
|
|
13
|
+
|
|
14
|
+
hvi = []
|
|
15
|
+
|
|
16
|
+
for k in range(len(F)):
|
|
17
|
+
v = np.full(len(F), True)
|
|
18
|
+
v[k] = False
|
|
19
|
+
_hv = func(F[v], ref_point)
|
|
20
|
+
hvi.append(hv - _hv)
|
|
21
|
+
|
|
22
|
+
hvi = np.array(hvi)
|
|
23
|
+
return hvi
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
def install_matlab():
|
|
2
|
+
print("Please install the Matlab python interface:")
|
|
3
|
+
print("Tutorial: https://www.mathworks.com/help/matlab/matlab_external/install-the-matlab-engine-for-python.html")
|
|
4
|
+
print("---------------------------")
|
|
5
|
+
print("Go to:")
|
|
6
|
+
print("Windows:", 'cd "matlabroot\extern\engines\python"')
|
|
7
|
+
print("Linux/Mac:", 'cd "matlabroot/extern/engines/python"')
|
|
8
|
+
print("python setup.py install")
|
|
9
|
+
print("---------------------------")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MatlabEngine:
|
|
13
|
+
"""
|
|
14
|
+
Launching the Matlab engine can become time-consuming and thus shall only be done once and the instance
|
|
15
|
+
could be reused by different kinds of problems at the same time.
|
|
16
|
+
|
|
17
|
+
This is an implementation based on the singleton pattern where only one instance of the engine is used.
|
|
18
|
+
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
__instance = None
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def get_instance():
|
|
25
|
+
if MatlabEngine.__instance is None:
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
import matlab
|
|
29
|
+
import matlab.engine
|
|
30
|
+
except:
|
|
31
|
+
print(install_matlab())
|
|
32
|
+
|
|
33
|
+
MatlabEngine.__instance = matlab.engine.start_matlab(option="")
|
|
34
|
+
|
|
35
|
+
return MatlabEngine.__instance
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def shutdown():
|
|
39
|
+
MatlabEngine.__instance.quit()
|