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,296 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from pymoo.visualization.matplotlib import matplotlib, patches, PatchCollection, plt, animation
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_circle_points(n_points):
|
|
8
|
+
t = np.linspace(0, 2 * np.pi, n_points, endpoint=False)
|
|
9
|
+
return np.column_stack([np.cos(t), np.sin(t)])
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def default_number_to_text(val):
|
|
13
|
+
if val > 1e3:
|
|
14
|
+
return "{:.2e}".format(val)
|
|
15
|
+
else:
|
|
16
|
+
return "{:.2f}".format(val)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def in_notebook():
|
|
20
|
+
return 'ipykernel' in sys.modules
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_uniform_points_around_circle(n):
|
|
24
|
+
t = 2 * np.pi * np.arange(n) / n
|
|
25
|
+
s = np.column_stack([np.cos(t), np.sin(t)])
|
|
26
|
+
return s
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def plot_circle(ax, center=0, radius=1, **kwargs):
|
|
30
|
+
P = get_circle_points(5000)
|
|
31
|
+
P = (P + center) * radius
|
|
32
|
+
plot(P[:, 0], P[:, 1], **kwargs)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def plot_radar_line(ax, x, **kwargs):
|
|
36
|
+
x = np.vstack([x, x[0]])
|
|
37
|
+
plot(x[:, 0], x[:, 1], **kwargs)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def plot_axes_arrow(ax, X, extend_factor=1.0, **kwargs):
|
|
41
|
+
for (x, y) in X:
|
|
42
|
+
ax.arrow(0, 0, x * extend_factor, y * extend_factor, **kwargs)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def plot_axes_lines(ax, X, extend_factor=1.0, **kwargs):
|
|
46
|
+
for (x, y) in X:
|
|
47
|
+
plot([0, x * extend_factor], [0, y * extend_factor], **kwargs)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def plot_polygon(ax, x, **kwargs):
|
|
51
|
+
ax.add_collection(PatchCollection([patches.Polygon(x, closed=True)], **kwargs))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def plot_axis_labels(ax, endpoints, labels, margin=0.035, size='small', **kwargs):
|
|
55
|
+
for k in range(len(labels)):
|
|
56
|
+
xy = endpoints[k]
|
|
57
|
+
|
|
58
|
+
if xy[0] < 0.0:
|
|
59
|
+
x = xy[0] - margin
|
|
60
|
+
ha = "right"
|
|
61
|
+
else:
|
|
62
|
+
x = xy[0] + margin
|
|
63
|
+
ha = "left"
|
|
64
|
+
|
|
65
|
+
if xy[1] < 0.0:
|
|
66
|
+
y = xy[1] - margin
|
|
67
|
+
va = "top"
|
|
68
|
+
else:
|
|
69
|
+
y = xy[1] + margin
|
|
70
|
+
va = "bottom"
|
|
71
|
+
|
|
72
|
+
ax.text(x, y, labels[k], ha=ha, va=va, size=size, **kwargs)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def equal_axis(ax):
|
|
76
|
+
ax.set_xlim([-1.1, 1.1])
|
|
77
|
+
ax.set_ylim([-1.1, 1.1])
|
|
78
|
+
ax.axis('equal')
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def no_ticks(ax):
|
|
82
|
+
ax.set_yticks([])
|
|
83
|
+
ax.set_xticks([])
|
|
84
|
+
ax.set_frame_on(False)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def normalize(data, bounds, reverse=False, return_bounds=False):
|
|
88
|
+
from pymoo.util.normalization import normalize as _normalize
|
|
89
|
+
|
|
90
|
+
_F = np.vstack([e[0] for e in data])
|
|
91
|
+
if bounds is None:
|
|
92
|
+
bounds = (_F.min(axis=0), _F.max(axis=0))
|
|
93
|
+
|
|
94
|
+
to_plot = []
|
|
95
|
+
for k in range(len(data)):
|
|
96
|
+
F = _normalize(data[k][0], bounds[0], bounds[1])
|
|
97
|
+
|
|
98
|
+
if reverse:
|
|
99
|
+
F = 1 - F
|
|
100
|
+
|
|
101
|
+
to_plot.append([F, data[k][1]])
|
|
102
|
+
|
|
103
|
+
if return_bounds:
|
|
104
|
+
return to_plot, bounds
|
|
105
|
+
else:
|
|
106
|
+
return to_plot
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def parse_bounds(bounds, n_dim):
|
|
110
|
+
if bounds is not None:
|
|
111
|
+
bounds = np.array(bounds, dtype=float)
|
|
112
|
+
if bounds.ndim == 1:
|
|
113
|
+
bounds = bounds[None, :].repeat(n_dim, axis=0).T
|
|
114
|
+
return bounds
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def radviz_pandas(F):
|
|
118
|
+
import pandas as pd
|
|
119
|
+
df = pd.DataFrame([x for x in F], columns=["X%s" % k for k in range(F.shape[1])])
|
|
120
|
+
df["class"] = "Points"
|
|
121
|
+
return pd.plotting.radviz(df, "class")
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def plot(*args, show=True, labels=None, no_fill=False, **kwargs):
|
|
125
|
+
import numpy as np
|
|
126
|
+
F = np.array(args[0])
|
|
127
|
+
|
|
128
|
+
if F.ndim == 1:
|
|
129
|
+
print("Cannot plot a one dimensional array.")
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
n_dim = F.shape[1]
|
|
133
|
+
|
|
134
|
+
if n_dim == 2:
|
|
135
|
+
ret = plot_2d(*args, labels=labels, no_fill=no_fill, **kwargs)
|
|
136
|
+
elif n_dim == 3:
|
|
137
|
+
ret = plot_3d(*args, labels=labels, no_fill=no_fill, **kwargs)
|
|
138
|
+
else:
|
|
139
|
+
print("Cannot plot a %s dimensional array." % n_dim)
|
|
140
|
+
return
|
|
141
|
+
|
|
142
|
+
if labels:
|
|
143
|
+
plt.legend()
|
|
144
|
+
|
|
145
|
+
if show and matplotlib.get_backend().lower() != "agg":
|
|
146
|
+
plt.show()
|
|
147
|
+
|
|
148
|
+
return ret
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def plot_3d(*args, no_fill=False, labels=None, **kwargs):
|
|
152
|
+
fig = plt.figure()
|
|
153
|
+
ax = fig.add_subplot(111, projection='3d')
|
|
154
|
+
|
|
155
|
+
for i, F in enumerate(args):
|
|
156
|
+
|
|
157
|
+
if no_fill:
|
|
158
|
+
kwargs["s"] = 20
|
|
159
|
+
kwargs["marker"] = '.'
|
|
160
|
+
kwargs["facecolors"] = (0, 0, 0, 0)
|
|
161
|
+
kwargs["edgecolors"] = 'r'
|
|
162
|
+
|
|
163
|
+
if labels:
|
|
164
|
+
ax.scatter(F[:, 0], F[:, 1], F[:, 2], label=labels[i], **kwargs)
|
|
165
|
+
else:
|
|
166
|
+
ax.scatter(F[:, 0], F[:, 1], F[:, 2], **kwargs)
|
|
167
|
+
|
|
168
|
+
return ax
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def plot_2d(*args, labels=None, no_fill=False):
|
|
172
|
+
if no_fill:
|
|
173
|
+
kwargs = dict(
|
|
174
|
+
s=20,
|
|
175
|
+
facecolors='none',
|
|
176
|
+
edgecolors='r'
|
|
177
|
+
)
|
|
178
|
+
else:
|
|
179
|
+
kwargs = {}
|
|
180
|
+
|
|
181
|
+
for i, F in enumerate(args):
|
|
182
|
+
if labels:
|
|
183
|
+
plt.scatter(F[:, 0], F[:, 1], label=labels[i], **kwargs)
|
|
184
|
+
else:
|
|
185
|
+
plt.scatter(F[:, 0], F[:, 1], **kwargs)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def animate(path_to_file, H, problem=None, func_iter=None, plot_min=None, plot_max=None):
|
|
189
|
+
if H.ndim != 3 or H.shape[2] != 2:
|
|
190
|
+
print("Can only animate a two dimensional set of arrays.")
|
|
191
|
+
return
|
|
192
|
+
|
|
193
|
+
fig = plt.figure()
|
|
194
|
+
ax = plt.gca()
|
|
195
|
+
|
|
196
|
+
# plot the pareto front if it is known for the problem
|
|
197
|
+
if problem is not None:
|
|
198
|
+
pf = problem.pareto_front()
|
|
199
|
+
plt.scatter(pf[:, 0], pf[:, 1], label='Pareto Front', s=60, facecolors='none', edgecolors='r')
|
|
200
|
+
|
|
201
|
+
# plot the initial population
|
|
202
|
+
_F = H[0, :, :]
|
|
203
|
+
scat = plt.scatter(_F[:, 0], _F[:, 1])
|
|
204
|
+
plt.title("0")
|
|
205
|
+
|
|
206
|
+
if func_iter is not None:
|
|
207
|
+
func_iter(ax, H[0])
|
|
208
|
+
|
|
209
|
+
# the update method
|
|
210
|
+
def update(n):
|
|
211
|
+
_F = H[n, :, :]
|
|
212
|
+
scat.set_offsets(_F)
|
|
213
|
+
|
|
214
|
+
# get the bounds for plotting and add padding
|
|
215
|
+
min = np.min(_F, axis=0) - 0.1
|
|
216
|
+
max = np.max(_F, axis=0) + 0.1
|
|
217
|
+
|
|
218
|
+
# set the scatter object with padding
|
|
219
|
+
ax.set_xlim(min[0], max[0])
|
|
220
|
+
ax.set_ylim(min[1], max[1])
|
|
221
|
+
|
|
222
|
+
if func_iter is not None:
|
|
223
|
+
func_iter(ax, H[n])
|
|
224
|
+
|
|
225
|
+
plt.title(n)
|
|
226
|
+
|
|
227
|
+
# create the animation
|
|
228
|
+
ani = animation.FuncAnimation(fig, update, frames=H.shape[0])
|
|
229
|
+
|
|
230
|
+
# write the file
|
|
231
|
+
Writer = animation.writers['ffmpeg']
|
|
232
|
+
writer = Writer(fps=6, bitrate=1800)
|
|
233
|
+
ani.save(path_to_file, writer=writer)
|
|
234
|
+
|
|
235
|
+
print("Saving: ", path_to_file)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def plot_problem_surface(problem, n_samples, plot_type="wireframe", cmap="summer", show=True, return_figure=False):
|
|
239
|
+
try:
|
|
240
|
+
from pymoo.visualization.matplotlib import plt
|
|
241
|
+
from mpl_toolkits.mplot3d import Axes3D
|
|
242
|
+
except:
|
|
243
|
+
raise Exception("Please install 'matplotlib' to use the plotting functionality.")
|
|
244
|
+
|
|
245
|
+
fig = plt.figure()
|
|
246
|
+
|
|
247
|
+
if problem.n_var == 1 and problem.n_obj == 1:
|
|
248
|
+
|
|
249
|
+
X = np.linspace(problem.xl[0], problem.xu[0], num=n_samples)[:, None]
|
|
250
|
+
Y = problem.evaluate(X, return_values_of=["F"])
|
|
251
|
+
ax = plt.plot(X, Y)
|
|
252
|
+
|
|
253
|
+
elif problem.n_var == 2 and problem.n_obj == 1:
|
|
254
|
+
|
|
255
|
+
X_range = np.linspace(problem.xl[0], problem.xu[0], num=n_samples)
|
|
256
|
+
Y_range = np.linspace(problem.xl[1], problem.xu[1], num=n_samples)
|
|
257
|
+
X, Y = np.meshgrid(X_range, Y_range)
|
|
258
|
+
|
|
259
|
+
A = np.zeros((n_samples * n_samples, 2))
|
|
260
|
+
counter = 0
|
|
261
|
+
for i, x in enumerate(X_range):
|
|
262
|
+
for j, y in enumerate(Y_range):
|
|
263
|
+
A[counter, 0] = x
|
|
264
|
+
A[counter, 1] = y
|
|
265
|
+
counter += 1
|
|
266
|
+
|
|
267
|
+
F = np.reshape(problem.evaluate(A, return_values_of=["F"]), (n_samples, n_samples))
|
|
268
|
+
|
|
269
|
+
# Plot the surface.
|
|
270
|
+
if plot_type == "wireframe":
|
|
271
|
+
ax = fig.add_subplot(111, projection='3d')
|
|
272
|
+
ax.plot_wireframe(X, Y, F)
|
|
273
|
+
elif plot_type == "contour":
|
|
274
|
+
CS = plt.contour(X, Y, F)
|
|
275
|
+
plt.clabel(CS, inline=1, fontsize=10)
|
|
276
|
+
elif plot_type == "wireframe+contour":
|
|
277
|
+
ax = fig.add_subplot(111, projection="3d")
|
|
278
|
+
ax.plot_surface(X, Y, F, cmap=cmap, rstride=1, cstride=1)
|
|
279
|
+
ax.contour(X, Y, F, 10, linestyles="solid", offset=-1)
|
|
280
|
+
ax.set_xlabel("$x_1$")
|
|
281
|
+
ax.set_ylabel("$x_2$")
|
|
282
|
+
ax.set_zlabel("$f(x)$")
|
|
283
|
+
ax.view_init(45, 45)
|
|
284
|
+
else:
|
|
285
|
+
raise Exception("Unknown plotting method.")
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
else:
|
|
289
|
+
raise Exception("Can only plot single with less than two variables and one objective.")
|
|
290
|
+
|
|
291
|
+
if show:
|
|
292
|
+
plt.tight_layout()
|
|
293
|
+
plt.show()
|
|
294
|
+
|
|
295
|
+
if return_figure:
|
|
296
|
+
return fig, ax
|
|
File without changes
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from pymoo.visualization.matplotlib import plt
|
|
2
|
+
|
|
3
|
+
from pymoo.core.callback import Callback
|
|
4
|
+
from pymoo.visualization.scatter import Scatter
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AnimationCallback(Callback):
|
|
8
|
+
|
|
9
|
+
def __init__(self,
|
|
10
|
+
do_show=False,
|
|
11
|
+
do_close=True,
|
|
12
|
+
nth_gen=1,
|
|
13
|
+
dpi=None,
|
|
14
|
+
recorder=None,
|
|
15
|
+
fname=None,
|
|
16
|
+
exception_if_not_applicable=True):
|
|
17
|
+
|
|
18
|
+
super().__init__()
|
|
19
|
+
self.nth_gen = nth_gen
|
|
20
|
+
self.do_show = do_show
|
|
21
|
+
self.do_close = do_close
|
|
22
|
+
self.exception_if_not_applicable = exception_if_not_applicable
|
|
23
|
+
|
|
24
|
+
self.recorder = recorder
|
|
25
|
+
if self.recorder is None and fname is not None:
|
|
26
|
+
try:
|
|
27
|
+
from pyrecorder.recorder import Recorder
|
|
28
|
+
from pyrecorder.writers.video import Video
|
|
29
|
+
from pyrecorder.converters.matplotlib import Matplotlib
|
|
30
|
+
self.recorder = Recorder(Video(fname), converter=Matplotlib(dpi=dpi))
|
|
31
|
+
except:
|
|
32
|
+
raise Exception("Please install or update pyrecorder for animation support: pip install -U pyrecorder")
|
|
33
|
+
|
|
34
|
+
def update(self, algorithm):
|
|
35
|
+
if algorithm.n_gen == 1 or algorithm.n_gen % self.nth_gen == 0:
|
|
36
|
+
try:
|
|
37
|
+
|
|
38
|
+
figure = self.do(algorithm.problem, algorithm)
|
|
39
|
+
|
|
40
|
+
if self.do_show:
|
|
41
|
+
if figure is not None:
|
|
42
|
+
figure.show()
|
|
43
|
+
else:
|
|
44
|
+
plt.show()
|
|
45
|
+
|
|
46
|
+
if self.recorder is not None:
|
|
47
|
+
self.recorder.record(fig=figure)
|
|
48
|
+
|
|
49
|
+
if self.do_close:
|
|
50
|
+
plt.close(fig=figure)
|
|
51
|
+
|
|
52
|
+
return figure
|
|
53
|
+
|
|
54
|
+
except Exception as ex:
|
|
55
|
+
if self.exception_if_not_applicable:
|
|
56
|
+
raise ex
|
|
57
|
+
|
|
58
|
+
def do(self, problem, algorithm, **kwargs):
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class ObjectiveSpaceAnimation(AnimationCallback):
|
|
63
|
+
|
|
64
|
+
def __init__(self, recorder=None, **kwargs):
|
|
65
|
+
if recorder is None:
|
|
66
|
+
from pyrecorder.recorder import Recorder
|
|
67
|
+
from pyrecorder.writers.streamer import Streamer
|
|
68
|
+
recorder = Recorder(Streamer())
|
|
69
|
+
super().__init__(recorder=recorder, **kwargs)
|
|
70
|
+
|
|
71
|
+
def update(self, algorithm):
|
|
72
|
+
F = algorithm.opt.get("F")
|
|
73
|
+
pf = algorithm.problem.pareto_front()
|
|
74
|
+
|
|
75
|
+
sc = Scatter()
|
|
76
|
+
sc.add(F)
|
|
77
|
+
if pf is not None:
|
|
78
|
+
sc.add(pf, plot_type="line", color="black", alpha=0.7)
|
|
79
|
+
sc.do()
|
|
80
|
+
|
|
81
|
+
self.recorder.record()
|
|
82
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from pymoo.visualization.matplotlib import plt
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from pymoo.visualization.video.callback_video import AnimationCallback
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class OneVariableOneObjectiveVisualization(AnimationCallback):
|
|
8
|
+
|
|
9
|
+
def __init__(self,
|
|
10
|
+
n_samples_for_surface=10000,
|
|
11
|
+
**kwargs):
|
|
12
|
+
super().__init__(**kwargs)
|
|
13
|
+
self.last_pop = None
|
|
14
|
+
self.n_samples_for_surface = n_samples_for_surface
|
|
15
|
+
|
|
16
|
+
def do(self, problem, algorithm):
|
|
17
|
+
|
|
18
|
+
# check whether the visualization can be done or not - throw exception or simply do nothing
|
|
19
|
+
if problem.n_var != 1 or problem.n_obj != 1:
|
|
20
|
+
raise Exception("This visualization can only be used for problems with one variable and one objective!")
|
|
21
|
+
|
|
22
|
+
# draw the problem surface
|
|
23
|
+
xl, xu = problem.bounds()
|
|
24
|
+
_X = np.linspace(xl, xu, self.n_samples_for_surface)
|
|
25
|
+
_F = problem.evaluate(_X)
|
|
26
|
+
plt.plot(_X, _F, label="True", color="black", alpha=0.6)
|
|
27
|
+
plt.ylim(xl[0], xu[0])
|
|
28
|
+
plt.ylim(_F.min(), _F.max())
|
|
29
|
+
|
|
30
|
+
pop = algorithm.pop
|
|
31
|
+
|
|
32
|
+
X, F, CV = pop.get("X", "F", "CV")
|
|
33
|
+
plt.scatter(X[:, 0], F[:, 0], color="blue", marker="o", s=70)
|
|
34
|
+
|
|
35
|
+
is_new = np.full(len(pop), True)
|
|
36
|
+
if self.last_pop is not None:
|
|
37
|
+
for k, ind in enumerate(pop):
|
|
38
|
+
if ind in self.last_pop:
|
|
39
|
+
is_new[k] = False
|
|
40
|
+
|
|
41
|
+
# plot the new population
|
|
42
|
+
if is_new.sum() > 0:
|
|
43
|
+
X, F, CV = pop[is_new].get("X", "F", "CV")
|
|
44
|
+
plt.scatter(X[:, 0], F[:, 0], color="red", marker="*", s=70)
|
|
45
|
+
|
|
46
|
+
if hasattr(algorithm, "off") and algorithm.off is not None:
|
|
47
|
+
X, F, CV = algorithm.off.get("X", "F", "CV")
|
|
48
|
+
plt.scatter(X[:, 0], F[:, 0], color="purple", marker="*", s=40)
|
|
49
|
+
|
|
50
|
+
plt.title(f"Generation: {algorithm.n_gen}")
|
|
51
|
+
plt.legend()
|
|
52
|
+
|
|
53
|
+
# store the current population as the last
|
|
54
|
+
self.last_pop = set(pop)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from pymoo.visualization.matplotlib import plt
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from pymoo.visualization.fitness_landscape import FitnessLandscape
|
|
5
|
+
from pymoo.visualization.video.callback_video import AnimationCallback
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TwoVariablesOneObjectiveVisualization(AnimationCallback):
|
|
9
|
+
|
|
10
|
+
def __init__(self,
|
|
11
|
+
n_samples_for_surface=10000,
|
|
12
|
+
**kwargs):
|
|
13
|
+
super().__init__(**kwargs)
|
|
14
|
+
self.last_pop = None
|
|
15
|
+
self.n_samples_for_surface = n_samples_for_surface
|
|
16
|
+
|
|
17
|
+
def do(self, problem, algorithm):
|
|
18
|
+
|
|
19
|
+
# check whether the visualization can be done or not - throw exception or simply do nothing
|
|
20
|
+
if problem.n_var != 2 or problem.n_obj != 1:
|
|
21
|
+
raise Exception("This visualization can only be used for problems with two variables and one objective!")
|
|
22
|
+
|
|
23
|
+
# draw the problem surface
|
|
24
|
+
# if algorithm.surrogate.targets["F"].doe is not None:
|
|
25
|
+
# problem = algorithm.surrogate
|
|
26
|
+
plot = FitnessLandscape(problem, _type="contour", kwargs_contour=dict(alpha=0.5))
|
|
27
|
+
plot.do()
|
|
28
|
+
|
|
29
|
+
# get the population
|
|
30
|
+
pop = algorithm.pop
|
|
31
|
+
|
|
32
|
+
X, F, CV = pop.get("X", "F", "CV")
|
|
33
|
+
plt.scatter(X[:, 0], X[:, 1], facecolor="none", edgecolors="black", marker="o", s=50, label="Solutions")
|
|
34
|
+
|
|
35
|
+
if hasattr(algorithm, "off") and algorithm.off is not None:
|
|
36
|
+
X, F, CV = algorithm.off.get("X", "F", "CV")
|
|
37
|
+
plt.scatter(X[:, 0], X[:, 1], color="green", marker="D", s=30, label="Offsprings")
|
|
38
|
+
|
|
39
|
+
is_new = np.full(len(pop), True)
|
|
40
|
+
if self.last_pop is not None:
|
|
41
|
+
for k, ind in enumerate(pop):
|
|
42
|
+
if ind in self.last_pop:
|
|
43
|
+
is_new[k] = False
|
|
44
|
+
|
|
45
|
+
# plot the new population
|
|
46
|
+
if is_new.sum() > 0:
|
|
47
|
+
X, F, CV = pop[is_new].get("X", "F", "CV")
|
|
48
|
+
plt.scatter(X[:, 0], X[:, 1], color="red", marker="*", s=70, label="Survivors")
|
|
49
|
+
|
|
50
|
+
xl, xu = problem.bounds()
|
|
51
|
+
plt.xlim(xl[0], xu[0])
|
|
52
|
+
plt.ylim(xl[1], xu[1])
|
|
53
|
+
|
|
54
|
+
plt.title(f"Generation: {algorithm.n_gen}")
|
|
55
|
+
plt.legend()
|
|
56
|
+
|
|
57
|
+
# store the current population as the last
|
|
58
|
+
self.last_pop = set(pop)
|
|
59
|
+
|
|
60
|
+
plt.show()
|
|
61
|
+
|
|
62
|
+
return plt.gcf()
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pymoo
|
|
3
|
+
Version: 0.6.1.6
|
|
4
|
+
Summary: Multi-Objective Optimization in Python
|
|
5
|
+
Author-email: Julian Blank <blankjul@outlook.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: homepage, https://pymoo.org
|
|
8
|
+
Keywords: optimization
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/x-rst
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: numpy>=1.19.3
|
|
26
|
+
Requires-Dist: scipy>=1.1
|
|
27
|
+
Requires-Dist: moocore>=0.1.7
|
|
28
|
+
Requires-Dist: autograd>=1.4
|
|
29
|
+
Requires-Dist: cma>=3.2.2
|
|
30
|
+
Requires-Dist: matplotlib>=3
|
|
31
|
+
Requires-Dist: alive_progress
|
|
32
|
+
Requires-Dist: Deprecated
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: numba; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest; extra == "dev"
|
|
36
|
+
Requires-Dist: nbformat; extra == "dev"
|
|
37
|
+
Requires-Dist: jupyter; extra == "dev"
|
|
38
|
+
Requires-Dist: pyrecorder; extra == "dev"
|
|
39
|
+
Requires-Dist: optproblems; extra == "dev"
|
|
40
|
+
Requires-Dist: pandas; extra == "dev"
|
|
41
|
+
Requires-Dist: ipython; extra == "dev"
|
|
42
|
+
Requires-Dist: ipykernel; extra == "dev"
|
|
43
|
+
Provides-Extra: parallelization
|
|
44
|
+
Requires-Dist: joblib; extra == "parallelization"
|
|
45
|
+
Requires-Dist: dask[distributed]; extra == "parallelization"
|
|
46
|
+
Requires-Dist: ray[default]; extra == "parallelization"
|
|
47
|
+
Provides-Extra: others
|
|
48
|
+
Requires-Dist: optuna; extra == "others"
|
|
49
|
+
Provides-Extra: full
|
|
50
|
+
Requires-Dist: numba; extra == "full"
|
|
51
|
+
Requires-Dist: scikit-learn; extra == "full"
|
|
52
|
+
Requires-Dist: pandas; extra == "full"
|
|
53
|
+
Requires-Dist: pymoo[parallelization]; extra == "full"
|
|
54
|
+
Requires-Dist: pymoo[others]; extra == "full"
|
|
55
|
+
Dynamic: license-file
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
.. |python| image:: https://img.shields.io/badge/python-3.10-blue.svg
|
|
60
|
+
:alt: python 3.10
|
|
61
|
+
|
|
62
|
+
.. |license| image:: https://img.shields.io/badge/license-apache-orange.svg
|
|
63
|
+
:alt: license apache
|
|
64
|
+
:target: https://www.apache.org/licenses/LICENSE-2.0
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
.. |logo| image:: https://github.com/anyoptimization/pymoo-data/blob/main/logo.png?raw=true
|
|
68
|
+
:target: https://pymoo.org
|
|
69
|
+
:alt: pymoo
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
.. |animation| image:: https://github.com/anyoptimization/pymoo-data/blob/main/animation.gif?raw=true
|
|
73
|
+
:target: https://pymoo.org
|
|
74
|
+
:alt: pymoo
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
.. _Github: https://github.com/anyoptimization/pymoo
|
|
78
|
+
.. _Documentation: https://www.pymoo.org/
|
|
79
|
+
.. _Paper: https://ieeexplore.ieee.org/document/9078759
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|python| |license|
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|logo|
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
Documentation_ / Paper_ / Installation_ / Usage_ / Citation_ / Contact_
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
pymoo: Multi-objective Optimization in Python
|
|
96
|
+
====================================================================
|
|
97
|
+
|
|
98
|
+
Our open-source framework pymoo offers state of the art single- and multi-objective algorithms and many more features
|
|
99
|
+
related to multi-objective optimization such as visualization and decision making.
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
.. _Installation:
|
|
103
|
+
|
|
104
|
+
Installation
|
|
105
|
+
********************************************************************************
|
|
106
|
+
|
|
107
|
+
First, make sure you have a Python 3 environment installed. We recommend miniconda3 or anaconda3.
|
|
108
|
+
|
|
109
|
+
The official release is always available at PyPi:
|
|
110
|
+
|
|
111
|
+
.. code:: bash
|
|
112
|
+
|
|
113
|
+
pip install -U pymoo
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
For the current developer version:
|
|
117
|
+
|
|
118
|
+
.. code:: bash
|
|
119
|
+
|
|
120
|
+
git clone https://github.com/anyoptimization/pymoo
|
|
121
|
+
cd pymoo
|
|
122
|
+
pip install .
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
Since for speedup, some of the modules are also available compiled, you can double-check
|
|
126
|
+
if the compilation worked. When executing the command, be sure not already being in the local pymoo
|
|
127
|
+
directory because otherwise not the in site-packages installed version will be used.
|
|
128
|
+
|
|
129
|
+
.. code:: bash
|
|
130
|
+
|
|
131
|
+
python -c "from pymoo.functions import is_compiled;print('Compiled Extensions: ', is_compiled())"
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
.. _Usage:
|
|
135
|
+
|
|
136
|
+
Usage
|
|
137
|
+
********************************************************************************
|
|
138
|
+
|
|
139
|
+
We refer here to our documentation for all the details.
|
|
140
|
+
However, for instance, executing NSGA2:
|
|
141
|
+
|
|
142
|
+
.. code:: python
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
from pymoo.algorithms.moo.nsga2 import NSGA2
|
|
146
|
+
from pymoo.problems import get_problem
|
|
147
|
+
from pymoo.optimize import minimize
|
|
148
|
+
from pymoo.visualization.scatter import Scatter
|
|
149
|
+
|
|
150
|
+
problem = get_problem("zdt1")
|
|
151
|
+
|
|
152
|
+
algorithm = NSGA2(pop_size=100)
|
|
153
|
+
|
|
154
|
+
res = minimize(problem,
|
|
155
|
+
algorithm,
|
|
156
|
+
('n_gen', 200),
|
|
157
|
+
seed=1,
|
|
158
|
+
verbose=True)
|
|
159
|
+
|
|
160
|
+
plot = Scatter()
|
|
161
|
+
plot.add(problem.pareto_front(), plot_type="line", color="black", alpha=0.7)
|
|
162
|
+
plot.add(res.F, color="red")
|
|
163
|
+
plot.show()
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
A representative run of NSGA2 looks as follows:
|
|
168
|
+
|
|
169
|
+
|animation|
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
.. _Citation:
|
|
174
|
+
|
|
175
|
+
Citation
|
|
176
|
+
********************************************************************************
|
|
177
|
+
|
|
178
|
+
If you have used our framework for research purposes, you can cite our publication by:
|
|
179
|
+
|
|
180
|
+
| `J. Blank and K. Deb, pymoo: Multi-Objective Optimization in Python, in IEEE Access, vol. 8, pp. 89497-89509, 2020, doi: 10.1109/ACCESS.2020.2990567 <https://ieeexplore.ieee.org/document/9078759>`_
|
|
181
|
+
|
|
|
182
|
+
| BibTex:
|
|
183
|
+
|
|
184
|
+
::
|
|
185
|
+
|
|
186
|
+
@ARTICLE{pymoo,
|
|
187
|
+
author={J. {Blank} and K. {Deb}},
|
|
188
|
+
journal={IEEE Access},
|
|
189
|
+
title={pymoo: Multi-Objective Optimization in Python},
|
|
190
|
+
year={2020},
|
|
191
|
+
volume={8},
|
|
192
|
+
number={},
|
|
193
|
+
pages={89497-89509},
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.. _Contact:
|
|
197
|
+
|
|
198
|
+
Contact
|
|
199
|
+
********************************************************************************
|
|
200
|
+
|
|
201
|
+
Feel free to contact me if you have any questions:
|
|
202
|
+
|
|
203
|
+
| `Julian Blank <http://julianblank.com>`_ (blankjul [at] outlook.com)
|
|
204
|
+
| Michigan State University
|
|
205
|
+
| Computational Optimization and Innovation Laboratory (COIN)
|
|
206
|
+
| East Lansing, MI 48824, USA
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|