pymoo 0.6.1.5.dev0__cp313-cp313-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-313-x86_64-linux-gnu.so +0 -0
- pymoo/cython/calc_perpendicular_distance.pyx +67 -0
- pymoo/cython/decomposition.cpython-313-x86_64-linux-gnu.so +0 -0
- pymoo/cython/decomposition.pyx +165 -0
- pymoo/cython/hv.cpython-313-x86_64-linux-gnu.so +0 -0
- pymoo/cython/hv.pyx +18 -0
- pymoo/cython/info.cpython-313-x86_64-linux-gnu.so +0 -0
- pymoo/cython/info.pyx +5 -0
- pymoo/cython/mnn.cpython-313-x86_64-linux-gnu.so +0 -0
- pymoo/cython/mnn.pyx +273 -0
- pymoo/cython/non_dominated_sorting.cpython-313-x86_64-linux-gnu.so +0 -0
- pymoo/cython/non_dominated_sorting.pyx +645 -0
- pymoo/cython/pruning_cd.cpython-313-x86_64-linux-gnu.so +0 -0
- pymoo/cython/pruning_cd.pyx +197 -0
- pymoo/cython/stochastic_ranking.cpython-313-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,125 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.core.crossover import Crossover
|
|
4
|
+
from pymoo.core.variable import Real, get
|
|
5
|
+
from pymoo.operators.repair.bounds_repair import repair_clamp
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
9
|
+
# Function
|
|
10
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def cross_sbx(X, xl, xu, eta, prob_var, prob_bin, eps=1.0e-14):
|
|
14
|
+
n_parents, n_matings, n_var = X.shape
|
|
15
|
+
|
|
16
|
+
# the probability of a crossover for each of the variables
|
|
17
|
+
cross = np.random.random((n_matings, n_var)) < prob_var
|
|
18
|
+
|
|
19
|
+
# when solutions are too close -> do not apply sbx crossover
|
|
20
|
+
too_close = np.abs(X[0] - X[1]) <= eps
|
|
21
|
+
|
|
22
|
+
# disable if two individuals are already too close
|
|
23
|
+
cross[too_close] = False
|
|
24
|
+
|
|
25
|
+
# disable crossover when lower and upper bound are identical
|
|
26
|
+
cross[:, xl == xu] = False
|
|
27
|
+
|
|
28
|
+
# assign y1 the smaller and y2 the larger value
|
|
29
|
+
y1 = np.min(X, axis=0)[cross]
|
|
30
|
+
y2 = np.max(X, axis=0)[cross]
|
|
31
|
+
|
|
32
|
+
# mask all the values that should be crossovered
|
|
33
|
+
_xl = np.repeat(xl[None, :], n_matings, axis=0)[cross]
|
|
34
|
+
_xu = np.repeat(xu[None, :], n_matings, axis=0)[cross]
|
|
35
|
+
eta = eta.repeat(n_var, axis=1)[cross]
|
|
36
|
+
prob_bin = prob_bin.repeat(n_var, axis=1)[cross]
|
|
37
|
+
|
|
38
|
+
# random values for each individual
|
|
39
|
+
rand = np.random.random(len(eta))
|
|
40
|
+
|
|
41
|
+
def calc_betaq(beta):
|
|
42
|
+
alpha = 2.0 - np.power(beta, -(eta + 1.0))
|
|
43
|
+
|
|
44
|
+
mask, mask_not = (rand <= (1.0 / alpha)), (rand > (1.0 / alpha))
|
|
45
|
+
|
|
46
|
+
betaq = np.zeros(mask.shape)
|
|
47
|
+
betaq[mask] = np.power((rand * alpha), (1.0 / (eta + 1.0)))[mask]
|
|
48
|
+
betaq[mask_not] = np.power((1.0 / (2.0 - rand * alpha)), (1.0 / (eta + 1.0)))[mask_not]
|
|
49
|
+
|
|
50
|
+
return betaq
|
|
51
|
+
|
|
52
|
+
# difference between all variables
|
|
53
|
+
delta = (y2 - y1)
|
|
54
|
+
|
|
55
|
+
beta = 1.0 + (2.0 * (y1 - _xl) / delta)
|
|
56
|
+
betaq = calc_betaq(beta)
|
|
57
|
+
c1 = 0.5 * ((y1 + y2) - betaq * delta)
|
|
58
|
+
|
|
59
|
+
beta = 1.0 + (2.0 * (_xu - y2) / delta)
|
|
60
|
+
betaq = calc_betaq(beta)
|
|
61
|
+
c2 = 0.5 * ((y1 + y2) + betaq * delta)
|
|
62
|
+
|
|
63
|
+
# with the given probability either assign the value from the first or second parent
|
|
64
|
+
b = np.random.random(len(prob_bin)) < prob_bin
|
|
65
|
+
tmp = np.copy(c1[b])
|
|
66
|
+
c1[b] = c2[b]
|
|
67
|
+
c2[b] = tmp
|
|
68
|
+
|
|
69
|
+
# first copy the unmodified parents
|
|
70
|
+
Q = np.copy(X)
|
|
71
|
+
|
|
72
|
+
# copy the positions where the crossover was done
|
|
73
|
+
Q[0, cross] = c1
|
|
74
|
+
Q[1, cross] = c2
|
|
75
|
+
|
|
76
|
+
Q[0] = repair_clamp(Q[0], xl, xu)
|
|
77
|
+
Q[1] = repair_clamp(Q[1], xl, xu)
|
|
78
|
+
|
|
79
|
+
return Q
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
83
|
+
# Class
|
|
84
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class SimulatedBinaryCrossover(Crossover):
|
|
88
|
+
|
|
89
|
+
def __init__(self,
|
|
90
|
+
prob_var=0.5,
|
|
91
|
+
eta=15,
|
|
92
|
+
prob_exch=1.0,
|
|
93
|
+
prob_bin=0.5,
|
|
94
|
+
n_offsprings=2,
|
|
95
|
+
**kwargs):
|
|
96
|
+
super().__init__(2, n_offsprings, **kwargs)
|
|
97
|
+
|
|
98
|
+
self.prob_var = Real(prob_var, bounds=(0.1, 0.9))
|
|
99
|
+
self.eta = Real(eta, bounds=(3.0, 30.0), strict=(1.0, None))
|
|
100
|
+
self.prob_exch = Real(prob_exch, bounds=(0.0, 1.0), strict=(0.0, 1.0))
|
|
101
|
+
self.prob_bin = Real(prob_bin, bounds=(0.0, 1.0), strict=(0.0, 1.0))
|
|
102
|
+
|
|
103
|
+
def _do(self, problem, X, **kwargs):
|
|
104
|
+
_, n_matings, _ = X.shape
|
|
105
|
+
|
|
106
|
+
# get the parameters required by SBX
|
|
107
|
+
eta, prob_var, prob_exch, prob_bin = get(self.eta, self.prob_var, self.prob_exch, self.prob_bin,
|
|
108
|
+
size=(n_matings, 1))
|
|
109
|
+
|
|
110
|
+
# set the binomial probability to zero if no exchange between individuals shall happen
|
|
111
|
+
rand = np.random.random((len(prob_bin), 1))
|
|
112
|
+
prob_bin[rand > prob_exch] = 0.0
|
|
113
|
+
|
|
114
|
+
Q = cross_sbx(X.astype(float), problem.xl, problem.xu, eta, prob_var, prob_bin)
|
|
115
|
+
|
|
116
|
+
if self.n_offsprings == 1:
|
|
117
|
+
rand = np.random.random(size=n_matings) < 0.5
|
|
118
|
+
Q[0, rand] = Q[1, rand]
|
|
119
|
+
Q = Q[[0]]
|
|
120
|
+
|
|
121
|
+
return Q
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class SBX(SimulatedBinaryCrossover):
|
|
125
|
+
pass
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.core.crossover import Crossover
|
|
4
|
+
from pymoo.util.misc import crossover_mask
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class UniformCrossover(Crossover):
|
|
8
|
+
|
|
9
|
+
def __init__(self, **kwargs):
|
|
10
|
+
super().__init__(2, 2, **kwargs)
|
|
11
|
+
|
|
12
|
+
def _do(self, _, X, **kwargs):
|
|
13
|
+
_, n_matings, n_var = X.shape
|
|
14
|
+
M = np.random.random((n_matings, n_var)) < 0.5
|
|
15
|
+
_X = crossover_mask(X, M)
|
|
16
|
+
return _X
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class UX(UniformCrossover):
|
|
20
|
+
pass
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.core.mutation import Mutation
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BitflipMutation(Mutation):
|
|
7
|
+
|
|
8
|
+
def _do(self, problem, X, **kwargs):
|
|
9
|
+
prob_var = self.get_prob_var(problem, size=(len(X), 1))
|
|
10
|
+
Xp = np.copy(X)
|
|
11
|
+
flip = np.random.random(X.shape) < prob_var
|
|
12
|
+
Xp[flip] = ~X[flip]
|
|
13
|
+
return Xp
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BFM(BitflipMutation):
|
|
17
|
+
pass
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.core.mutation import Mutation
|
|
4
|
+
from pymoo.core.variable import Real, get
|
|
5
|
+
from pymoo.operators.repair.bounds_repair import repair_random_init
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
9
|
+
# Function
|
|
10
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def mut_gauss(X, xl, xu, sigma, prob):
|
|
14
|
+
n, n_var = X.shape
|
|
15
|
+
assert len(sigma) == n
|
|
16
|
+
assert len(prob) == n
|
|
17
|
+
|
|
18
|
+
Xp = np.full(X.shape, np.inf)
|
|
19
|
+
|
|
20
|
+
mut = np.random.random(X.shape) < prob[:, None]
|
|
21
|
+
|
|
22
|
+
Xp[:, :] = X
|
|
23
|
+
|
|
24
|
+
_xl = np.repeat(xl[None, :], X.shape[0], axis=0)[mut]
|
|
25
|
+
_xu = np.repeat(xu[None, :], X.shape[0], axis=0)[mut]
|
|
26
|
+
sigma = sigma[:, None].repeat(n_var, axis=1)[mut]
|
|
27
|
+
|
|
28
|
+
Xp[mut] = np.random.normal(X[mut], sigma * (_xu - _xl))
|
|
29
|
+
|
|
30
|
+
Xp = repair_random_init(Xp, X, xl, xu)
|
|
31
|
+
|
|
32
|
+
return Xp
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
36
|
+
# Class
|
|
37
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class GaussianMutation(Mutation):
|
|
41
|
+
|
|
42
|
+
def __init__(self, sigma=0.1, **kwargs):
|
|
43
|
+
super().__init__(**kwargs)
|
|
44
|
+
self.sigma = Real(sigma, bounds=(0.01, 0.25), strict=(0.0, 1.0))
|
|
45
|
+
|
|
46
|
+
def _do(self, problem, X, **kwargs):
|
|
47
|
+
X = X.astype(float)
|
|
48
|
+
|
|
49
|
+
sigma = get(self.sigma, size=len(X))
|
|
50
|
+
prob_var = self.get_prob_var(problem, size=len(X))
|
|
51
|
+
|
|
52
|
+
Xp = mut_gauss(X, problem.xl, problem.xu, sigma, prob_var)
|
|
53
|
+
|
|
54
|
+
return Xp
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class GM(GaussianMutation):
|
|
58
|
+
pass
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.core.mutation import Mutation
|
|
4
|
+
from pymoo.operators.crossover.ox import random_sequence
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def inversion_mutation(y, seq, inplace=True):
|
|
8
|
+
y = y if inplace else np.copy(y)
|
|
9
|
+
|
|
10
|
+
if seq is None:
|
|
11
|
+
seq = random_sequence(len(y))
|
|
12
|
+
start, end = seq
|
|
13
|
+
|
|
14
|
+
y[start:end + 1] = np.flip(y[start:end + 1])
|
|
15
|
+
return y
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class InversionMutation(Mutation):
|
|
19
|
+
|
|
20
|
+
def __init__(self, prob=1.0):
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
This mutation is applied to permutations. It randomly selects a segment of a chromosome and reverse its order.
|
|
24
|
+
For instance, for the permutation `[1, 2, 3, 4, 5]` the segment can be `[2, 3, 4]` which results in `[1, 4, 3, 2, 5]`.
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
prob : float
|
|
29
|
+
Probability to apply the mutation to the individual
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
super().__init__()
|
|
33
|
+
self.prob = prob
|
|
34
|
+
|
|
35
|
+
def _do(self, problem, X, **kwargs):
|
|
36
|
+
Y = X.copy()
|
|
37
|
+
for i, y in enumerate(X):
|
|
38
|
+
if np.random.random() < self.prob:
|
|
39
|
+
seq = random_sequence(len(y))
|
|
40
|
+
Y[i] = inversion_mutation(y, seq, inplace=True)
|
|
41
|
+
|
|
42
|
+
return Y
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.core.mutation import Mutation
|
|
4
|
+
from pymoo.core.variable import get, Real
|
|
5
|
+
from pymoo.operators.crossover.binx import mut_binomial
|
|
6
|
+
from pymoo.operators.repair.to_bound import set_to_bounds_if_outside
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
10
|
+
# Function
|
|
11
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def mut_pm(X, xl, xu, eta, prob, at_least_once):
|
|
15
|
+
n, n_var = X.shape
|
|
16
|
+
assert len(eta) == n
|
|
17
|
+
assert len(prob) == n
|
|
18
|
+
|
|
19
|
+
Xp = np.full(X.shape, np.inf)
|
|
20
|
+
|
|
21
|
+
mut = mut_binomial(n, n_var, prob, at_least_once=at_least_once)
|
|
22
|
+
mut[:, xl == xu] = False
|
|
23
|
+
|
|
24
|
+
Xp[:, :] = X
|
|
25
|
+
|
|
26
|
+
_xl = np.repeat(xl[None, :], X.shape[0], axis=0)[mut]
|
|
27
|
+
_xu = np.repeat(xu[None, :], X.shape[0], axis=0)[mut]
|
|
28
|
+
|
|
29
|
+
X = X[mut]
|
|
30
|
+
eta = np.tile(eta[:, None], (1, n_var))[mut]
|
|
31
|
+
|
|
32
|
+
delta1 = (X - _xl) / (_xu - _xl)
|
|
33
|
+
delta2 = (_xu - X) / (_xu - _xl)
|
|
34
|
+
|
|
35
|
+
mut_pow = 1.0 / (eta + 1.0)
|
|
36
|
+
|
|
37
|
+
rand = np.random.random(X.shape)
|
|
38
|
+
mask = rand <= 0.5
|
|
39
|
+
mask_not = np.logical_not(mask)
|
|
40
|
+
|
|
41
|
+
deltaq = np.zeros(X.shape)
|
|
42
|
+
|
|
43
|
+
xy = 1.0 - delta1
|
|
44
|
+
val = 2.0 * rand + (1.0 - 2.0 * rand) * (np.power(xy, (eta + 1.0)))
|
|
45
|
+
d = np.power(val, mut_pow) - 1.0
|
|
46
|
+
deltaq[mask] = d[mask]
|
|
47
|
+
|
|
48
|
+
xy = 1.0 - delta2
|
|
49
|
+
val = 2.0 * (1.0 - rand) + 2.0 * (rand - 0.5) * (np.power(xy, (eta + 1.0)))
|
|
50
|
+
d = 1.0 - (np.power(val, mut_pow))
|
|
51
|
+
deltaq[mask_not] = d[mask_not]
|
|
52
|
+
|
|
53
|
+
# mutated values
|
|
54
|
+
_Y = X + deltaq * (_xu - _xl)
|
|
55
|
+
|
|
56
|
+
# back in bounds if necessary (floating point issues)
|
|
57
|
+
_Y[_Y < _xl] = _xl[_Y < _xl]
|
|
58
|
+
_Y[_Y > _xu] = _xu[_Y > _xu]
|
|
59
|
+
|
|
60
|
+
# set the values for output
|
|
61
|
+
Xp[mut] = _Y
|
|
62
|
+
|
|
63
|
+
# in case out of bounds repair (very unlikely)
|
|
64
|
+
Xp = set_to_bounds_if_outside(Xp, xl, xu)
|
|
65
|
+
|
|
66
|
+
return Xp
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
70
|
+
# Class
|
|
71
|
+
# ---------------------------------------------------------------------------------------------------------
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class PolynomialMutation(Mutation):
|
|
75
|
+
|
|
76
|
+
def __init__(self, prob=0.9, eta=20, at_least_once=False, **kwargs):
|
|
77
|
+
super().__init__(prob=prob, **kwargs)
|
|
78
|
+
self.at_least_once = at_least_once
|
|
79
|
+
self.eta = Real(eta, bounds=(3.0, 30.0), strict=(1.0, 100.0))
|
|
80
|
+
|
|
81
|
+
def _do(self, problem, X, params=None, **kwargs):
|
|
82
|
+
X = X.astype(float)
|
|
83
|
+
|
|
84
|
+
eta = get(self.eta, size=len(X))
|
|
85
|
+
prob_var = self.get_prob_var(problem, size=len(X))
|
|
86
|
+
|
|
87
|
+
Xp = mut_pm(X, problem.xl, problem.xu, eta, prob_var, at_least_once=self.at_least_once)
|
|
88
|
+
|
|
89
|
+
return Xp
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class PM(PolynomialMutation):
|
|
93
|
+
pass
|
|
94
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.core.mutation import Mutation
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ChoiceRandomMutation(Mutation):
|
|
7
|
+
|
|
8
|
+
def _do(self, problem, X, **kwargs):
|
|
9
|
+
assert problem.vars is not None
|
|
10
|
+
|
|
11
|
+
# ensure the type object (fixed string length <UX can cause issues)
|
|
12
|
+
X = X.astype(object)
|
|
13
|
+
|
|
14
|
+
prob_var = self.get_prob_var(problem, size=len(X))
|
|
15
|
+
|
|
16
|
+
for k, (_, var) in enumerate(problem.vars.items()):
|
|
17
|
+
mut = np.where(np.random.random(len(X)) < prob_var)[0]
|
|
18
|
+
|
|
19
|
+
v = var.sample(len(mut))
|
|
20
|
+
X[mut, k] = v
|
|
21
|
+
|
|
22
|
+
return X
|
|
23
|
+
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.operators.repair.bounds_repair import BoundsRepair
|
|
4
|
+
from pymoo.util.misc import at_least_2d_array
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def bounce_back(X, xl, xu):
|
|
8
|
+
only_1d = (X.ndim == 1)
|
|
9
|
+
X = at_least_2d_array(X)
|
|
10
|
+
|
|
11
|
+
xl = np.repeat(xl[None, :], X.shape[0], axis=0)
|
|
12
|
+
xu = np.repeat(xu[None, :], X.shape[0], axis=0)
|
|
13
|
+
|
|
14
|
+
# otherwise bounds back into the feasible space
|
|
15
|
+
_range = xu - xl
|
|
16
|
+
X[X < xl] = (xl + np.mod((xl - X), _range))[X < xl]
|
|
17
|
+
X[X > xu] = (xu - np.mod((X - xu), _range))[X > xu]
|
|
18
|
+
|
|
19
|
+
if only_1d:
|
|
20
|
+
return X[0, :]
|
|
21
|
+
else:
|
|
22
|
+
return X
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def bounce_back_by_problem(problem, X):
|
|
26
|
+
return bounce_back(X, problem.xl, problem.xu)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class BounceBackOutOfBoundsRepair(BoundsRepair):
|
|
30
|
+
|
|
31
|
+
def repair_out_of_bounds(self, problem, X, **kwargs):
|
|
32
|
+
return bounce_back_by_problem(problem, X)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from pymoo.core.population import Population
|
|
6
|
+
from pymoo.core.repair import Repair
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def is_in_bounds(X, xl, xu):
|
|
10
|
+
return np.where(np.all(np.logical_and(X >= xl, X <= xu), axis=1))[0]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def is_in_bounds_by_problem(problem, X):
|
|
14
|
+
return is_in_bounds(X, problem.xl, problem.xu)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def is_out_of_bounds(X, xl, xu):
|
|
18
|
+
return np.where(np.any(np.logical_or(X < xl, X > xu), axis=1))[0]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def is_out_of_bounds_by_problem(problem, X):
|
|
22
|
+
return is_out_of_bounds(X, problem.xl, problem.xu)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def repeat_bounds(xl, xu, n):
|
|
26
|
+
XL = np.tile(xl, (n, 1))
|
|
27
|
+
XU = np.tile(xu, (n, 1))
|
|
28
|
+
return XL, XU
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def repair_clamp(Xp, xl, xu):
|
|
32
|
+
XL, XU = repeat_bounds(xl, xu, len(Xp))
|
|
33
|
+
|
|
34
|
+
I = np.where(Xp < XL)
|
|
35
|
+
Xp[I] = XL[I]
|
|
36
|
+
|
|
37
|
+
I = np.where(Xp > XU)
|
|
38
|
+
Xp[I] = XU[I]
|
|
39
|
+
|
|
40
|
+
return Xp
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def repair_periodic(Xp, xl, xu):
|
|
44
|
+
XL, XU = repeat_bounds(xl, xu, len(Xp))
|
|
45
|
+
|
|
46
|
+
S = (XU - XL)
|
|
47
|
+
|
|
48
|
+
I = np.where(Xp < XL)
|
|
49
|
+
Xp[I] = XU[I] - (XL[I] - Xp[I]) % S[I]
|
|
50
|
+
|
|
51
|
+
I = np.where(Xp > XU)
|
|
52
|
+
Xp[I] = XL[I] + (Xp[I] - XU[I]) % S[I]
|
|
53
|
+
|
|
54
|
+
return Xp
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def repair_random_init(Xp, X, xl, xu):
|
|
58
|
+
XL, XU = repeat_bounds(xl, xu, len(Xp))
|
|
59
|
+
|
|
60
|
+
i, j = np.where(Xp < XL)
|
|
61
|
+
if len(i) > 0:
|
|
62
|
+
Xp[i, j] = XL[i, j] + np.random.random(len(i)) * (X[i, j] - XL[i, j])
|
|
63
|
+
|
|
64
|
+
i, j = np.where(Xp > XU)
|
|
65
|
+
if len(i) > 0:
|
|
66
|
+
Xp[i, j] = XU[i, j] - np.random.random(len(i)) * (XU[i, j] - X[i, j])
|
|
67
|
+
|
|
68
|
+
return Xp
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class BoundsRepair(Repair):
|
|
72
|
+
|
|
73
|
+
def _do(self,
|
|
74
|
+
problem,
|
|
75
|
+
pop_or_X,
|
|
76
|
+
check_out_of_bounds=True,
|
|
77
|
+
**kwargs):
|
|
78
|
+
|
|
79
|
+
is_array = not isinstance(pop_or_X, Population)
|
|
80
|
+
|
|
81
|
+
X = pop_or_X if is_array else pop_or_X.get("X")
|
|
82
|
+
|
|
83
|
+
X = self.repair_out_of_bounds(problem, X, **kwargs)
|
|
84
|
+
|
|
85
|
+
assert len(is_out_of_bounds_by_problem(problem, X)) == 0
|
|
86
|
+
|
|
87
|
+
if is_array:
|
|
88
|
+
return X
|
|
89
|
+
else:
|
|
90
|
+
pop_or_X.set("X", X)
|
|
91
|
+
return pop_or_X
|
|
92
|
+
|
|
93
|
+
@abc.abstractmethod
|
|
94
|
+
def repair_out_of_bounds(self, problem, X, **kwargs):
|
|
95
|
+
pass
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.operators.repair.bounds_repair import BoundsRepair
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def inverse_penality(x, p, xl, xu, alpha=None):
|
|
7
|
+
assert len(p) == len(x)
|
|
8
|
+
|
|
9
|
+
normv = np.linalg.norm(p - x)
|
|
10
|
+
|
|
11
|
+
# violated boundaries
|
|
12
|
+
idl = x < xl
|
|
13
|
+
idr = xu < x
|
|
14
|
+
|
|
15
|
+
# if nothing is out of bounds just return the value
|
|
16
|
+
if not np.any(np.logical_or(idl, idr)):
|
|
17
|
+
return x
|
|
18
|
+
|
|
19
|
+
else:
|
|
20
|
+
# lower bounds of Y
|
|
21
|
+
diff = (p - x)
|
|
22
|
+
diff[diff == 0] = 1e-32
|
|
23
|
+
d = normv * np.max(np.maximum(idl * (xl - x) / diff, idr * (xu - x) / diff))
|
|
24
|
+
|
|
25
|
+
# upper bounds on Y
|
|
26
|
+
bounds = np.array([~idl * ((xl - x) / diff), ~idr * (xu - x) / diff])
|
|
27
|
+
|
|
28
|
+
D = normv * np.min(bounds[bounds > 0])
|
|
29
|
+
|
|
30
|
+
if alpha is None:
|
|
31
|
+
alpha = (normv - d) / normv
|
|
32
|
+
alpha += 1e-32
|
|
33
|
+
|
|
34
|
+
r = np.random.random()
|
|
35
|
+
Y = d * (1.0 + alpha * np.tan(r * np.arctan((D - d) / (alpha * d))))
|
|
36
|
+
|
|
37
|
+
ret = x + (p - x) * Y / normv
|
|
38
|
+
|
|
39
|
+
# for floating point error - in theory it will always be in bounds
|
|
40
|
+
ret[ret < xl] = xl[ret < xl]
|
|
41
|
+
ret[ret > xu] = xu[ret > xu]
|
|
42
|
+
|
|
43
|
+
return ret
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def inverse_penality_by_problem(problem, x, p, **kwargs):
|
|
47
|
+
return inverse_penality(x, p, problem.xl, problem.xu, **kwargs)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class InversePenaltyOutOfBoundsRepair(BoundsRepair):
|
|
51
|
+
|
|
52
|
+
def repair_out_of_bounds(self, problem, X, P=None, **kwargs):
|
|
53
|
+
if P is None:
|
|
54
|
+
raise Exception("For this out of bounds handling a parent solution in bounds needs to be provided.")
|
|
55
|
+
assert len(X) == len(P)
|
|
56
|
+
n = len(X)
|
|
57
|
+
|
|
58
|
+
for k in range(n):
|
|
59
|
+
X[k] = inverse_penality_by_problem(problem, X[k], P[k])
|
|
60
|
+
|
|
61
|
+
return X
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if __name__ == '__main__':
|
|
65
|
+
|
|
66
|
+
# lower and upper bounds
|
|
67
|
+
xl = np.zeros(2)
|
|
68
|
+
xu = np.ones(2)
|
|
69
|
+
|
|
70
|
+
# chosen parents
|
|
71
|
+
# p = np.array([0.1, 1.0])
|
|
72
|
+
p = np.array([0.5, 0.6])
|
|
73
|
+
|
|
74
|
+
c = np.array([-0.1, 1.0])
|
|
75
|
+
|
|
76
|
+
import matplotlib.pyplot as plt
|
|
77
|
+
|
|
78
|
+
plt.scatter(p[0], p[1], color="green", label="Parent")
|
|
79
|
+
plt.scatter(c[0], c[1], color="orange", label="Offspring")
|
|
80
|
+
|
|
81
|
+
data = []
|
|
82
|
+
for j in range(200):
|
|
83
|
+
ret = inverse_penality(c, p, xl, xu, alpha=None)
|
|
84
|
+
plt.scatter(ret[0], ret[1], facecolor="none", edgecolor="red", s=10, alpha=0.6)
|
|
85
|
+
|
|
86
|
+
plt.ylim(0.0, 1.3)
|
|
87
|
+
plt.xlim(-0.2, 1)
|
|
88
|
+
plt.legend()
|
|
89
|
+
plt.show()
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.core.repair import Repair
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class RoundingRepair(Repair):
|
|
7
|
+
|
|
8
|
+
def __init__(self, **kwargs) -> None:
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
Returns
|
|
12
|
+
-------
|
|
13
|
+
object
|
|
14
|
+
"""
|
|
15
|
+
super().__init__(**kwargs)
|
|
16
|
+
|
|
17
|
+
def _do(self, problem, X, **kwargs):
|
|
18
|
+
return np.around(X).astype(int)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.operators.repair.bounds_repair import BoundsRepair
|
|
4
|
+
from pymoo.util.misc import at_least_2d_array
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def set_to_bounds_if_outside(X, xl, xu):
|
|
8
|
+
_X, only_1d = at_least_2d_array(X, return_if_reshaped=True)
|
|
9
|
+
|
|
10
|
+
if xl is not None:
|
|
11
|
+
xl = np.repeat(xl[None, :], _X.shape[0], axis=0)
|
|
12
|
+
_X[_X < xl] = xl[_X < xl]
|
|
13
|
+
|
|
14
|
+
if xu is not None:
|
|
15
|
+
xu = np.repeat(xu[None, :], _X.shape[0], axis=0)
|
|
16
|
+
_X[_X > xu] = xu[_X > xu]
|
|
17
|
+
|
|
18
|
+
if only_1d:
|
|
19
|
+
return _X[0, :]
|
|
20
|
+
else:
|
|
21
|
+
return _X
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def set_to_bounds_if_outside_by_problem(problem, X):
|
|
25
|
+
return set_to_bounds_if_outside(X, problem.xl, problem.xu)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ToBoundOutOfBoundsRepair(BoundsRepair):
|
|
29
|
+
|
|
30
|
+
def repair_out_of_bounds(self, problem, X, **kwargs):
|
|
31
|
+
return set_to_bounds_if_outside_by_problem(problem, X)
|
|
File without changes
|