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
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Optimizer:
|
|
5
|
+
|
|
6
|
+
def __init__(self, precision=1e-6) -> None:
|
|
7
|
+
super().__init__()
|
|
8
|
+
self.has_converged = False
|
|
9
|
+
self.precision = precision
|
|
10
|
+
|
|
11
|
+
def next(self, X, dX):
|
|
12
|
+
_X = self._next(X, dX)
|
|
13
|
+
|
|
14
|
+
if np.abs(_X - X).mean() < self.precision:
|
|
15
|
+
self.has_converged = True
|
|
16
|
+
|
|
17
|
+
return _X
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class GradientDescent(Optimizer):
|
|
21
|
+
|
|
22
|
+
def __init__(self, learning_rate=0.01, **kwargs) -> None:
|
|
23
|
+
super().__init__(**kwargs)
|
|
24
|
+
self.learning_rate = learning_rate
|
|
25
|
+
|
|
26
|
+
def _next(self, X, dX):
|
|
27
|
+
return X - self.learning_rate * dX
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Adam(Optimizer):
|
|
31
|
+
|
|
32
|
+
def __init__(self, alpha=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-8, **kwargs) -> None:
|
|
33
|
+
super().__init__(**kwargs)
|
|
34
|
+
|
|
35
|
+
self.alpha = alpha
|
|
36
|
+
self.beta_1 = beta_1
|
|
37
|
+
self.beta_2 = beta_2
|
|
38
|
+
self.epsilon = epsilon
|
|
39
|
+
|
|
40
|
+
self.m_t = 0
|
|
41
|
+
self.v_t = 0
|
|
42
|
+
self.t = 0
|
|
43
|
+
|
|
44
|
+
def _next(self, X, dX):
|
|
45
|
+
self.t += 1
|
|
46
|
+
beta_1, beta_2 = self.beta_1, self.beta_2
|
|
47
|
+
|
|
48
|
+
# update moving average of gradient and squared gradient
|
|
49
|
+
self.m_t = beta_1 * self.m_t + (1 - beta_1) * dX
|
|
50
|
+
self.v_t = beta_2 * self.v_t + (1 - beta_2) * (dX * dX)
|
|
51
|
+
|
|
52
|
+
# calculates the bias-corrected estimates
|
|
53
|
+
m_cap = self.m_t / (1 - (beta_1 ** self.t))
|
|
54
|
+
v_cap = self.v_t / (1 - (beta_2 ** self.t))
|
|
55
|
+
|
|
56
|
+
# do the gradient update
|
|
57
|
+
_X = X - (self.alpha * m_cap) / (np.sqrt(v_cap) + self.epsilon)
|
|
58
|
+
|
|
59
|
+
return _X
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import numpy as np
|
|
3
|
+
from scipy.spatial.qhull import Delaunay
|
|
4
|
+
from scipy.stats import gmean
|
|
5
|
+
|
|
6
|
+
from pymoo.util.misc import distance_of_closest_points_to_others, vectorized_cdist, cdist
|
|
7
|
+
from pymoo.util.ref_dirs.das_dennis import DasDennis
|
|
8
|
+
from pymoo.util.reference_direction import get_partition_closest_to_points
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def distance_of_closest_point(ref_dirs):
|
|
12
|
+
_, dist = distance_of_closest_points_to_others(ref_dirs)
|
|
13
|
+
return dist.min()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def average_distance_to_other_points(ref_dirs):
|
|
17
|
+
D = vectorized_cdist(ref_dirs, ref_dirs)
|
|
18
|
+
D = D[np.triu_indices(len(ref_dirs), 1)]
|
|
19
|
+
return D.mean()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def closest_point_variance(z):
|
|
23
|
+
for row in np.eye(z.shape[1]):
|
|
24
|
+
if not np.any(np.all(row == z, axis=1)):
|
|
25
|
+
z = np.vstack([z, row])
|
|
26
|
+
|
|
27
|
+
D = vectorized_cdist(z, z)
|
|
28
|
+
np.fill_diagonal(D, 1)
|
|
29
|
+
|
|
30
|
+
return D.min(axis=1).var()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def closest_point_variance_mod(z):
|
|
34
|
+
n_points, n_dim = z.shape
|
|
35
|
+
|
|
36
|
+
for row in np.eye(z.shape[1]):
|
|
37
|
+
if not np.any(np.all(row == z, axis=1)):
|
|
38
|
+
z = np.vstack([z, row])
|
|
39
|
+
|
|
40
|
+
D = vectorized_cdist(z, z)
|
|
41
|
+
np.fill_diagonal(D, np.inf)
|
|
42
|
+
|
|
43
|
+
k = int(np.ceil(np.sqrt(n_dim)))
|
|
44
|
+
I = D.argsort(axis=1)[:, k - 1]
|
|
45
|
+
|
|
46
|
+
return D[np.arange(n_points), I].var()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def geometric_mean_var(z):
|
|
50
|
+
for row in np.eye(z.shape[1]):
|
|
51
|
+
if not np.any(np.all(row == z, axis=1)):
|
|
52
|
+
z = np.vstack([z, row])
|
|
53
|
+
n_points, n_dim = z.shape
|
|
54
|
+
|
|
55
|
+
D = vectorized_cdist(z, z)
|
|
56
|
+
np.fill_diagonal(D, np.inf)
|
|
57
|
+
|
|
58
|
+
k = n_dim - 1
|
|
59
|
+
I = D.argsort(axis=1)[:, :k]
|
|
60
|
+
|
|
61
|
+
first = np.column_stack([np.arange(n_points) for _ in range(k)])
|
|
62
|
+
|
|
63
|
+
val = gmean(D[first, I], axis=1)
|
|
64
|
+
|
|
65
|
+
return val.var()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def mean_mean(z):
|
|
69
|
+
for row in np.eye(z.shape[1]):
|
|
70
|
+
if not np.any(np.all(row == z, axis=1)):
|
|
71
|
+
z = np.vstack([z, row])
|
|
72
|
+
n_points, n_dim = z.shape
|
|
73
|
+
|
|
74
|
+
D = vectorized_cdist(z, z)
|
|
75
|
+
np.fill_diagonal(D, np.inf)
|
|
76
|
+
|
|
77
|
+
k = n_dim - 1
|
|
78
|
+
I = D.argsort(axis=1)[:, :k]
|
|
79
|
+
|
|
80
|
+
first = np.column_stack([np.arange(n_points) for _ in range(k)])
|
|
81
|
+
|
|
82
|
+
val = np.mean(D[first, I], axis=1)
|
|
83
|
+
|
|
84
|
+
return val.mean()
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def potential_energy(x):
|
|
88
|
+
_x = x / x.sum(axis=1)[:, None]
|
|
89
|
+
D = ((_x[:, None] - _x[None, :]) ** 2).sum(axis=2)
|
|
90
|
+
D = D[np.triu_indices(len(_x), 1)]
|
|
91
|
+
return (1 / D).mean()
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def iterative_igd(X, n_partitions=None, batch_size=100):
|
|
95
|
+
n_points, n_dim = X.shape
|
|
96
|
+
|
|
97
|
+
if n_partitions is None:
|
|
98
|
+
n_partitions = get_partition_closest_to_points(n_points * n_dim * 10, n_dim) + 1
|
|
99
|
+
|
|
100
|
+
scaling = 1 + 1 / 2
|
|
101
|
+
|
|
102
|
+
dd = DasDennis(n_partitions, n_dim, scaling=scaling)
|
|
103
|
+
val = 0
|
|
104
|
+
|
|
105
|
+
while dd.has_next():
|
|
106
|
+
points = dd.next(n_points=batch_size)
|
|
107
|
+
val += cdist(points, X).min(axis=1).sum()
|
|
108
|
+
|
|
109
|
+
val /= dd.number_of_points()
|
|
110
|
+
return val
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def gram_schmidt(X, row_vecs=True, norm=True):
|
|
114
|
+
if not row_vecs:
|
|
115
|
+
X = X.T
|
|
116
|
+
Y = X[0:1, :].copy()
|
|
117
|
+
for i in range(1, X.shape[0]):
|
|
118
|
+
proj = np.diag((X[i, :].dot(Y.T) / np.linalg.norm(Y, axis=1) ** 2).flat).dot(Y)
|
|
119
|
+
Y = np.vstack((Y, X[i, :] - proj.sum(0)))
|
|
120
|
+
if norm:
|
|
121
|
+
Y = np.diag(1 / np.linalg.norm(Y, axis=1)).dot(Y)
|
|
122
|
+
if row_vecs:
|
|
123
|
+
return Y
|
|
124
|
+
else:
|
|
125
|
+
return Y.T
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def triangulation(X):
|
|
129
|
+
return simplex_edge_difference(project_onto_one_dim_less(X))
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def project_onto_one_dim_less(X):
|
|
133
|
+
E = np.eye(X.shape[1])
|
|
134
|
+
P = E[0]
|
|
135
|
+
D = E[1:] - P
|
|
136
|
+
O = gram_schmidt(D)
|
|
137
|
+
return (X - P) @ O.T
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def simplex_edge_difference(X):
|
|
141
|
+
tri = Delaunay(X, qhull_options="QJ")
|
|
142
|
+
|
|
143
|
+
simplices = []
|
|
144
|
+
for e in tri.simplices:
|
|
145
|
+
diff = X[e[1:]] - X[e[0]]
|
|
146
|
+
det = np.linalg.det(diff)
|
|
147
|
+
if det > 1e-6:
|
|
148
|
+
simplices.append(e)
|
|
149
|
+
|
|
150
|
+
val = []
|
|
151
|
+
for triangle in simplices:
|
|
152
|
+
dists = np.zeros(len(triangle))
|
|
153
|
+
|
|
154
|
+
for i in range(len(triangle)):
|
|
155
|
+
a, b = triangle[i], triangle[(i + 1) % len(triangle)]
|
|
156
|
+
dists[i] = np.linalg.norm(X[a] - X[b])
|
|
157
|
+
|
|
158
|
+
val.append(dists.max() - dists.min())
|
|
159
|
+
|
|
160
|
+
val = np.array(val)
|
|
161
|
+
|
|
162
|
+
return val.mean()
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
from pymoo.util.misc import cdist
|
|
5
|
+
|
|
6
|
+
from pymoo.util.ref_dirs.misc import project_onto_unit_simplex_recursive
|
|
7
|
+
from pymoo.util.reference_direction import ReferenceDirectionFactory, sample_on_unit_simplex, \
|
|
8
|
+
select_points_with_maximum_distance, get_partition_closest_to_points, UniformReferenceDirectionFactory
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def kmeans(X, centroids, n_max_iter, a_tol, n_ignore):
|
|
12
|
+
|
|
13
|
+
for i in range(n_max_iter):
|
|
14
|
+
|
|
15
|
+
# copy the old centroids
|
|
16
|
+
last_centroids = np.copy(centroids)
|
|
17
|
+
|
|
18
|
+
# assign all points to one of the centroids
|
|
19
|
+
points_to_centroid = cdist(X, centroids).argmin(axis=1)
|
|
20
|
+
|
|
21
|
+
centroids_to_points = [[] for _ in range(len(centroids))]
|
|
22
|
+
for j, k in enumerate(points_to_centroid):
|
|
23
|
+
centroids_to_points[k].append(j)
|
|
24
|
+
|
|
25
|
+
for j in range(n_ignore, len(centroids_to_points)):
|
|
26
|
+
centroids[j] = np.mean(X[centroids_to_points[j]], axis=0)
|
|
27
|
+
|
|
28
|
+
project_onto_unit_simplex_recursive(centroids)
|
|
29
|
+
centroids /= centroids.sum(axis=1)[:, None]
|
|
30
|
+
|
|
31
|
+
delta = np.abs(centroids - last_centroids).sum(axis=1).mean()
|
|
32
|
+
|
|
33
|
+
if delta < a_tol:
|
|
34
|
+
break
|
|
35
|
+
|
|
36
|
+
return centroids
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ReductionBasedReferenceDirectionFactory(ReferenceDirectionFactory):
|
|
40
|
+
|
|
41
|
+
def __init__(self,
|
|
42
|
+
n_dim,
|
|
43
|
+
n_points,
|
|
44
|
+
scaling=None,
|
|
45
|
+
n_sample_points=10000,
|
|
46
|
+
sampling="kraemer",
|
|
47
|
+
kmeans=True,
|
|
48
|
+
kmeans_max_iter=1000,
|
|
49
|
+
kmeans_a_tol=0.0001,
|
|
50
|
+
**kwargs):
|
|
51
|
+
|
|
52
|
+
super().__init__(n_dim, scaling, **kwargs)
|
|
53
|
+
self.n_sample_points = n_sample_points
|
|
54
|
+
self.sampling = sampling
|
|
55
|
+
self.kmeans = kmeans
|
|
56
|
+
self.kmeans_max_iter = kmeans_max_iter
|
|
57
|
+
self.kmeans_a_tol = kmeans_a_tol
|
|
58
|
+
|
|
59
|
+
if n_points is None:
|
|
60
|
+
raise Exception("Please provide the number of points to be factored!")
|
|
61
|
+
|
|
62
|
+
self.n_points = n_points
|
|
63
|
+
|
|
64
|
+
def _do(self, random_state=None):
|
|
65
|
+
rnd = sample_on_unit_simplex(self.n_sample_points, self.n_dim, random_state=random_state, unit_simplex_mapping=self.sampling)
|
|
66
|
+
|
|
67
|
+
def h(n):
|
|
68
|
+
return get_partition_closest_to_points(n, self.n_dim)
|
|
69
|
+
|
|
70
|
+
H = h(self.n_points)
|
|
71
|
+
|
|
72
|
+
E = UniformReferenceDirectionFactory(self.n_dim, n_partitions=H).do()
|
|
73
|
+
E = E[np.any(E == 0, axis=1)]
|
|
74
|
+
|
|
75
|
+
# add the edge coordinates
|
|
76
|
+
X = np.vstack([E, rnd])
|
|
77
|
+
|
|
78
|
+
I = select_points_with_maximum_distance(X, self.n_points, selected=list(range((len(E)))))
|
|
79
|
+
centroids = X[I].copy()
|
|
80
|
+
|
|
81
|
+
if self.kmeans:
|
|
82
|
+
#centroids = kmeans(X, centroids, self.kmeans_max_iter, self.kmeans_a_tol, 0)
|
|
83
|
+
centroids = kmeans(X, centroids, self.kmeans_max_iter, self.kmeans_a_tol, len(E))
|
|
84
|
+
|
|
85
|
+
return centroids
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.core.problem import Problem
|
|
4
|
+
from pymoo.operators.sampling.lhs import LatinHypercubeSampling
|
|
5
|
+
from pymoo.util.reference_direction import ReferenceDirectionFactory, map_onto_unit_simplex
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RandomSamplingAndMap(ReferenceDirectionFactory):
|
|
9
|
+
|
|
10
|
+
def __init__(self,
|
|
11
|
+
n_dim,
|
|
12
|
+
n_points,
|
|
13
|
+
**kwargs):
|
|
14
|
+
super().__init__(n_dim, **kwargs)
|
|
15
|
+
self.n_points = n_points
|
|
16
|
+
|
|
17
|
+
def _do(self, random_state=None):
|
|
18
|
+
problem = Problem(n_var=self.n_dim, xl=0.0, xu=1.0)
|
|
19
|
+
sampling = LatinHypercubeSampling()
|
|
20
|
+
|
|
21
|
+
x = sampling(problem, self.n_points - self.n_dim, to_numpy=True, random_state=random_state)
|
|
22
|
+
x = map_onto_unit_simplex(x, "kraemer")
|
|
23
|
+
x = np.vstack([x, np.eye(self.n_dim)])
|
|
24
|
+
return x
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from scipy import special
|
|
5
|
+
|
|
6
|
+
from pymoo.util.misc import find_duplicates, cdist
|
|
7
|
+
from pymoo.util import default_random_state
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# =========================================================================================================
|
|
11
|
+
# Model
|
|
12
|
+
# =========================================================================================================
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def default_ref_dirs(m):
|
|
16
|
+
if m == 1:
|
|
17
|
+
return np.array([[1.0]])
|
|
18
|
+
elif m == 2:
|
|
19
|
+
return UniformReferenceDirectionFactory(m, n_partitions=99).do()
|
|
20
|
+
elif m == 3:
|
|
21
|
+
return UniformReferenceDirectionFactory(m, n_partitions=12).do()
|
|
22
|
+
else:
|
|
23
|
+
raise Exception("No default reference directions for more than 3 objectives. Please provide them directly:"
|
|
24
|
+
"https://pymoo.org/misc/reference_directions.html")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ReferenceDirectionFactory:
|
|
28
|
+
|
|
29
|
+
def __init__(self, n_dim, scaling=None, lexsort=True, verbose=False, **kwargs) -> None:
|
|
30
|
+
super().__init__()
|
|
31
|
+
self.n_dim = n_dim
|
|
32
|
+
self.scaling = scaling
|
|
33
|
+
self.lexsort = lexsort
|
|
34
|
+
self.verbose = verbose
|
|
35
|
+
|
|
36
|
+
def __call__(self):
|
|
37
|
+
return self.do()
|
|
38
|
+
|
|
39
|
+
@default_random_state(seed=1)
|
|
40
|
+
def do(self, random_state=None):
|
|
41
|
+
|
|
42
|
+
if self.n_dim == 1:
|
|
43
|
+
return np.array([[1.0]])
|
|
44
|
+
else:
|
|
45
|
+
|
|
46
|
+
val = self._do(random_state=random_state)
|
|
47
|
+
if isinstance(val, tuple):
|
|
48
|
+
ref_dirs, other = val[0], val[1:]
|
|
49
|
+
else:
|
|
50
|
+
ref_dirs = val
|
|
51
|
+
|
|
52
|
+
if self.scaling is not None:
|
|
53
|
+
ref_dirs = scale_reference_directions(ref_dirs, self.scaling)
|
|
54
|
+
|
|
55
|
+
# do ref_dirs is desired
|
|
56
|
+
if self.lexsort:
|
|
57
|
+
I = np.lexsort([ref_dirs[:, j] for j in range(ref_dirs.shape[1])][::-1])
|
|
58
|
+
ref_dirs = ref_dirs[I]
|
|
59
|
+
|
|
60
|
+
return ref_dirs
|
|
61
|
+
|
|
62
|
+
def _do(self, random_state=None):
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# =========================================================================================================
|
|
67
|
+
# Das Dennis Reference Directions (Uniform)
|
|
68
|
+
# =========================================================================================================
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def get_number_of_uniform_points(n_partitions, n_dim):
|
|
72
|
+
"""
|
|
73
|
+
Returns the number of uniform points that can be created uniformly.
|
|
74
|
+
"""
|
|
75
|
+
return int(special.binom(n_dim + n_partitions - 1, n_partitions))
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def get_partition_closest_to_points(n_points, n_dim):
|
|
79
|
+
"""
|
|
80
|
+
Returns the corresponding partition number which create the desired number of points
|
|
81
|
+
or less!
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
if n_dim == 1:
|
|
85
|
+
return 0
|
|
86
|
+
|
|
87
|
+
n_partitions = 1
|
|
88
|
+
_n_points = get_number_of_uniform_points(n_partitions, n_dim)
|
|
89
|
+
while _n_points <= n_points:
|
|
90
|
+
n_partitions += 1
|
|
91
|
+
_n_points = get_number_of_uniform_points(n_partitions, n_dim)
|
|
92
|
+
return n_partitions - 1
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def das_dennis(n_partitions, n_dim):
|
|
96
|
+
if n_partitions == 0:
|
|
97
|
+
return np.full((1, n_dim), 1 / n_dim)
|
|
98
|
+
else:
|
|
99
|
+
ref_dirs = []
|
|
100
|
+
ref_dir = np.full(n_dim, np.nan)
|
|
101
|
+
das_dennis_recursion(ref_dirs, ref_dir, n_partitions, n_partitions, 0)
|
|
102
|
+
return np.concatenate(ref_dirs, axis=0)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def das_dennis_recursion(ref_dirs, ref_dir, n_partitions, beta, depth):
|
|
106
|
+
if depth == len(ref_dir) - 1:
|
|
107
|
+
ref_dir[depth] = beta / (1.0 * n_partitions)
|
|
108
|
+
ref_dirs.append(ref_dir[None, :])
|
|
109
|
+
else:
|
|
110
|
+
for i in range(beta + 1):
|
|
111
|
+
ref_dir[depth] = 1.0 * i / (1.0 * n_partitions)
|
|
112
|
+
das_dennis_recursion(ref_dirs, np.copy(ref_dir), n_partitions, beta - i, depth + 1)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class UniformReferenceDirectionFactory(ReferenceDirectionFactory):
|
|
116
|
+
|
|
117
|
+
def __init__(self, n_dim, scaling=None, n_points=None, n_partitions=None, **kwargs) -> None:
|
|
118
|
+
super().__init__(n_dim, scaling=scaling, **kwargs)
|
|
119
|
+
|
|
120
|
+
if n_points is not None:
|
|
121
|
+
n_partitions = get_partition_closest_to_points(n_points, n_dim)
|
|
122
|
+
results_in = get_number_of_uniform_points(n_partitions, n_dim)
|
|
123
|
+
|
|
124
|
+
# the number of points are not matching to any partition number
|
|
125
|
+
if results_in != n_points:
|
|
126
|
+
results_in_next = get_number_of_uniform_points(n_partitions + 1, n_dim)
|
|
127
|
+
raise Exception("The number of points (n_points = %s) can not be created uniformly.\n"
|
|
128
|
+
"Either choose n_points = %s (n_partitions = %s) or "
|
|
129
|
+
"n_points = %s (n_partitions = %s)." %
|
|
130
|
+
(n_points, results_in, n_partitions, results_in_next, n_partitions + 1))
|
|
131
|
+
|
|
132
|
+
self.n_partitions = n_partitions
|
|
133
|
+
|
|
134
|
+
elif n_partitions is not None:
|
|
135
|
+
self.n_partitions = n_partitions
|
|
136
|
+
|
|
137
|
+
else:
|
|
138
|
+
raise Exception("Either provide number of partitions or number of points.")
|
|
139
|
+
|
|
140
|
+
def _do(self, random_state=None):
|
|
141
|
+
return das_dennis(self.n_partitions, self.n_dim)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
# =========================================================================================================
|
|
145
|
+
# Multi Layer
|
|
146
|
+
# =========================================================================================================
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class MultiLayerReferenceDirectionFactory:
|
|
150
|
+
|
|
151
|
+
def __init__(self, *args) -> None:
|
|
152
|
+
self.layers = []
|
|
153
|
+
self.layers.extend(args)
|
|
154
|
+
|
|
155
|
+
def __call__(self):
|
|
156
|
+
return self.do()
|
|
157
|
+
|
|
158
|
+
def add_layer(self, *args):
|
|
159
|
+
self.layers.extend(args)
|
|
160
|
+
|
|
161
|
+
def do(self):
|
|
162
|
+
ref_dirs = []
|
|
163
|
+
for factory in self.layers:
|
|
164
|
+
ref_dirs.append(factory)
|
|
165
|
+
ref_dirs = np.concatenate(ref_dirs, axis=0)
|
|
166
|
+
is_duplicate = find_duplicates(ref_dirs)
|
|
167
|
+
return ref_dirs[np.logical_not(is_duplicate)]
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# =========================================================================================================
|
|
171
|
+
# Util
|
|
172
|
+
# =========================================================================================================
|
|
173
|
+
|
|
174
|
+
@default_random_state
|
|
175
|
+
def get_rng(random_state=None, **kwargs):
|
|
176
|
+
return random_state
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@default_random_state
|
|
180
|
+
def sample_on_unit_simplex(n_points, n_dim, unit_simplex_mapping="kraemer", random_state=None, **kwargs):
|
|
181
|
+
if unit_simplex_mapping == "sum":
|
|
182
|
+
rnd = map_onto_unit_simplex(random_state.random((n_points, n_dim)), "sum")
|
|
183
|
+
|
|
184
|
+
elif unit_simplex_mapping == "kraemer":
|
|
185
|
+
rnd = map_onto_unit_simplex(random_state.random((n_points, n_dim)), "kraemer")
|
|
186
|
+
|
|
187
|
+
elif unit_simplex_mapping == "das-dennis":
|
|
188
|
+
n_partitions = get_partition_closest_to_points(n_points, n_dim)
|
|
189
|
+
rnd = UniformReferenceDirectionFactory(n_dim, n_partitions=n_partitions).do()
|
|
190
|
+
|
|
191
|
+
else:
|
|
192
|
+
raise Exception("Please define a valid sampling on unit simplex strategy!")
|
|
193
|
+
|
|
194
|
+
return rnd
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def map_onto_unit_simplex(rnd, method):
|
|
198
|
+
n_points, n_dim = rnd.shape
|
|
199
|
+
|
|
200
|
+
if method == "sum":
|
|
201
|
+
ret = rnd / rnd.sum(axis=1)[:, None]
|
|
202
|
+
|
|
203
|
+
elif method == "kraemer":
|
|
204
|
+
M = sys.maxsize
|
|
205
|
+
|
|
206
|
+
rnd *= M
|
|
207
|
+
rnd = rnd[:, :n_dim - 1]
|
|
208
|
+
rnd = np.column_stack([np.zeros(n_points), rnd, np.full(n_points, M)])
|
|
209
|
+
|
|
210
|
+
rnd = np.sort(rnd, axis=1)
|
|
211
|
+
|
|
212
|
+
ret = np.full((n_points, n_dim), np.nan)
|
|
213
|
+
for i in range(1, n_dim + 1):
|
|
214
|
+
ret[:, i - 1] = rnd[:, i] - rnd[:, i - 1]
|
|
215
|
+
ret /= M
|
|
216
|
+
|
|
217
|
+
else:
|
|
218
|
+
raise Exception("Invalid unit simplex mapping!")
|
|
219
|
+
|
|
220
|
+
return ret
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def scale_reference_directions(ref_dirs, scaling):
|
|
224
|
+
return ref_dirs * scaling + ((1 - scaling) / ref_dirs.shape[1])
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def select_points_with_maximum_distance(X, n_select, selected=[], random_state=None):
|
|
228
|
+
n_points, n_dim = X.shape
|
|
229
|
+
|
|
230
|
+
# calculate the distance matrix
|
|
231
|
+
D = cdist(X, X)
|
|
232
|
+
|
|
233
|
+
# if no selection provided pick randomly in the beginning
|
|
234
|
+
if len(selected) == 0:
|
|
235
|
+
# random_state should be provided by caller
|
|
236
|
+
selected = [random_state.integers(len(X))]
|
|
237
|
+
|
|
238
|
+
# create variables to store what selected and what not
|
|
239
|
+
not_selected = [i for i in range(n_points) if i not in selected]
|
|
240
|
+
|
|
241
|
+
# remove unnecessary points
|
|
242
|
+
dist_to_closest_selected = D[:, selected].min(axis=1)
|
|
243
|
+
|
|
244
|
+
# now select the points until sufficient ones are found
|
|
245
|
+
while len(selected) < n_select:
|
|
246
|
+
# find point that has the maximum distance to all others
|
|
247
|
+
index_in_not_selected = dist_to_closest_selected[not_selected].argmax()
|
|
248
|
+
I = not_selected[index_in_not_selected]
|
|
249
|
+
|
|
250
|
+
# add the closest distance to selected point
|
|
251
|
+
is_closer = D[I] < dist_to_closest_selected
|
|
252
|
+
dist_to_closest_selected[is_closer] = D[I][is_closer]
|
|
253
|
+
|
|
254
|
+
# add it to the selected and remove from not selected
|
|
255
|
+
selected.append(I)
|
|
256
|
+
not_selected = np.delete(not_selected, index_in_not_selected)
|
|
257
|
+
|
|
258
|
+
return selected
|
pymoo/util/remote.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import urllib.request
|
|
4
|
+
from os.path import join, dirname, abspath
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
from pymoo.config import Config
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Remote:
|
|
12
|
+
# -------------------------------------------------
|
|
13
|
+
# Singleton Pattern
|
|
14
|
+
# -------------------------------------------------
|
|
15
|
+
__instance = None
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def get_instance():
|
|
19
|
+
if Remote.__instance is None:
|
|
20
|
+
server = Config.data()
|
|
21
|
+
folder = join(dirname(dirname(abspath(__file__))), 'data')
|
|
22
|
+
Remote.__instance = Remote(server, folder)
|
|
23
|
+
return Remote.__instance
|
|
24
|
+
|
|
25
|
+
# -------------------------------------------------
|
|
26
|
+
|
|
27
|
+
def __init__(self, server, folder=None) -> None:
|
|
28
|
+
super().__init__()
|
|
29
|
+
self.server = server
|
|
30
|
+
self.folder = folder
|
|
31
|
+
|
|
32
|
+
def load(self, *args, to="numpy"):
|
|
33
|
+
|
|
34
|
+
# the local file we can try loading
|
|
35
|
+
f = join(str(self.folder), *args)
|
|
36
|
+
|
|
37
|
+
# check if that path already exists
|
|
38
|
+
if not os.path.exists(f):
|
|
39
|
+
|
|
40
|
+
# if not make sure to create it that the file can be written
|
|
41
|
+
folder = dirname(f)
|
|
42
|
+
if not os.path.exists(folder):
|
|
43
|
+
os.makedirs(folder)
|
|
44
|
+
|
|
45
|
+
# create the url to load it from and download the file remotely
|
|
46
|
+
url = self.server + "/".join(args)
|
|
47
|
+
urllib.request.urlretrieve(url, f)
|
|
48
|
+
|
|
49
|
+
if to == "numpy":
|
|
50
|
+
return np.loadtxt(f)
|
|
51
|
+
elif to == "json":
|
|
52
|
+
with open(f) as file:
|
|
53
|
+
return json.load(file)
|
|
54
|
+
|
|
55
|
+
return f
|
pymoo/util/roulette.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from pymoo.util import default_random_state
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class RouletteWheelSelection:
|
|
6
|
+
|
|
7
|
+
def __init__(self, val, larger_is_better=True):
|
|
8
|
+
super().__init__()
|
|
9
|
+
if not larger_is_better:
|
|
10
|
+
val = val.max() - val
|
|
11
|
+
_sum = val.sum()
|
|
12
|
+
self.cumulative = np.array([val[:k].sum() / _sum for k in range(1, len(val))])
|
|
13
|
+
|
|
14
|
+
@default_random_state
|
|
15
|
+
def next(self, n=None, random_state=None):
|
|
16
|
+
if n is None:
|
|
17
|
+
X = random_state.random((1, 1))
|
|
18
|
+
else:
|
|
19
|
+
X = random_state.random((n, 1))
|
|
20
|
+
if n > 1:
|
|
21
|
+
X.repeat(n - 1, axis=1)
|
|
22
|
+
|
|
23
|
+
M = self.cumulative[None, :].repeat(len(X), axis=0)
|
|
24
|
+
B = X >= M
|
|
25
|
+
ret = B.sum(axis=1)
|
|
26
|
+
|
|
27
|
+
if n is None:
|
|
28
|
+
return ret[0]
|
|
29
|
+
return ret
|