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/selection.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from pymoo.core.operator import Operator
|
|
6
|
+
from pymoo.util import default_random_state
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Selection(Operator):
|
|
10
|
+
|
|
11
|
+
def __init__(self, **kwargs) -> None:
|
|
12
|
+
"""
|
|
13
|
+
This class is used to select parents for the mating or other evolutionary operators.
|
|
14
|
+
Several strategies can be used to increase the selection pressure.
|
|
15
|
+
"""
|
|
16
|
+
super().__init__(**kwargs)
|
|
17
|
+
|
|
18
|
+
@default_random_state
|
|
19
|
+
def do(self, problem, pop, n_select, n_parents, to_pop=True, *args, random_state=None, **kwargs):
|
|
20
|
+
"""
|
|
21
|
+
Choose from the population new individuals to be selected.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
problem: class
|
|
28
|
+
The problem to be solved. Provides information such as lower and upper bounds or feasibility
|
|
29
|
+
conditions for custom crossovers.
|
|
30
|
+
|
|
31
|
+
pop : :class:`~pymoo.core.population.Population`
|
|
32
|
+
The population which should be selected from. Some criteria from the design or objective space
|
|
33
|
+
might be used for the selection. Therefore, only the number of individual might be not enough.
|
|
34
|
+
|
|
35
|
+
n_select : int
|
|
36
|
+
Number of individuals to select.
|
|
37
|
+
|
|
38
|
+
n_parents : int
|
|
39
|
+
Number of parents needed to create an offspring.
|
|
40
|
+
|
|
41
|
+
to_pop : bool
|
|
42
|
+
Whether IF(!) the implementation returns only indices, it should be converted to individuals.
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
parents : list
|
|
47
|
+
List of parents to be used in the crossover
|
|
48
|
+
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
ret = self._do(problem, pop, n_select, n_parents, *args, random_state=random_state, **kwargs)
|
|
52
|
+
|
|
53
|
+
# if some selections return indices they are used to create the individual list
|
|
54
|
+
if to_pop and isinstance(ret, np.ndarray) and np.issubdtype(ret.dtype, np.integer):
|
|
55
|
+
ret = pop[ret]
|
|
56
|
+
|
|
57
|
+
return ret
|
|
58
|
+
|
|
59
|
+
@abstractmethod
|
|
60
|
+
def _do(self, problem, pop, n_select, n_parents, *args, random_state=None, **kwargs):
|
|
61
|
+
pass
|
pymoo/core/solution.py
ADDED
pymoo/core/survival.py
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from pymoo.core.population import Population
|
|
6
|
+
from pymoo.util import default_random_state
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
10
|
+
# Survival
|
|
11
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Survival:
|
|
15
|
+
|
|
16
|
+
def __init__(self, filter_infeasible=True):
|
|
17
|
+
super().__init__()
|
|
18
|
+
self.filter_infeasible = filter_infeasible
|
|
19
|
+
|
|
20
|
+
@default_random_state
|
|
21
|
+
def do(self,
|
|
22
|
+
problem,
|
|
23
|
+
pop,
|
|
24
|
+
*args,
|
|
25
|
+
n_survive=None,
|
|
26
|
+
random_state=None,
|
|
27
|
+
return_indices=False,
|
|
28
|
+
**kwargs):
|
|
29
|
+
|
|
30
|
+
# make sure the population has at least one individual
|
|
31
|
+
if len(pop) == 0:
|
|
32
|
+
return pop
|
|
33
|
+
|
|
34
|
+
if n_survive is None:
|
|
35
|
+
n_survive = len(pop)
|
|
36
|
+
|
|
37
|
+
n_survive = min(n_survive, len(pop))
|
|
38
|
+
|
|
39
|
+
# if the split should be done beforehand
|
|
40
|
+
if self.filter_infeasible and problem.has_constraints():
|
|
41
|
+
|
|
42
|
+
# split feasible and infeasible solutions
|
|
43
|
+
feas, infeas = split_by_feasibility(pop, sort_infeas_by_cv=True)
|
|
44
|
+
|
|
45
|
+
if len(feas) == 0:
|
|
46
|
+
survivors = Population()
|
|
47
|
+
else:
|
|
48
|
+
survivors = self._do(problem, pop[feas], *args, n_survive=min(len(feas), n_survive),
|
|
49
|
+
random_state=random_state, **kwargs)
|
|
50
|
+
|
|
51
|
+
# calculate how many individuals are still remaining to be filled up with infeasible ones
|
|
52
|
+
n_remaining = n_survive - len(survivors)
|
|
53
|
+
|
|
54
|
+
# if infeasible solutions needs to be added
|
|
55
|
+
if n_remaining > 0:
|
|
56
|
+
survivors = Population.merge(survivors, pop[infeas[:n_remaining]])
|
|
57
|
+
|
|
58
|
+
else:
|
|
59
|
+
survivors = self._do(problem, pop, *args, n_survive=n_survive, random_state=random_state, **kwargs)
|
|
60
|
+
|
|
61
|
+
if return_indices:
|
|
62
|
+
H = {}
|
|
63
|
+
for k, ind in enumerate(pop):
|
|
64
|
+
H[ind] = k
|
|
65
|
+
return [H[survivor] for survivor in survivors]
|
|
66
|
+
else:
|
|
67
|
+
return survivors
|
|
68
|
+
|
|
69
|
+
@abstractmethod
|
|
70
|
+
def _do(self, problem, pop, *args, n_survive=None, random_state=None, **kwargs):
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class ToReplacement(Survival):
|
|
75
|
+
|
|
76
|
+
def __init__(self, survival):
|
|
77
|
+
super().__init__(False)
|
|
78
|
+
self.survival = survival
|
|
79
|
+
|
|
80
|
+
def _do(self, problem, pop, off, random_state=None, **kwargs):
|
|
81
|
+
merged = Population.merge(pop, off)
|
|
82
|
+
I = self.survival.do(problem, merged, n_survive=len(merged), return_indices=True, random_state=random_state, **kwargs)
|
|
83
|
+
merged.set("__rank__", I)
|
|
84
|
+
|
|
85
|
+
for k in range(len(pop)):
|
|
86
|
+
if off[k].get("__rank__") < pop[k].get("__rank__"):
|
|
87
|
+
pop[k] = off[k]
|
|
88
|
+
|
|
89
|
+
return pop
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def split_by_feasibility(pop, sort_infeas_by_cv=True, sort_feas_by_obj=False, return_pop=False):
|
|
93
|
+
F, CV, b = pop.get("F", "CV", "FEAS")
|
|
94
|
+
|
|
95
|
+
feasible = np.where(b)[0]
|
|
96
|
+
infeasible = np.where(~b)[0]
|
|
97
|
+
|
|
98
|
+
if sort_infeas_by_cv:
|
|
99
|
+
infeasible = infeasible[np.argsort(CV[infeasible, 0])]
|
|
100
|
+
|
|
101
|
+
if sort_feas_by_obj:
|
|
102
|
+
feasible = feasible[np.argsort(F[feasible, 0])]
|
|
103
|
+
|
|
104
|
+
if not return_pop:
|
|
105
|
+
return feasible, infeasible
|
|
106
|
+
else:
|
|
107
|
+
return feasible, infeasible, pop[feasible], pop[infeasible]
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Termination:
|
|
5
|
+
|
|
6
|
+
def __init__(self) -> None:
|
|
7
|
+
super().__init__()
|
|
8
|
+
|
|
9
|
+
# the algorithm can be forced to terminate by setting this attribute to true
|
|
10
|
+
self.force_termination = False
|
|
11
|
+
|
|
12
|
+
# the value indicating how much perc has been made
|
|
13
|
+
self.perc = 0.0
|
|
14
|
+
|
|
15
|
+
def update(self, algorithm):
|
|
16
|
+
"""
|
|
17
|
+
Provide the termination criterion a current status of the algorithm to update the perc.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
algorithm : object
|
|
22
|
+
The algorithm object which is used to determine whether a run has terminated.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
if self.force_termination:
|
|
26
|
+
progress = 1.0
|
|
27
|
+
else:
|
|
28
|
+
progress = self._update(algorithm)
|
|
29
|
+
assert progress >= 0.0, "Invalid progress was set by the TerminationCriterion."
|
|
30
|
+
|
|
31
|
+
self.perc = progress
|
|
32
|
+
return self.perc
|
|
33
|
+
|
|
34
|
+
def has_terminated(self):
|
|
35
|
+
return self.perc >= 1.0
|
|
36
|
+
|
|
37
|
+
def do_continue(self):
|
|
38
|
+
return not self.has_terminated()
|
|
39
|
+
|
|
40
|
+
def terminate(self):
|
|
41
|
+
self.force_termination = True
|
|
42
|
+
|
|
43
|
+
@abstractmethod
|
|
44
|
+
def _update(self, algorithm):
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class NoTermination(Termination):
|
|
49
|
+
|
|
50
|
+
def _update(self, algorithm):
|
|
51
|
+
return 0.0
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class MultipleCriteria(Termination):
|
|
55
|
+
|
|
56
|
+
def __init__(self, *args) -> None:
|
|
57
|
+
super().__init__()
|
|
58
|
+
self.criteria = args
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class TerminateIfAny(MultipleCriteria):
|
|
62
|
+
|
|
63
|
+
def _update(self, algorithm):
|
|
64
|
+
return max([termination.update(algorithm) for termination in self.criteria])
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class TerminateIfAll(MultipleCriteria):
|
|
68
|
+
|
|
69
|
+
def _update(self, algorithm):
|
|
70
|
+
return min([termination.update(algorithm) for termination in self.criteria])
|
pymoo/core/variable.py
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module containing infrastructure for representing decision variable classes.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# public API for when using ``from pymoo.core.variable import *``
|
|
6
|
+
__all__ = [
|
|
7
|
+
"Variable",
|
|
8
|
+
"BoundedVariable",
|
|
9
|
+
"Real",
|
|
10
|
+
"Integer",
|
|
11
|
+
"Binary",
|
|
12
|
+
"Choice",
|
|
13
|
+
"get",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
from typing import Any, Optional, Tuple
|
|
17
|
+
from typing import Union
|
|
18
|
+
import numpy as np
|
|
19
|
+
from numpy.typing import ArrayLike
|
|
20
|
+
from pymoo.util import default_random_state
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Variable(object):
|
|
24
|
+
"""
|
|
25
|
+
Semi-abstract base class for the representation of a decision variable.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
value: Optional[object] = None,
|
|
31
|
+
active: bool = True,
|
|
32
|
+
flag: str = "default",
|
|
33
|
+
) -> None:
|
|
34
|
+
"""
|
|
35
|
+
Constructor for the ``Variable`` class.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
value : object, None
|
|
40
|
+
Value the decision variable is to take.
|
|
41
|
+
active : bool
|
|
42
|
+
Whether the variable is active (``True``) or inactive (``False``).
|
|
43
|
+
flag : str
|
|
44
|
+
Flag to bind to the decision variable.
|
|
45
|
+
"""
|
|
46
|
+
super().__init__()
|
|
47
|
+
self.value = value
|
|
48
|
+
self.flag = flag
|
|
49
|
+
self.active = active
|
|
50
|
+
|
|
51
|
+
@default_random_state
|
|
52
|
+
def sample(
|
|
53
|
+
self,
|
|
54
|
+
n: Optional[int] = None,
|
|
55
|
+
random_state=None,
|
|
56
|
+
) -> Union[object,np.ndarray]:
|
|
57
|
+
"""
|
|
58
|
+
Randomly sample ``n`` instances of a decision variable.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
n : int, None
|
|
63
|
+
Number of decision variable samples which to draw.
|
|
64
|
+
If ``int``, sample ``n`` decision variables.
|
|
65
|
+
If ``None``, sample a single decision variables.
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
out : object, np.ndarray
|
|
70
|
+
If ``n`` is ``int``, return a ``np.ndarray`` of shape ``(n,)``
|
|
71
|
+
containing sampled decision variables.
|
|
72
|
+
If ``n`` is ``None``, return an ``object`` of a sampled decision
|
|
73
|
+
variable.
|
|
74
|
+
"""
|
|
75
|
+
if n is None:
|
|
76
|
+
return self._sample(1, random_state=random_state)[0]
|
|
77
|
+
else:
|
|
78
|
+
return self._sample(n, random_state=random_state)
|
|
79
|
+
|
|
80
|
+
def _sample(
|
|
81
|
+
self,
|
|
82
|
+
n: int,
|
|
83
|
+
random_state=None,
|
|
84
|
+
) -> np.ndarray:
|
|
85
|
+
"""
|
|
86
|
+
Randomly sample ``n`` instances of a decision variable.
|
|
87
|
+
This is an abstract private method governing the behavior of the
|
|
88
|
+
``sample`` method.
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
n : int
|
|
93
|
+
Number of decision variable samples which to draw.
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
out : np.ndarray
|
|
98
|
+
An array of shape ``(n,)`` containing sampled decision variables.
|
|
99
|
+
"""
|
|
100
|
+
pass
|
|
101
|
+
|
|
102
|
+
def set(
|
|
103
|
+
self,
|
|
104
|
+
value: object,
|
|
105
|
+
) -> None:
|
|
106
|
+
"""
|
|
107
|
+
Set the value of a decision variable.
|
|
108
|
+
|
|
109
|
+
Parameters
|
|
110
|
+
----------
|
|
111
|
+
value : object
|
|
112
|
+
Value to assign to the decision variable.
|
|
113
|
+
"""
|
|
114
|
+
self.value = value
|
|
115
|
+
|
|
116
|
+
def get(
|
|
117
|
+
self,
|
|
118
|
+
**kwargs: Any
|
|
119
|
+
) -> object:
|
|
120
|
+
"""
|
|
121
|
+
Get the value of a decision variable.
|
|
122
|
+
|
|
123
|
+
Parameters
|
|
124
|
+
----------
|
|
125
|
+
kwargs : Any
|
|
126
|
+
Additional keyword arguments.
|
|
127
|
+
|
|
128
|
+
Returns
|
|
129
|
+
-------
|
|
130
|
+
out : object
|
|
131
|
+
The value of the decision variable.
|
|
132
|
+
"""
|
|
133
|
+
return self.value
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class BoundedVariable(Variable):
|
|
137
|
+
"""
|
|
138
|
+
Semi-abstract class for the representation of a bounded decision variable.
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
def __init__(
|
|
142
|
+
self,
|
|
143
|
+
value: Optional[object] = None,
|
|
144
|
+
bounds: Tuple[Optional[object],Optional[object]] = (None, None),
|
|
145
|
+
strict: Optional[Tuple[Optional[object],Optional[object]]] = None,
|
|
146
|
+
**kwargs: Any,
|
|
147
|
+
) -> None:
|
|
148
|
+
"""
|
|
149
|
+
Constructor for the ``BoundedVariable`` class.
|
|
150
|
+
|
|
151
|
+
Parameters
|
|
152
|
+
----------
|
|
153
|
+
value : object
|
|
154
|
+
Value the decision variable is to take.
|
|
155
|
+
bounds : tuple
|
|
156
|
+
A tuple of length 2 containing upper and lower limits for the
|
|
157
|
+
decision variable.
|
|
158
|
+
strict : tuple, None
|
|
159
|
+
Strict boundaries for the decision variable.
|
|
160
|
+
If ``None``, the value of ``bounds`` is copied to ``strict``.
|
|
161
|
+
kwargs : Any
|
|
162
|
+
Additional keyword arguments for ``active`` and ``flag``.
|
|
163
|
+
"""
|
|
164
|
+
# call the Variable constructor
|
|
165
|
+
super().__init__(value=value, **kwargs)
|
|
166
|
+
self.bounds = bounds
|
|
167
|
+
|
|
168
|
+
# if no strict boundaries were provided, consider ``bounds`` as
|
|
169
|
+
# strict boundaries
|
|
170
|
+
if strict is None:
|
|
171
|
+
strict = bounds
|
|
172
|
+
self.strict = strict
|
|
173
|
+
|
|
174
|
+
@property
|
|
175
|
+
def lb(self) -> object:
|
|
176
|
+
"""
|
|
177
|
+
Lower bound of the decision variable.
|
|
178
|
+
|
|
179
|
+
Returns
|
|
180
|
+
-------
|
|
181
|
+
out : object
|
|
182
|
+
The decision variable lower bound.
|
|
183
|
+
"""
|
|
184
|
+
return self.bounds[0]
|
|
185
|
+
|
|
186
|
+
@property
|
|
187
|
+
def ub(self) -> object:
|
|
188
|
+
"""
|
|
189
|
+
Upper bound of the decision variable.
|
|
190
|
+
|
|
191
|
+
Returns
|
|
192
|
+
-------
|
|
193
|
+
out : object
|
|
194
|
+
The decision variable upper bound.
|
|
195
|
+
"""
|
|
196
|
+
return self.bounds[1]
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class Real(BoundedVariable):
|
|
200
|
+
"""
|
|
201
|
+
Class for the representation of bounded, real decision variables.
|
|
202
|
+
"""
|
|
203
|
+
# variable type represented by this object class
|
|
204
|
+
vtype = float
|
|
205
|
+
|
|
206
|
+
def _sample(
|
|
207
|
+
self,
|
|
208
|
+
n: int,
|
|
209
|
+
random_state=None,
|
|
210
|
+
) -> np.ndarray:
|
|
211
|
+
"""
|
|
212
|
+
Randomly sample ``n`` instances of a real, bounded decision variable.
|
|
213
|
+
Decision variables are sampled from a uniform distribution.
|
|
214
|
+
|
|
215
|
+
This is a private method governing the behavior of the ``sample``
|
|
216
|
+
method.
|
|
217
|
+
|
|
218
|
+
Parameters
|
|
219
|
+
----------
|
|
220
|
+
n : int
|
|
221
|
+
Number of decision variable samples which to draw.
|
|
222
|
+
random_state
|
|
223
|
+
Random state for sampling.
|
|
224
|
+
|
|
225
|
+
Returns
|
|
226
|
+
-------
|
|
227
|
+
out : np.ndarray
|
|
228
|
+
An array of shape ``(n,)`` containing sampled real, bounded
|
|
229
|
+
decision variables.
|
|
230
|
+
"""
|
|
231
|
+
low, high = self.bounds
|
|
232
|
+
return random_state.uniform(low=low, high=high, size=n)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
class Integer(BoundedVariable):
|
|
236
|
+
"""
|
|
237
|
+
Class for the representation of bounded, integer decision variables.
|
|
238
|
+
"""
|
|
239
|
+
# variable type represented by this object class
|
|
240
|
+
vtype = int
|
|
241
|
+
|
|
242
|
+
def _sample(
|
|
243
|
+
self,
|
|
244
|
+
n: int,
|
|
245
|
+
random_state=None,
|
|
246
|
+
) -> np.ndarray:
|
|
247
|
+
"""
|
|
248
|
+
Randomly sample ``n`` instances of a bounded, integer decision variable.
|
|
249
|
+
Decision variables are sampled from a uniform distribution.
|
|
250
|
+
|
|
251
|
+
This is a private method governing the behavior of the ``sample``
|
|
252
|
+
method.
|
|
253
|
+
|
|
254
|
+
Parameters
|
|
255
|
+
----------
|
|
256
|
+
n : int
|
|
257
|
+
Number of decision variable samples which to draw.
|
|
258
|
+
random_state
|
|
259
|
+
Random state for sampling.
|
|
260
|
+
|
|
261
|
+
Returns
|
|
262
|
+
-------
|
|
263
|
+
out : np.ndarray
|
|
264
|
+
An array of shape ``(n,)`` containing sampled bounded, integer
|
|
265
|
+
decision variables.
|
|
266
|
+
"""
|
|
267
|
+
low, high = self.bounds
|
|
268
|
+
return random_state.integers(low, high + 1, size=n)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
class Binary(BoundedVariable):
|
|
272
|
+
"""
|
|
273
|
+
Class for the representation of a binary, bounded decision variable.
|
|
274
|
+
"""
|
|
275
|
+
# variable type represented by this object class
|
|
276
|
+
vtype = bool
|
|
277
|
+
|
|
278
|
+
def _sample(
|
|
279
|
+
self,
|
|
280
|
+
n: int,
|
|
281
|
+
random_state=None,
|
|
282
|
+
) -> np.ndarray:
|
|
283
|
+
"""
|
|
284
|
+
Randomly sample ``n`` instances of a bounded, binary decision variable.
|
|
285
|
+
Decision variables are sampled from a uniform distribution.
|
|
286
|
+
|
|
287
|
+
This is a private method governing the behavior of the ``sample``
|
|
288
|
+
method.
|
|
289
|
+
|
|
290
|
+
Parameters
|
|
291
|
+
----------
|
|
292
|
+
n : int
|
|
293
|
+
Number of decision variable samples which to draw.
|
|
294
|
+
random_state
|
|
295
|
+
Random state for sampling.
|
|
296
|
+
|
|
297
|
+
Returns
|
|
298
|
+
-------
|
|
299
|
+
out : np.ndarray
|
|
300
|
+
An array of shape ``(n,)`` containing sampled bounded, binary
|
|
301
|
+
decision variables.
|
|
302
|
+
"""
|
|
303
|
+
return random_state.random(size=n) < 0.5
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
class Choice(Variable):
|
|
307
|
+
"""
|
|
308
|
+
Class for the representation of a discrete, subset decision variable.
|
|
309
|
+
"""
|
|
310
|
+
# variable type represented by this object class
|
|
311
|
+
vtype = object
|
|
312
|
+
|
|
313
|
+
def __init__(
|
|
314
|
+
self,
|
|
315
|
+
value: Optional[object] = None,
|
|
316
|
+
options: Optional[ArrayLike] = None,
|
|
317
|
+
all: Optional[ArrayLike] = None,
|
|
318
|
+
**kwargs: Any,
|
|
319
|
+
) -> None:
|
|
320
|
+
"""
|
|
321
|
+
Constructor for the ``Choice`` class.
|
|
322
|
+
|
|
323
|
+
Parameters
|
|
324
|
+
----------
|
|
325
|
+
value : object
|
|
326
|
+
Value the decision variable is to take.
|
|
327
|
+
options : ArrayLike, None
|
|
328
|
+
A list of decision variable options from which to choose.
|
|
329
|
+
all : ArrayLike, None
|
|
330
|
+
A strict list of decision variable options from which to choose.
|
|
331
|
+
If ``None``, the value of ``options`` is copied to ``all``.
|
|
332
|
+
kwargs : Any
|
|
333
|
+
Additional keyword arguments for ``active`` and ``flag``.
|
|
334
|
+
"""
|
|
335
|
+
# all super constructor
|
|
336
|
+
super().__init__(value=value, **kwargs)
|
|
337
|
+
self.options = options
|
|
338
|
+
|
|
339
|
+
# if strict list not provided, set to ``options``
|
|
340
|
+
if all is None:
|
|
341
|
+
all = options
|
|
342
|
+
self.all = all
|
|
343
|
+
|
|
344
|
+
def _sample(
|
|
345
|
+
self,
|
|
346
|
+
n: int,
|
|
347
|
+
random_state=None,
|
|
348
|
+
) -> np.ndarray:
|
|
349
|
+
"""
|
|
350
|
+
Randomly sample ``n`` instances of a discrete, subset decision variable.
|
|
351
|
+
Decision variables are sampled with replacement from a uniform
|
|
352
|
+
distribution.
|
|
353
|
+
|
|
354
|
+
This is a private method governing the behavior of the ``sample``
|
|
355
|
+
method.
|
|
356
|
+
|
|
357
|
+
Parameters
|
|
358
|
+
----------
|
|
359
|
+
n : int
|
|
360
|
+
Number of decision variable samples which to draw.
|
|
361
|
+
random_state
|
|
362
|
+
Random state for sampling.
|
|
363
|
+
|
|
364
|
+
Returns
|
|
365
|
+
-------
|
|
366
|
+
out : np.ndarray
|
|
367
|
+
An array of shape ``(n,)`` containing sampled bounded, integer
|
|
368
|
+
decision variables.
|
|
369
|
+
"""
|
|
370
|
+
return random_state.choice(self.options, size=n)
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
def get(
|
|
374
|
+
*args: Tuple[Union[Variable,object],...],
|
|
375
|
+
size: Optional[Union[tuple,int]] = None,
|
|
376
|
+
**kwargs: Any
|
|
377
|
+
) -> Union[tuple,object,None]:
|
|
378
|
+
"""
|
|
379
|
+
Get decision variable values from a tuple of ``Variable`` objects.
|
|
380
|
+
|
|
381
|
+
Parameters
|
|
382
|
+
----------
|
|
383
|
+
args : tuple
|
|
384
|
+
A tuple of ``Variable`` or ``object``s.
|
|
385
|
+
size : tuple, int, None
|
|
386
|
+
Size to reshape decision variables.
|
|
387
|
+
kwargs : Any
|
|
388
|
+
Additional keyword arguments to pass to the ``get`` method of the
|
|
389
|
+
``Variable`` class when getting decision variable values.
|
|
390
|
+
|
|
391
|
+
Returns
|
|
392
|
+
-------
|
|
393
|
+
out : tuple, object, None
|
|
394
|
+
Decision variable value(s).
|
|
395
|
+
"""
|
|
396
|
+
if len(args) == 0:
|
|
397
|
+
return
|
|
398
|
+
|
|
399
|
+
ret = []
|
|
400
|
+
for arg in args:
|
|
401
|
+
v = arg.get(**kwargs) if isinstance(arg, Variable) else arg
|
|
402
|
+
|
|
403
|
+
if size is not None:
|
|
404
|
+
|
|
405
|
+
if isinstance(v, np.ndarray):
|
|
406
|
+
v = np.reshape(v, size)
|
|
407
|
+
else:
|
|
408
|
+
v = np.full(size, v)
|
|
409
|
+
|
|
410
|
+
ret.append(v)
|
|
411
|
+
|
|
412
|
+
if len(ret) == 1:
|
|
413
|
+
return ret[0]
|
|
414
|
+
else:
|
|
415
|
+
return tuple(ret)
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.decomposition.asf import ASF
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AASF(ASF):
|
|
7
|
+
|
|
8
|
+
def __init__(self, eps=1e-10, _type="auto", rho=None, beta=None, **kwargs) -> None:
|
|
9
|
+
super().__init__(eps, _type, **kwargs)
|
|
10
|
+
if rho is None and beta is None:
|
|
11
|
+
raise Exception("Either provide rho or beta!")
|
|
12
|
+
elif rho is None:
|
|
13
|
+
self.rho = calc_rho(beta)
|
|
14
|
+
else:
|
|
15
|
+
self.rho = rho
|
|
16
|
+
|
|
17
|
+
def _do(self, F, weights, **kwargs):
|
|
18
|
+
asf = super()._do(F, weights, **kwargs)
|
|
19
|
+
augment = ((F - self.utopian_point) / np.clip(weights, 1e-12, np.inf)).sum(axis=1)
|
|
20
|
+
return asf + self.rho * augment
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def calc_rho(beta):
|
|
24
|
+
return 1 / (1 - np.tan(beta / 360 * 2 * np.pi)) - 1
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from pymoo.core.decomposition import Decomposition
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ASF(Decomposition):
|
|
5
|
+
|
|
6
|
+
def _do(self, F, weights, weight_0=1e-10, **kwargs):
|
|
7
|
+
_weights = weights.astype(float)
|
|
8
|
+
_weights[weights == 0] = weight_0
|
|
9
|
+
asf = ((F - self.utopian_point) / _weights).max(axis=1)
|
|
10
|
+
return asf
|