pymoo 0.6.1.5.dev0__cp311-cp311-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-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/calc_perpendicular_distance.pyx +67 -0
- pymoo/cython/decomposition.cpython-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/decomposition.pyx +165 -0
- pymoo/cython/hv.cpython-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/hv.pyx +18 -0
- pymoo/cython/info.cpython-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/info.pyx +5 -0
- pymoo/cython/mnn.cpython-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/mnn.pyx +273 -0
- pymoo/cython/non_dominated_sorting.cpython-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/non_dominated_sorting.pyx +645 -0
- pymoo/cython/pruning_cd.cpython-311-x86_64-linux-musl.so +0 -0
- pymoo/cython/pruning_cd.pyx +197 -0
- pymoo/cython/stochastic_ranking.cpython-311-x86_64-linux-musl.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,25 @@
|
|
|
1
|
+
from pymoo.core.algorithm import Algorithm
|
|
2
|
+
from pymoo.core.population import Population
|
|
3
|
+
from pymoo.operators.sampling.rnd import FloatRandomSampling
|
|
4
|
+
from pymoo.util.display.single import SingleObjectiveOutput
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class RandomSearch(Algorithm):
|
|
8
|
+
|
|
9
|
+
def __init__(self,
|
|
10
|
+
n_points_per_iteration=100,
|
|
11
|
+
sampling=FloatRandomSampling(),
|
|
12
|
+
output=SingleObjectiveOutput(),
|
|
13
|
+
**kwargs):
|
|
14
|
+
super().__init__(output=output, **kwargs)
|
|
15
|
+
self.n_points_per_iteration = n_points_per_iteration
|
|
16
|
+
self.sampling = sampling
|
|
17
|
+
|
|
18
|
+
def _initialize_infill(self):
|
|
19
|
+
return self._infill()
|
|
20
|
+
|
|
21
|
+
def _infill(self):
|
|
22
|
+
return self.sampling.do(self.problem, self.n_points_per_iteration)
|
|
23
|
+
|
|
24
|
+
def _advance(self, infills=None, **kwargs):
|
|
25
|
+
self.pop = infills if self.opt is None else Population.merge(infills, self.opt)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.algorithms.soo.nonconvex.es import ES
|
|
4
|
+
from pymoo.core.population import Population, calc_cv
|
|
5
|
+
from pymoo.core.survival import Survival
|
|
6
|
+
from pymoo.docs import parse_doc_string
|
|
7
|
+
from pymoo.util.function_loader import load_function
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class StochasticRankingSurvival(Survival):
|
|
11
|
+
|
|
12
|
+
def __init__(self, PR):
|
|
13
|
+
super().__init__(filter_infeasible=False)
|
|
14
|
+
self.PR = PR
|
|
15
|
+
|
|
16
|
+
def _do(self, problem, pop, *args, n_survive=None, tcv=None, **kwargs):
|
|
17
|
+
assert problem.n_obj == 1, "This stochastic ranking implementation only works for single-objective problems."
|
|
18
|
+
|
|
19
|
+
F, G = pop.get("F", "G")
|
|
20
|
+
f = F[:, 0]
|
|
21
|
+
|
|
22
|
+
if not problem.has_constraints():
|
|
23
|
+
I = f.argsort()
|
|
24
|
+
|
|
25
|
+
else:
|
|
26
|
+
phi = calc_cv(pop)
|
|
27
|
+
J = np.arange(len(phi))
|
|
28
|
+
I = load_function("stochastic_ranking")(f, phi, self.PR, J)
|
|
29
|
+
|
|
30
|
+
return pop[I][:n_survive]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class SRES(ES):
|
|
34
|
+
|
|
35
|
+
def __init__(self, PF=0.45, **kwargs):
|
|
36
|
+
"""
|
|
37
|
+
Stochastic Ranking Evolutionary Strategy (SRES)
|
|
38
|
+
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
PF: float
|
|
42
|
+
The stochastic ranking weight for choosing a random decision while doing the modified bubble sort.
|
|
43
|
+
"""
|
|
44
|
+
super().__init__(survival=StochasticRankingSurvival(PF), **kwargs)
|
|
45
|
+
self.PF = PF
|
|
46
|
+
|
|
47
|
+
def _advance(self, infills=None, **kwargs):
|
|
48
|
+
|
|
49
|
+
# if not all solutions suggested by infill() are evaluated we create a more semi (mu+lambda) algorithm
|
|
50
|
+
if len(infills) < self.pop_size:
|
|
51
|
+
infills = Population.merge(infills, self.pop)
|
|
52
|
+
|
|
53
|
+
self.pop = self.survival.do(self.problem, infills, n_survive=self.pop_size)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
parse_doc_string(SRES.__init__)
|
|
File without changes
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from pymoo.algorithms.base.line import LineSearch
|
|
2
|
+
from pymoo.core.evaluator import Evaluator
|
|
3
|
+
from pymoo.core.solution import Solution, SolutionSet
|
|
4
|
+
from pymoo.core.termination import NoTermination
|
|
5
|
+
from pymoo.optimize import minimize
|
|
6
|
+
from pymoo.problems.single import Sphere
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BacktrackingLineSearch(LineSearch):
|
|
10
|
+
|
|
11
|
+
def __init__(self, alpha=0.1, beta=0.33, **kwargs):
|
|
12
|
+
super().__init__(**kwargs)
|
|
13
|
+
self.alpha = alpha
|
|
14
|
+
self.beta = beta
|
|
15
|
+
self.termination = NoTermination()
|
|
16
|
+
|
|
17
|
+
def _initialize_infill(self):
|
|
18
|
+
super()._initialize_infill()
|
|
19
|
+
self.t = 1.0
|
|
20
|
+
self.point.set("t", self.t)
|
|
21
|
+
|
|
22
|
+
# TODO: evaluate_values_of needs to be moved into evaluator to be more flexible
|
|
23
|
+
if self.point.get("dF") is None:
|
|
24
|
+
self.evaluator.eval(self.problem, self.point, evaluate_values_of=["dF"], algorithm=self)
|
|
25
|
+
|
|
26
|
+
def step(self):
|
|
27
|
+
t = self.t
|
|
28
|
+
x, f, df, p = self.point.X, self.point.F[0], self.point.get("dF")[0], self.direction
|
|
29
|
+
|
|
30
|
+
infill = Solution(X=x + t * p, t=t)
|
|
31
|
+
self.evaluator.eval(self.problem, infill, algorithm=self, evaluate_values_of=["F"])
|
|
32
|
+
_f = infill.F[0]
|
|
33
|
+
|
|
34
|
+
self.pop = SolutionSet.merge(self.pop, infill)
|
|
35
|
+
self.infill = infill
|
|
36
|
+
|
|
37
|
+
if _f < f + self.alpha * self.t * df.T @ p or self.t <= 1e-8:
|
|
38
|
+
self.termination.force_termination = True
|
|
39
|
+
else:
|
|
40
|
+
self.t = self.t * self.beta
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
if __name__ == '__main__':
|
|
44
|
+
import numpy as np
|
|
45
|
+
|
|
46
|
+
problem = Sphere()
|
|
47
|
+
|
|
48
|
+
X = np.array(np.random.random(problem.n_var))
|
|
49
|
+
|
|
50
|
+
point = Solution(X=X)
|
|
51
|
+
Evaluator(evaluate_values_of=["F", "dF"]).eval(problem, point)
|
|
52
|
+
|
|
53
|
+
direction = - point.get("dF")[0]
|
|
54
|
+
|
|
55
|
+
algorithm = BacktrackingLineSearch().setup(problem, point=point, direction=direction)._initialize()
|
|
56
|
+
|
|
57
|
+
res = minimize(problem, algorithm)
|
|
58
|
+
|
|
59
|
+
print(res.X)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.core.algorithm import Algorithm
|
|
4
|
+
from pymoo.core.individual import Individual
|
|
5
|
+
from pymoo.core.population import Population
|
|
6
|
+
from pymoo.core.replacement import is_better
|
|
7
|
+
from pymoo.termination.default import DefaultSingleObjectiveTermination
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ExponentialSearch(Algorithm):
|
|
11
|
+
|
|
12
|
+
def __init__(self, delta=0.05, **kwargs):
|
|
13
|
+
super().__init__(**kwargs)
|
|
14
|
+
self.termination = DefaultSingleObjectiveTermination()
|
|
15
|
+
self.alpha = delta
|
|
16
|
+
self.point = None
|
|
17
|
+
|
|
18
|
+
def _setup(self, problem, x0=None, **kwargs):
|
|
19
|
+
msg = "Only problems with one variable, one objective and no constraints can be solved!"
|
|
20
|
+
assert problem.n_var == 1 and not problem.has_constraints() and problem.n_obj == 1, msg
|
|
21
|
+
self.point = x0
|
|
22
|
+
|
|
23
|
+
def _initialize_infill(self):
|
|
24
|
+
self.step_size = self.alpha
|
|
25
|
+
|
|
26
|
+
if self.point is None:
|
|
27
|
+
return Population.new(X=np.copy(self.problem.xl[None, :]))
|
|
28
|
+
else:
|
|
29
|
+
return Population.create(self.point)
|
|
30
|
+
|
|
31
|
+
def step(self):
|
|
32
|
+
alpha, max_alpha = self.alpha, self.problem.xu[0]
|
|
33
|
+
|
|
34
|
+
if alpha > max_alpha:
|
|
35
|
+
alpha = max_alpha
|
|
36
|
+
|
|
37
|
+
infill = Individual(X=np.array([alpha]))
|
|
38
|
+
self.evaluator.eval(self.problem, infill)
|
|
39
|
+
self.pop = Population.merge(self.pop, infill)[-10:]
|
|
40
|
+
|
|
41
|
+
if is_better(self.point, infill, eps=0.0) or alpha == max_alpha:
|
|
42
|
+
self.termination.force_termination = True
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
self.point = infill
|
|
46
|
+
self.alpha *= 2
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from pymoo.algorithms.base.bracket import BracketSearch
|
|
2
|
+
from pymoo.core.individual import Individual
|
|
3
|
+
from pymoo.core.population import Population
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class GoldenSectionSearch(BracketSearch):
|
|
7
|
+
|
|
8
|
+
def __init__(self, **kwargs):
|
|
9
|
+
super().__init__(**kwargs)
|
|
10
|
+
self.left, self.right = None, None
|
|
11
|
+
self.R = (5 ** 0.5 - 1) / 2
|
|
12
|
+
|
|
13
|
+
def _initialize_infill(self):
|
|
14
|
+
super()._initialize_infill()
|
|
15
|
+
a, b = self.a, self.b
|
|
16
|
+
|
|
17
|
+
# the golden ratio (precomputed constant)
|
|
18
|
+
R = self.R
|
|
19
|
+
|
|
20
|
+
# create the left and right in the interval itself
|
|
21
|
+
c, d = Individual(X=b.X - R * (b.X - a.X)), Individual(X=a.X + R * (b.X - a.X))
|
|
22
|
+
|
|
23
|
+
# create a population with all four individuals
|
|
24
|
+
pop = Population.create(a, c, d, b)
|
|
25
|
+
|
|
26
|
+
self.pop, self.infills = pop, pop
|
|
27
|
+
|
|
28
|
+
return pop
|
|
29
|
+
|
|
30
|
+
def _advance(self, **kwargs):
|
|
31
|
+
|
|
32
|
+
# all the elements in the interval
|
|
33
|
+
a, c, d, b = self.pop
|
|
34
|
+
|
|
35
|
+
# the golden ratio (precomputed constant)
|
|
36
|
+
R = self.R
|
|
37
|
+
|
|
38
|
+
# if the left solution is better than the right
|
|
39
|
+
if c.F[0] < d.F[0]:
|
|
40
|
+
|
|
41
|
+
# make the right to be the new right bound and the left becomes the right
|
|
42
|
+
a, b = a, d
|
|
43
|
+
d = c
|
|
44
|
+
|
|
45
|
+
# create a new left individual and evaluate
|
|
46
|
+
c = Individual(X=b.X - R * (b.X - a.X))
|
|
47
|
+
self.evaluator.eval(self.problem, c, algorithm=self)
|
|
48
|
+
self.infills = c
|
|
49
|
+
|
|
50
|
+
# if the right solution is better than the left
|
|
51
|
+
else:
|
|
52
|
+
|
|
53
|
+
# make the left to be the new left bound and the right becomes the left
|
|
54
|
+
a, b = c, b
|
|
55
|
+
c = d
|
|
56
|
+
|
|
57
|
+
# create a new right individual and evaluate
|
|
58
|
+
d = Individual(X=a.X + R * (b.X - a.X))
|
|
59
|
+
self.evaluator.eval(self.problem, d, algorithm=self)
|
|
60
|
+
self.infills = d
|
|
61
|
+
|
|
62
|
+
# update the population with all the four individuals
|
|
63
|
+
self.pop = Population.create(a, c, d, b)
|
|
64
|
+
|
|
65
|
+
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from pymoo.algorithms.base.bracket import BracketSearch
|
|
2
|
+
from pymoo.core.individual import Individual
|
|
3
|
+
from pymoo.core.population import Population
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def quadr_interp_equ(xa, fa, xb, fb, xc, fc):
|
|
7
|
+
g1 = (fc - fa) / (xc - xa)
|
|
8
|
+
g2 = ((fb - fc) / (xb - xc) - g1) * (xb - xa)
|
|
9
|
+
xd = 0.5 * ((xa - xb) - g1 / g2)
|
|
10
|
+
return xd
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def quadr_interp(a, b, c):
|
|
14
|
+
return Individual(X=quadr_interp_equ(a.X, a.F, b.X, b.F, c.X, c.F))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class QuadraticInterpolationSearch(BracketSearch):
|
|
18
|
+
|
|
19
|
+
def __init__(self, a=None, b=None, **kwargs):
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
7.1.2 Quadratic Interpolation Search
|
|
23
|
+
http://www.mathcs.emory.edu/~haber/math315/chap7.pdf
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
a
|
|
28
|
+
b
|
|
29
|
+
kwargs
|
|
30
|
+
"""
|
|
31
|
+
super().__init__(a, b, **kwargs)
|
|
32
|
+
|
|
33
|
+
def _initialize_infill(self):
|
|
34
|
+
super()._initialize_infill()
|
|
35
|
+
a, b = self.a, self.b
|
|
36
|
+
|
|
37
|
+
# set c to be directly in the middle between the two brackets
|
|
38
|
+
c = Individual(X=(b.X - a.X) / 2)
|
|
39
|
+
|
|
40
|
+
# create a population with all three individuals
|
|
41
|
+
pop = Population.create(a, b, c)
|
|
42
|
+
|
|
43
|
+
return pop
|
|
44
|
+
|
|
45
|
+
def _advance(self, **kwargs):
|
|
46
|
+
|
|
47
|
+
# all the elements in the interval
|
|
48
|
+
a, b, c = self.pop
|
|
49
|
+
|
|
50
|
+
# if this is the case then the function is not convex (which means U shaped)
|
|
51
|
+
if c.F[0] >= a.F[0] or c.F[0] >= b.F[0]:
|
|
52
|
+
|
|
53
|
+
# choose the left side if a smaller than b, or the right side otherwise
|
|
54
|
+
if a.F[0] <= b.F[0]:
|
|
55
|
+
a = c
|
|
56
|
+
else:
|
|
57
|
+
b = c
|
|
58
|
+
|
|
59
|
+
c = Individual(X=(b.X - a.X) / 2)
|
|
60
|
+
self.evaluator.eval(self.problem, c, algorithm=self)
|
|
61
|
+
self.infills = c
|
|
62
|
+
|
|
63
|
+
else:
|
|
64
|
+
|
|
65
|
+
d = quadr_interp(a, b, c)
|
|
66
|
+
self.evaluator.eval(self.problem, d, algorithm=self)
|
|
67
|
+
self.infills = d
|
|
68
|
+
|
|
69
|
+
# swap c and d -> make sure d is always on the right of c -> a, c, d, b
|
|
70
|
+
if c.X[0] > d.X[0]:
|
|
71
|
+
c, d = d, c
|
|
72
|
+
|
|
73
|
+
# if c is better than d, then d becomes the new right bound
|
|
74
|
+
if c.F[0] <= d.F[0]:
|
|
75
|
+
b = d
|
|
76
|
+
|
|
77
|
+
# if d is better than c, then c becomes the new left bound and d the new right bound
|
|
78
|
+
else:
|
|
79
|
+
a, c = c, d
|
|
80
|
+
|
|
81
|
+
self.pop = Population.create(a, b, c)
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.algorithms.base.line import LineSearchProblem
|
|
4
|
+
from pymoo.core.algorithm import Algorithm
|
|
5
|
+
from pymoo.core.evaluator import Evaluator
|
|
6
|
+
from pymoo.core.individual import Individual
|
|
7
|
+
from pymoo.core.solution import SolutionSet
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class WolfeSearch(Algorithm):
|
|
11
|
+
|
|
12
|
+
def __init__(self, c1=1e-4, c2=0.9, max_iter=10, **kwargs):
|
|
13
|
+
|
|
14
|
+
super().__init__(**kwargs)
|
|
15
|
+
self.c1 = c1
|
|
16
|
+
self.c2 = c2
|
|
17
|
+
self.max_iter = max_iter
|
|
18
|
+
|
|
19
|
+
def _setup(self, problem, **kwargs):
|
|
20
|
+
assert isinstance(problem,
|
|
21
|
+
LineSearchProblem), "The wolfe search only purpose is to solve a line search problem!"
|
|
22
|
+
self.pop = SolutionSet.create(problem.point)
|
|
23
|
+
self.opt = self.pop
|
|
24
|
+
|
|
25
|
+
def _set_optimum(self, force=False):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
def step(self):
|
|
29
|
+
sol = self._infill()
|
|
30
|
+
|
|
31
|
+
self.opt = sol
|
|
32
|
+
self.termination.force_termination = True
|
|
33
|
+
|
|
34
|
+
def _infill(self):
|
|
35
|
+
|
|
36
|
+
problem, evaluator = self.problem, self.evaluator
|
|
37
|
+
evaluator.skip_already_evaluated = False
|
|
38
|
+
|
|
39
|
+
sol, direction = self.problem.point, self.problem.direction
|
|
40
|
+
|
|
41
|
+
# the function value and gradient of the initial solution
|
|
42
|
+
sol.set("alpha", 0.0)
|
|
43
|
+
sol_F, sol_dF = sol.F[0], sol.get("dF")[0]
|
|
44
|
+
|
|
45
|
+
def zoom(alpha_low, alpha_high, max_iter=100):
|
|
46
|
+
|
|
47
|
+
while True:
|
|
48
|
+
|
|
49
|
+
_alpha = (alpha_high.get("alpha") + alpha_low.get("alpha")) / 2
|
|
50
|
+
_point = Individual(X=_alpha)
|
|
51
|
+
evaluator.eval(problem, _point, evaluate_values_of=["F", "CV"])
|
|
52
|
+
|
|
53
|
+
if _point.F[0] > sol_F + self.c1 * _alpha * sol_dF @ direction or _point.F[0] > alpha_low.F[0]:
|
|
54
|
+
alpha_high = _point
|
|
55
|
+
else:
|
|
56
|
+
evaluator.eval(problem, _point, evaluate_values_of=["dF"])
|
|
57
|
+
point_dF = _point.get("dF")[0]
|
|
58
|
+
|
|
59
|
+
if np.abs(point_dF @ direction) <= -self.c2 * sol_dF @ direction:
|
|
60
|
+
return _point
|
|
61
|
+
|
|
62
|
+
if (point_dF @ direction) * (alpha_high.get("alpha") - alpha_low.get("alpha")) >= 0:
|
|
63
|
+
alpha_high = alpha_low
|
|
64
|
+
|
|
65
|
+
alpha_low = _point
|
|
66
|
+
|
|
67
|
+
last = sol
|
|
68
|
+
|
|
69
|
+
alpha = 1.0
|
|
70
|
+
current = Individual(X=alpha)
|
|
71
|
+
|
|
72
|
+
for i in range(1, self.max_iter + 1):
|
|
73
|
+
|
|
74
|
+
# evaluate the solutions
|
|
75
|
+
evaluator.eval(problem, current, evaluate_values_of=["F", "CV"])
|
|
76
|
+
|
|
77
|
+
# get the values from the solution to be used to evaluate the conditions
|
|
78
|
+
F, dF, _F = last.F[0], last.get("dF")[0], current.F[0]
|
|
79
|
+
|
|
80
|
+
# if the wolfe condition is violate we have found our upper bound
|
|
81
|
+
if _F > sol_F + self.c1 * sol_dF @ direction or (i > 1 and F >= _F):
|
|
82
|
+
return zoom(last, current)
|
|
83
|
+
|
|
84
|
+
# for the other condition we need the gradient information
|
|
85
|
+
evaluator.eval(problem, current, evaluate_values_of=["dF"])
|
|
86
|
+
_dF = current.get("dF")[0]
|
|
87
|
+
|
|
88
|
+
if np.abs(_dF @ direction) <= -self.c2 * sol_dF @ direction:
|
|
89
|
+
return current
|
|
90
|
+
|
|
91
|
+
if _dF @ direction >= 0:
|
|
92
|
+
return zoom(current, last)
|
|
93
|
+
|
|
94
|
+
alpha = 2 * alpha
|
|
95
|
+
last = current
|
|
96
|
+
current = Individual(X=alpha)
|
|
97
|
+
|
|
98
|
+
return current
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def wolfe_line_search(problem, sol, direction, c1=1e-4, c2=0.9, max_iter=10, evaluator=None):
|
|
102
|
+
# initialize the evaluator to be used (this will make sure evaluations are counted)
|
|
103
|
+
evaluator = evaluator if evaluator is not None else Evaluator()
|
|
104
|
+
evaluator.skip_already_evaluated = False
|
|
105
|
+
|
|
106
|
+
# the function value and gradient of the initial solution
|
|
107
|
+
sol.set("alpha", 0.0)
|
|
108
|
+
sol_F, sol_dF = sol.F[0], sol.get("dF")[0]
|
|
109
|
+
|
|
110
|
+
def zoom(alpha_low, alpha_high, max_iter=100):
|
|
111
|
+
|
|
112
|
+
while True:
|
|
113
|
+
|
|
114
|
+
_alpha = (alpha_high.get("alpha") + alpha_low.get("alpha")) / 2
|
|
115
|
+
_point = Individual(X=sol.X + _alpha * direction, alpha=_alpha)
|
|
116
|
+
evaluator.eval(problem, _point, evaluate_values_of=["F", "CV"])
|
|
117
|
+
|
|
118
|
+
if _point.F[0] > sol_F + c1 * _alpha * sol_dF @ direction or _point.F[0] > alpha_low.F[0]:
|
|
119
|
+
alpha_high = _point
|
|
120
|
+
else:
|
|
121
|
+
evaluator.eval(problem, _point, evaluate_values_of=["dF"])
|
|
122
|
+
point_dF = _point.get("dF")[0]
|
|
123
|
+
|
|
124
|
+
if np.abs(point_dF @ direction) <= -c2 * sol_dF @ direction:
|
|
125
|
+
return _point
|
|
126
|
+
|
|
127
|
+
if (point_dF @ direction) * (alpha_high.get("alpha") - alpha_low.get("alpha")) >= 0:
|
|
128
|
+
alpha_high = alpha_low
|
|
129
|
+
|
|
130
|
+
alpha_low = _point
|
|
131
|
+
|
|
132
|
+
last = sol
|
|
133
|
+
|
|
134
|
+
alpha = 1.0
|
|
135
|
+
current = Individual(X=sol.X + alpha * direction, alpha=alpha)
|
|
136
|
+
|
|
137
|
+
for i in range(1, max_iter + 1):
|
|
138
|
+
|
|
139
|
+
# evaluate the solutions
|
|
140
|
+
evaluator.eval(problem, current, evaluate_values_of=["F", "CV"])
|
|
141
|
+
|
|
142
|
+
# get the values from the solution to be used to evaluate the conditions
|
|
143
|
+
F, dF, _F = last.F[0], last.get("dF")[0], current.F[0]
|
|
144
|
+
|
|
145
|
+
# if the wolfe condition is violate we have found our upper bound
|
|
146
|
+
if _F > sol_F + c1 * sol_dF @ direction or (i > 1 and F >= _F):
|
|
147
|
+
return zoom(last, current)
|
|
148
|
+
|
|
149
|
+
# for the other condition we need the gradient information
|
|
150
|
+
evaluator.eval(problem, current, evaluate_values_of=["dF"])
|
|
151
|
+
_dF = current.get("dF")[0]
|
|
152
|
+
|
|
153
|
+
if np.abs(_dF @ direction) <= -c2 * sol_dF @ direction:
|
|
154
|
+
return current
|
|
155
|
+
|
|
156
|
+
if _dF @ direction >= 0:
|
|
157
|
+
return zoom(current, last)
|
|
158
|
+
|
|
159
|
+
alpha = 2 * alpha
|
|
160
|
+
last = current
|
|
161
|
+
current = Individual(X=sol.X + alpha * direction, alpha=alpha)
|
|
162
|
+
|
|
163
|
+
return current
|
pymoo/config.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from os.path import dirname, realpath
|
|
2
|
+
|
|
3
|
+
from pymoo.version import __version__
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Config:
|
|
7
|
+
"""
|
|
8
|
+
The configuration of this package in general providing the place
|
|
9
|
+
for declaring global variables.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
# the root directory where the package is located at
|
|
13
|
+
root = dirname(realpath(__file__))
|
|
14
|
+
|
|
15
|
+
warnings = {
|
|
16
|
+
"not_compiled": True
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
# whether a warning should be printed if compiled modules are not available
|
|
20
|
+
show_compile_hint = True
|
|
21
|
+
|
|
22
|
+
# whether when import a file the doc should be parsed - only activate when creating doc files
|
|
23
|
+
parse_custom_docs = False
|
|
24
|
+
|
|
25
|
+
# a method defining the endpoint to load data remotely - default from GitHub repo
|
|
26
|
+
@classmethod
|
|
27
|
+
def data(cls):
|
|
28
|
+
return f"https://raw.githubusercontent.com/anyoptimization/pymoo-data/main/"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# returns the directory to be used for imports
|
|
32
|
+
def get_pymoo():
|
|
33
|
+
return dirname(Config.root)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from copy import deepcopy
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from pymoo.core.algorithm import Algorithm
|
|
6
|
+
from pymoo.core.evaluator import Evaluator
|
|
7
|
+
from pymoo.core.individual import Individual
|
|
8
|
+
from pymoo.core.meta import Meta
|
|
9
|
+
from pymoo.core.population import Population
|
|
10
|
+
from pymoo.core.problem import Problem
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AttachConfigEvaluator(Meta, Evaluator):
|
|
14
|
+
|
|
15
|
+
def __init__(self, wrapped, config):
|
|
16
|
+
super().__init__(wrapped)
|
|
17
|
+
self.config = config
|
|
18
|
+
|
|
19
|
+
def eval(self, problem: Problem, pop: Population, **kwargs):
|
|
20
|
+
pop = super().eval(problem, pop, **kwargs)
|
|
21
|
+
pop.apply(lambda ind: ind.set("config", self.config))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def copy_to_dict(src, dest):
|
|
25
|
+
dest.clear()
|
|
26
|
+
dest.update(**src)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class AdaptiveConstraintHandling(Meta, Algorithm):
|
|
30
|
+
|
|
31
|
+
def __init__(self, algorithm):
|
|
32
|
+
super().__init__(algorithm)
|
|
33
|
+
|
|
34
|
+
self.config = Individual.default_config()
|
|
35
|
+
self.config["cache"] = False
|
|
36
|
+
|
|
37
|
+
self.default_config = deepcopy(self.config)
|
|
38
|
+
self.adapted_config = deepcopy(self.config)
|
|
39
|
+
|
|
40
|
+
def _setup(self, _, **kwargs):
|
|
41
|
+
self.evaluator = AttachConfigEvaluator(self.evaluator, self.config)
|
|
42
|
+
|
|
43
|
+
def _adapt_constraint_handling(self, config, infills=None, **kwargs):
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
def _initialize_advance(self, infills=None, **kwargs):
|
|
47
|
+
copy_to_dict(self.adapted_config, self.config)
|
|
48
|
+
super()._initialize_advance(infills=infills, **kwargs)
|
|
49
|
+
copy_to_dict(self.default_config, self.config)
|
|
50
|
+
|
|
51
|
+
def _advance(self, infills=None, **kwargs):
|
|
52
|
+
copy_to_dict(self.adapted_config, self.config)
|
|
53
|
+
super()._advance(infills=infills, **kwargs)
|
|
54
|
+
copy_to_dict(self.default_config, self.config)
|
|
55
|
+
|
|
56
|
+
self._adapt_constraint_handling(self.adapted_config, infills=infills, **kwargs)
|
|
57
|
+
|
|
58
|
+
def _infill(self):
|
|
59
|
+
copy_to_dict(self.adapted_config, self.config)
|
|
60
|
+
pop = super()._infill()
|
|
61
|
+
copy_to_dict(self.default_config, self.config)
|
|
62
|
+
return pop
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import pymoo.gradient.toolbox as anp
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from pymoo.core.individual import calc_cv
|
|
5
|
+
from pymoo.core.meta import Meta
|
|
6
|
+
from pymoo.core.problem import Problem
|
|
7
|
+
from pymoo.util.misc import from_dict
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ConstraintsAsObjective(Meta, Problem):
|
|
11
|
+
|
|
12
|
+
def __init__(self,
|
|
13
|
+
problem,
|
|
14
|
+
config=None,
|
|
15
|
+
append=True):
|
|
16
|
+
|
|
17
|
+
super().__init__(problem)
|
|
18
|
+
self.config = config
|
|
19
|
+
self.append = append
|
|
20
|
+
|
|
21
|
+
if append:
|
|
22
|
+
self.n_obj = problem.n_obj + 1
|
|
23
|
+
else:
|
|
24
|
+
self.n_obj = 1
|
|
25
|
+
|
|
26
|
+
self.n_ieq_constr = 0
|
|
27
|
+
self.n_eq_constr = 0
|
|
28
|
+
|
|
29
|
+
def do(self, X, return_values_of, *args, **kwargs):
|
|
30
|
+
out = self.__object__.do(X, return_values_of, *args, **kwargs)
|
|
31
|
+
|
|
32
|
+
# get at the values from the output
|
|
33
|
+
F, G, H = from_dict(out, "F", "G", "H")
|
|
34
|
+
|
|
35
|
+
# store a backup of the values in out
|
|
36
|
+
out["__F__"], out["__G__"], out["__H__"] = F, G, H
|
|
37
|
+
|
|
38
|
+
# calculate the total constraint violation (here normalization shall be already included)
|
|
39
|
+
CV = calc_cv(G=G, H=H, config=self.config)
|
|
40
|
+
|
|
41
|
+
# append the constraint violation as objective
|
|
42
|
+
if self.append:
|
|
43
|
+
out["F"] = anp.column_stack([CV, F])
|
|
44
|
+
else:
|
|
45
|
+
out["F"] = CV
|
|
46
|
+
|
|
47
|
+
del out["G"]
|
|
48
|
+
del out["H"]
|
|
49
|
+
|
|
50
|
+
return out
|
|
51
|
+
|
|
52
|
+
def pareto_front(self, *args, **kwargs):
|
|
53
|
+
pf = super().pareto_front(*args, **kwargs)
|
|
54
|
+
if pf is not None:
|
|
55
|
+
pf = np.column_stack([np.zeros(len(pf)), pf])
|
|
56
|
+
return pf
|