pymoo 0.6.1.5.dev0__cp313-cp313-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.
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-darwin.so +0 -0
- pymoo/cython/calc_perpendicular_distance.pyx +67 -0
- pymoo/cython/decomposition.cpython-313-darwin.so +0 -0
- pymoo/cython/decomposition.pyx +165 -0
- pymoo/cython/hv.cpython-313-darwin.so +0 -0
- pymoo/cython/hv.pyx +18 -0
- pymoo/cython/info.cpython-313-darwin.so +0 -0
- pymoo/cython/info.pyx +5 -0
- pymoo/cython/mnn.cpython-313-darwin.so +0 -0
- pymoo/cython/mnn.pyx +273 -0
- pymoo/cython/non_dominated_sorting.cpython-313-darwin.so +0 -0
- pymoo/cython/non_dominated_sorting.pyx +645 -0
- pymoo/cython/pruning_cd.cpython-313-darwin.so +0 -0
- pymoo/cython/pruning_cd.pyx +197 -0
- pymoo/cython/stochastic_ranking.cpython-313-darwin.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,83 @@
|
|
|
1
|
+
import pymoo.gradient.toolbox as anp
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from pymoo.core.problem import Problem
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Truss2D(Problem):
|
|
8
|
+
|
|
9
|
+
def __init__(self):
|
|
10
|
+
super().__init__(n_var=3, n_obj=2, n_ieq_constr=1, vtype=float)
|
|
11
|
+
|
|
12
|
+
self.Amax = 0.01
|
|
13
|
+
self.Smax = 1e5
|
|
14
|
+
|
|
15
|
+
self.xl = np.array([0.0, 0.0, 1.0])
|
|
16
|
+
self.xu = np.array([self.Amax, self.Amax, 3.0])
|
|
17
|
+
|
|
18
|
+
def _evaluate(self, x, out, *args, **kwargs):
|
|
19
|
+
|
|
20
|
+
# variable names for convenient access
|
|
21
|
+
x1 = x[:, 0]
|
|
22
|
+
x2 = x[:, 1]
|
|
23
|
+
y = x[:, 2]
|
|
24
|
+
|
|
25
|
+
# first objectives
|
|
26
|
+
f1 = x1 * anp.sqrt(16 + anp.square(y)) + x2 * anp.sqrt((1 + anp.square(y)))
|
|
27
|
+
|
|
28
|
+
# measure which are needed for the second objective
|
|
29
|
+
sigma_ac = 20 * anp.sqrt(16 + anp.square(y)) / (y * x1)
|
|
30
|
+
sigma_bc = 80 * anp.sqrt(1 + anp.square(y)) / (y * x2)
|
|
31
|
+
|
|
32
|
+
# take the max
|
|
33
|
+
f2 = anp.max(anp.column_stack((sigma_ac, sigma_bc)), axis=1)
|
|
34
|
+
|
|
35
|
+
# define a constraint
|
|
36
|
+
g1 = f2 - self.Smax
|
|
37
|
+
|
|
38
|
+
out["F"] = anp.column_stack([f1, f2])
|
|
39
|
+
out["G"] = g1
|
|
40
|
+
|
|
41
|
+
def _calc_pareto_front(self, *args, **kwargs):
|
|
42
|
+
|
|
43
|
+
T = 2 * np.sqrt(5) * self.Amax
|
|
44
|
+
|
|
45
|
+
# Part A - before transition point T
|
|
46
|
+
|
|
47
|
+
f1 = np.linspace(400 / self.Smax, T, 1000)
|
|
48
|
+
f2 = 400 / f1
|
|
49
|
+
part_a = np.column_stack([f1, f2])
|
|
50
|
+
|
|
51
|
+
# Part B - after transition point T
|
|
52
|
+
|
|
53
|
+
def calc_y(V):
|
|
54
|
+
return np.sqrt(3200 * V**2 + 40 * V * np.sqrt(6400 * V**2 - 12) - 4)
|
|
55
|
+
|
|
56
|
+
def calc_SV(y):
|
|
57
|
+
return (4 + y**2) / (0.01 * y)
|
|
58
|
+
|
|
59
|
+
def calc_x1(y):
|
|
60
|
+
return 0.0025 * np.sqrt((16 + y**2) / (1 + y**2))
|
|
61
|
+
|
|
62
|
+
def calc_S(V):
|
|
63
|
+
y = calc_y(V)
|
|
64
|
+
SV = calc_SV(y)
|
|
65
|
+
S = SV / V
|
|
66
|
+
return S
|
|
67
|
+
|
|
68
|
+
y = 3
|
|
69
|
+
x1 = calc_x1(y)
|
|
70
|
+
x2 = 0.01
|
|
71
|
+
|
|
72
|
+
V_min = T
|
|
73
|
+
V_max = self.evaluate(np.array([x1, x2, y]), return_values_of=["F"])[0]
|
|
74
|
+
|
|
75
|
+
f1 = np.linspace(V_min, V_max, 100)
|
|
76
|
+
f2 = calc_S(f1)
|
|
77
|
+
part_b = np.column_stack([f1, f2])
|
|
78
|
+
|
|
79
|
+
pf = np.row_stack([part_a, part_b])
|
|
80
|
+
|
|
81
|
+
return pf
|
|
82
|
+
|
|
83
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import pymoo.gradient.toolbox as anp
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from pymoo.core.problem import Problem
|
|
5
|
+
from pymoo.util.remote import Remote
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class WeldedBeam(Problem):
|
|
9
|
+
def __init__(self):
|
|
10
|
+
super().__init__(n_var=4, n_obj=2, n_ieq_constr=4, vtype=float)
|
|
11
|
+
self.xl = np.array([0.125, 0.1, 0.1, 0.125])
|
|
12
|
+
self.xu = np.array([5.0, 10.0, 10.0, 5.0])
|
|
13
|
+
|
|
14
|
+
def _evaluate(self, x, out, *args, **kwargs):
|
|
15
|
+
f1 = 1.10471 * x[:, 0] ** 2 * x[:, 1] + 0.04811 * x[:, 2] * x[:, 3] * (14.0 + x[:, 1])
|
|
16
|
+
f2 = 2.1952 / (x[:, 3] * x[:, 2] ** 3)
|
|
17
|
+
|
|
18
|
+
P = 6000
|
|
19
|
+
L = 14
|
|
20
|
+
t_max = 13600
|
|
21
|
+
s_max = 30000
|
|
22
|
+
|
|
23
|
+
R = anp.sqrt(0.25 * (x[:, 1] ** 2 + (x[:, 0] + x[:, 2]) ** 2))
|
|
24
|
+
M = P * (L + x[:, 1] / 2)
|
|
25
|
+
J = 2 * anp.sqrt(0.5) * x[:, 0] * x[:, 1] * (x[:, 1] ** 2 / 12 + 0.25 * (x[:, 0] + x[:, 2]) ** 2)
|
|
26
|
+
t1 = P / (anp.sqrt(2) * x[:, 0] * x[:, 1])
|
|
27
|
+
t2 = M * R / J
|
|
28
|
+
t = anp.sqrt(t1 ** 2 + t2 ** 2 + t1 * t2 * x[:, 1] / R)
|
|
29
|
+
s = 6 * P * L / (x[:, 3] * x[:, 2] ** 2)
|
|
30
|
+
P_c = 64746.022 * (1 - 0.0282346 * x[:, 2]) * x[:, 2] * x[:, 3] ** 3
|
|
31
|
+
|
|
32
|
+
g1 = (1 / t_max) * (t - t_max)
|
|
33
|
+
g2 = (1 / s_max) * (s - s_max)
|
|
34
|
+
g3 = (1 / (5 - 0.125)) * (x[:, 0] - x[:, 3])
|
|
35
|
+
g4 = (1 / P) * (P - P_c)
|
|
36
|
+
|
|
37
|
+
out["F"] = anp.column_stack([f1, f2])
|
|
38
|
+
out["G"] = anp.column_stack([g1, g2, g3, g4])
|
|
39
|
+
|
|
40
|
+
def _calc_pareto_front(self):
|
|
41
|
+
return Remote.get_instance().load("pymoo", "pf", "welded_beam.pf")
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import pymoo.gradient.toolbox as anp
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from pymoo.core.problem import Problem
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class WRM(Problem):
|
|
8
|
+
|
|
9
|
+
def __init__(self):
|
|
10
|
+
xl = np.array([0.01, 0.01, 0.01])
|
|
11
|
+
xu = np.array([0.45, 0.10, 0.10])
|
|
12
|
+
super().__init__(n_var=3, n_obj=5, n_ieq_constr=7, xl=xl, xu=xu, vtype=float)
|
|
13
|
+
|
|
14
|
+
def _evaluate(self, x, out, *args, **kwargs):
|
|
15
|
+
|
|
16
|
+
# the definition is index 1 based -> simply add a dummy var in the beginning
|
|
17
|
+
x = anp.column_stack([anp.zeros((len(x), 1)), x])
|
|
18
|
+
|
|
19
|
+
f1 = 106780.37 * (x[:, 2] + x[:, 3]) + 61704.67
|
|
20
|
+
f2 = 3000 * x[:, 1]
|
|
21
|
+
f3 = 305700 * 2289 * x[:, 2] / (0.06 * 2289) ** 0.65
|
|
22
|
+
f4 = 250 * 2289 * anp.exp(-39.75 * x[:, 2] + 9.9 * x[:, 3] + 2.74)
|
|
23
|
+
f5 = 25 * (1.39 / (x[:, 1] * x[:, 2]) + 4940 * x[:, 3] - 80)
|
|
24
|
+
|
|
25
|
+
deno = 1. / (x[:, 1] * x[:, 2])
|
|
26
|
+
|
|
27
|
+
g1 = -(1.0 - (0.00139 * deno + 4.94 * x[:, 3] - 0.08))
|
|
28
|
+
g2 = -(1.0 - (0.000306 * deno + 1.082 * x[:, 3] - 0.0986))
|
|
29
|
+
g3 = -(50000 - (12.307 * deno + 49408.24 * x[:, 3] + 4051.02))
|
|
30
|
+
g4 = -(16000 - (2.098 * deno + 8046.33 * x[:, 3] - 696.71))
|
|
31
|
+
g5 = -(10000 - (2.138 * deno + 7883.39 * x[:, 3] - 705.04))
|
|
32
|
+
g6 = -(2000 - (0.417 * deno + 1721.26 * x[:, 3] - 136.54))
|
|
33
|
+
g7 = -(550 - (0.164 * deno + 631.13 * x[:, 3] - 54.58))
|
|
34
|
+
|
|
35
|
+
out["F"] = anp.column_stack([f1, f2, f3, f4, f5])
|
|
36
|
+
out["G"] = anp.column_stack([g1, g2, g3, g4, g5, g6, g7])
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
import pymoo.gradient.toolbox as anp
|
|
5
|
+
from pymoo.core.problem import Problem
|
|
6
|
+
from pymoo.util.normalization import normalize
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ZDT(Problem):
|
|
10
|
+
|
|
11
|
+
def __init__(self, n_var=30, **kwargs):
|
|
12
|
+
super().__init__(n_var=n_var, n_obj=2, xl=0, xu=1, vtype=float, **kwargs)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ZDT1(ZDT):
|
|
16
|
+
|
|
17
|
+
def _calc_pareto_front(self, n_pareto_points=100):
|
|
18
|
+
x = np.linspace(0, 1, n_pareto_points)
|
|
19
|
+
return np.array([x, 1 - np.sqrt(x)]).T
|
|
20
|
+
|
|
21
|
+
def _evaluate(self, x, out, *args, **kwargs):
|
|
22
|
+
f1 = x[:, 0]
|
|
23
|
+
g = 1 + 9.0 / (self.n_var - 1) * anp.sum(x[:, 1:], axis=1)
|
|
24
|
+
f2 = g * (1 - anp.power((f1 / g), 0.5))
|
|
25
|
+
|
|
26
|
+
out["F"] = anp.column_stack([f1, f2])
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ZDT2(ZDT):
|
|
30
|
+
|
|
31
|
+
def _calc_pareto_front(self, n_pareto_points=100):
|
|
32
|
+
x = np.linspace(0, 1, n_pareto_points)
|
|
33
|
+
return np.array([x, 1 - np.power(x, 2)]).T
|
|
34
|
+
|
|
35
|
+
def _evaluate(self, x, out, *args, **kwargs):
|
|
36
|
+
f1 = x[:, 0]
|
|
37
|
+
c = anp.sum(x[:, 1:], axis=1)
|
|
38
|
+
g = 1.0 + 9.0 * c / (self.n_var - 1)
|
|
39
|
+
f2 = g * (1 - anp.power((f1 * 1.0 / g), 2))
|
|
40
|
+
|
|
41
|
+
out["F"] = anp.column_stack([f1, f2])
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ZDT3(ZDT):
|
|
45
|
+
|
|
46
|
+
def _calc_pareto_front(self, n_points=100, flatten=True):
|
|
47
|
+
regions = [[0, 0.0830015349],
|
|
48
|
+
[0.182228780, 0.2577623634],
|
|
49
|
+
[0.4093136748, 0.4538821041],
|
|
50
|
+
[0.6183967944, 0.6525117038],
|
|
51
|
+
[0.8233317983, 0.8518328654]]
|
|
52
|
+
|
|
53
|
+
pf = []
|
|
54
|
+
|
|
55
|
+
for r in regions:
|
|
56
|
+
x1 = np.linspace(r[0], r[1], int(n_points / len(regions)))
|
|
57
|
+
x2 = 1 - np.sqrt(x1) - x1 * np.sin(10 * np.pi * x1)
|
|
58
|
+
pf.append(np.array([x1, x2]).T)
|
|
59
|
+
|
|
60
|
+
if not flatten:
|
|
61
|
+
pf = np.concatenate([pf[None,...] for pf in pf])
|
|
62
|
+
else:
|
|
63
|
+
pf = np.row_stack(pf)
|
|
64
|
+
|
|
65
|
+
return pf
|
|
66
|
+
|
|
67
|
+
def _evaluate(self, x, out, *args, **kwargs):
|
|
68
|
+
f1 = x[:, 0]
|
|
69
|
+
c = anp.sum(x[:, 1:], axis=1)
|
|
70
|
+
g = 1.0 + 9.0 * c / (self.n_var - 1)
|
|
71
|
+
f2 = g * (1 - anp.power(f1 * 1.0 / g, 0.5) - (f1 * 1.0 / g) * anp.sin(10 * anp.pi * f1))
|
|
72
|
+
|
|
73
|
+
out["F"] = anp.column_stack([f1, f2])
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class ZDT4(ZDT):
|
|
77
|
+
def __init__(self, n_var=10):
|
|
78
|
+
super().__init__(n_var)
|
|
79
|
+
self.xl = -5 * np.ones(self.n_var)
|
|
80
|
+
self.xl[0] = 0.0
|
|
81
|
+
self.xu = 5 * np.ones(self.n_var)
|
|
82
|
+
self.xu[0] = 1.0
|
|
83
|
+
self.func = self._evaluate
|
|
84
|
+
|
|
85
|
+
def _calc_pareto_front(self, n_pareto_points=100):
|
|
86
|
+
x = np.linspace(0, 1, n_pareto_points)
|
|
87
|
+
return np.array([x, 1 - np.sqrt(x)]).T
|
|
88
|
+
|
|
89
|
+
def _evaluate(self, x, out, *args, **kwargs):
|
|
90
|
+
f1 = x[:, 0]
|
|
91
|
+
g = 1.0
|
|
92
|
+
g += 10 * (self.n_var - 1)
|
|
93
|
+
for i in range(1, self.n_var):
|
|
94
|
+
g += x[:, i] * x[:, i] - 10.0 * anp.cos(4.0 * anp.pi * x[:, i])
|
|
95
|
+
h = 1.0 - anp.sqrt(f1 / g)
|
|
96
|
+
f2 = g * h
|
|
97
|
+
|
|
98
|
+
out["F"] = anp.column_stack([f1, f2])
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class ZDT5(ZDT):
|
|
102
|
+
|
|
103
|
+
def __init__(self, m=11, n=5, normalize=True, **kwargs):
|
|
104
|
+
self.m = m
|
|
105
|
+
self.n = n
|
|
106
|
+
self.normalize = normalize
|
|
107
|
+
super().__init__(n_var=(30 + n * (m - 1)), **kwargs)
|
|
108
|
+
|
|
109
|
+
def _calc_pareto_front(self, n_pareto_points=100):
|
|
110
|
+
x = 1 + np.linspace(0, 1, n_pareto_points) * 30
|
|
111
|
+
pf = np.column_stack([x, (self.m-1) / x])
|
|
112
|
+
if self.normalize:
|
|
113
|
+
pf = normalize(pf)
|
|
114
|
+
return pf
|
|
115
|
+
|
|
116
|
+
def _evaluate(self, x, out, *args, **kwargs):
|
|
117
|
+
x = x.astype(float)
|
|
118
|
+
|
|
119
|
+
_x = [x[:, :30]]
|
|
120
|
+
for i in range(self.m - 1):
|
|
121
|
+
_x.append(x[:, 30 + i * self.n: 30 + (i + 1) * self.n])
|
|
122
|
+
|
|
123
|
+
u = anp.column_stack([x_i.sum(axis=1) for x_i in _x])
|
|
124
|
+
v = (2 + u) * (u < self.n) + 1 * (u == self.n)
|
|
125
|
+
g = v[:, 1:].sum(axis=1)
|
|
126
|
+
|
|
127
|
+
f1 = 1 + u[:, 0]
|
|
128
|
+
f2 = g * (1 / f1)
|
|
129
|
+
|
|
130
|
+
if self.normalize:
|
|
131
|
+
f1 = normalize(f1, 1, 31)
|
|
132
|
+
f2 = normalize(f2, (self.m-1) * 1/31, (self.m-1))
|
|
133
|
+
|
|
134
|
+
out["F"] = anp.column_stack([f1, f2])
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class ZDT6(ZDT):
|
|
138
|
+
|
|
139
|
+
def __init__(self, n_var=10, **kwargs):
|
|
140
|
+
super().__init__(n_var=n_var, **kwargs)
|
|
141
|
+
|
|
142
|
+
def _calc_pareto_front(self, n_pareto_points=100):
|
|
143
|
+
x = np.linspace(0.2807753191, 1, n_pareto_points)
|
|
144
|
+
return np.array([x, 1 - np.power(x, 2)]).T
|
|
145
|
+
|
|
146
|
+
def _evaluate(self, x, out, *args, **kwargs):
|
|
147
|
+
f1 = 1 - anp.exp(-4 * x[:, 0]) * anp.power(anp.sin(6 * anp.pi * x[:, 0]), 6)
|
|
148
|
+
g = 1 + 9.0 * anp.power(anp.sum(x[:, 1:], axis=1) / (self.n_var - 1.0), 0.25)
|
|
149
|
+
f2 = g * (1 - anp.power(f1 / g, 2))
|
|
150
|
+
|
|
151
|
+
out["F"] = anp.column_stack([f1, f2])
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from pymoo.core.meta import Meta
|
|
2
|
+
from pymoo.core.problem import Problem
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class MultiToSingleObjective(Meta, Problem):
|
|
6
|
+
|
|
7
|
+
def __init__(self, problem, decomposition, kwargs=None):
|
|
8
|
+
super().__init__(problem)
|
|
9
|
+
self.decomposition = decomposition
|
|
10
|
+
self.kwargs = kwargs if not None else dict()
|
|
11
|
+
self.n_obj = 1
|
|
12
|
+
|
|
13
|
+
def do(self, X, return_values_of, *args, **kwargs):
|
|
14
|
+
out = self.__object__.do(X, return_values_of, *args, **kwargs)
|
|
15
|
+
F = out["F"]
|
|
16
|
+
out["__F__"] = F
|
|
17
|
+
out["F"] = self.decomposition.do(F, **self.kwargs)[:, None]
|
|
18
|
+
return out
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from pymoo.problems.single.ackley import *
|
|
2
|
+
from pymoo.problems.single.cantilevered_beam import *
|
|
3
|
+
from pymoo.problems.single.griewank import *
|
|
4
|
+
from pymoo.problems.single.knapsack import *
|
|
5
|
+
from pymoo.problems.single.pressure_vessel import *
|
|
6
|
+
from pymoo.problems.single.rastrigin import *
|
|
7
|
+
from pymoo.problems.single.rosenbrock import *
|
|
8
|
+
from pymoo.problems.single.schwefel import *
|
|
9
|
+
from pymoo.problems.single.sphere import *
|
|
10
|
+
from pymoo.problems.single.zakharov import *
|
|
11
|
+
from pymoo.problems.single.g import *
|
|
12
|
+
from pymoo.problems.single.himmelblau import *
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pymoo.gradient.toolbox as anp
|
|
3
|
+
|
|
4
|
+
from pymoo.core.problem import Problem
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Ackley(Problem):
|
|
8
|
+
|
|
9
|
+
def __init__(self, n_var=2, a=20, b=1/5, c=2 * np.pi):
|
|
10
|
+
super().__init__(n_var=n_var, n_obj=1, xl=-32.768, xu=+32.768, vtype=float)
|
|
11
|
+
self.a = a
|
|
12
|
+
self.b = b
|
|
13
|
+
self.c = c
|
|
14
|
+
|
|
15
|
+
def _evaluate(self, x, out, *args, **kwargs):
|
|
16
|
+
part1 = -1. * self.a * anp.exp(-1. * self.b * anp.sqrt((1. / self.n_var) * anp.sum(x * x, axis=1)))
|
|
17
|
+
part2 = -1. * anp.exp((1. / self.n_var) * anp.sum(anp.cos(self.c * x), axis=1))
|
|
18
|
+
out["F"] = part1 + part2 + self.a + anp.exp(1)
|
|
19
|
+
|
|
20
|
+
def _calc_pareto_front(self):
|
|
21
|
+
return 0
|
|
22
|
+
|
|
23
|
+
def _calc_pareto_set(self):
|
|
24
|
+
return np.full(self.n_var, 0)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import pymoo.gradient.toolbox as anp
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from pymoo.core.problem import Problem
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CantileveredBeam(Problem):
|
|
8
|
+
|
|
9
|
+
def __init__(self):
|
|
10
|
+
super().__init__(n_var=4, n_obj=1, n_ieq_constr=2, vtype=float)
|
|
11
|
+
self.xl = np.array([2, 0.1, 0.1, 3.0])
|
|
12
|
+
self.xu = np.array([12.0, 1.0, 2.0, 7.0])
|
|
13
|
+
self.h1 = np.array([0.1, 0.25, 0.35, 0.5, 0.65, 0.75, 0.9, 1.0])
|
|
14
|
+
|
|
15
|
+
def _evaluate(self, x, out, *args, **kwargs):
|
|
16
|
+
E, L, P = 1e7, 36.0, 1000.0
|
|
17
|
+
|
|
18
|
+
b1, h1, b2, H = x[:, 0], x[:, 1], x[:, 2], x[:, 3]
|
|
19
|
+
I = 1 / 12 * b2 * (H - 2 * h1) ** 3 + 2 * (1 / 12 * b1 * h1 ** 3 + b1 * h1 * (H - h1) ** 2 / 4)
|
|
20
|
+
volume = (2 * h1 * b1 + (H - 2 * h1) * b2) * L
|
|
21
|
+
out["F"] = volume
|
|
22
|
+
|
|
23
|
+
sigma = P * L * H / (2 * I)
|
|
24
|
+
delta = P * L ** 3 / (3 * E * I)
|
|
25
|
+
|
|
26
|
+
g1 = (sigma - 5000.0) / 5000.0
|
|
27
|
+
g2 = (delta - 0.1) / 0.1
|
|
28
|
+
out["G"] = anp.column_stack([g1, g2])
|
|
29
|
+
|
|
30
|
+
def _calc_pareto_front(self):
|
|
31
|
+
return 92.7693
|
|
32
|
+
|
|
33
|
+
def _calc_pareto_set(self):
|
|
34
|
+
return [9.4846, 0.1000, 0.1000, 7.0000]
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from pymoo.core.problem import ElementwiseProblem
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class FlowshopScheduling(ElementwiseProblem):
|
|
8
|
+
|
|
9
|
+
def __init__(self, processing_times, **kwargs):
|
|
10
|
+
"""
|
|
11
|
+
Flowshop scheduling problem.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
processing_times : numpy.array
|
|
16
|
+
Matrix where processing_time[i][j] is the processing time for job j on machine i.
|
|
17
|
+
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
n_machines, n_jobs = processing_times.shape
|
|
21
|
+
self.records = processing_times
|
|
22
|
+
|
|
23
|
+
super(FlowshopScheduling, self).__init__(
|
|
24
|
+
n_var=n_jobs,
|
|
25
|
+
n_obj=1,
|
|
26
|
+
xl=0,
|
|
27
|
+
xu=n_machines,
|
|
28
|
+
vtype=int,
|
|
29
|
+
**kwargs
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def _evaluate(self, x, out, *args, **kwargs):
|
|
33
|
+
out["F"] = self.makespan(x)
|
|
34
|
+
|
|
35
|
+
def makespan(self, x):
|
|
36
|
+
machine_times = self.get_machine_times(x)
|
|
37
|
+
# The makespan is the difference between the starting time of the first job and the latest finish time of any
|
|
38
|
+
# job. Minimizing the makespan amounts to minimizing the total time it takes to process all jobs from start
|
|
39
|
+
# to finish.
|
|
40
|
+
makespan = machine_times[-1][-1] + self.records[-1][x[-1]] # finish time of the last job
|
|
41
|
+
return makespan
|
|
42
|
+
|
|
43
|
+
def get_machine_times(self, x):
|
|
44
|
+
n_machines, n_jobs = self.records.shape
|
|
45
|
+
|
|
46
|
+
# A 2d array to store the starting time for each job on each machine
|
|
47
|
+
# machine_times[i][j] --> starting time for the j-th job on machine i
|
|
48
|
+
machine_times = [[] for _ in range(n_machines)]
|
|
49
|
+
|
|
50
|
+
# Assign the initial job to the machines
|
|
51
|
+
machine_times[0].append(0)
|
|
52
|
+
for i in range(1, n_machines):
|
|
53
|
+
# Start the next job when the previous one is finished
|
|
54
|
+
machine_times[i].append(
|
|
55
|
+
machine_times[i - 1][0] + self.records[i - 1][x[0]]
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Assign the remaining jobs
|
|
59
|
+
for j in range(1, n_jobs):
|
|
60
|
+
# For the first machine, we can put a job when the previous one is finished
|
|
61
|
+
machine_times[0].append(
|
|
62
|
+
machine_times[0][j - 1] + self.records[0][x[j - 1]]
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# For the remaining machines, the starting time of the current job j is the max of the following two times:
|
|
66
|
+
# 1. The finish time of the previous job on the current machine
|
|
67
|
+
# 2. The finish time of the current job on the previous machine
|
|
68
|
+
for i in range(1, n_machines):
|
|
69
|
+
machine_times[i].append(
|
|
70
|
+
max(
|
|
71
|
+
machine_times[i][j - 1] + self.records[i][x[j - 1]], # 1
|
|
72
|
+
machine_times[i - 1][j] + self.records[i - 1][x[j]] # 2
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
return machine_times
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def create_random_flowshop_problem(n_machines, n_jobs, seed=None):
|
|
79
|
+
if seed is not None:
|
|
80
|
+
np.random.seed(seed)
|
|
81
|
+
T = np.random.random((n_machines, n_jobs)) * 50 + 50
|
|
82
|
+
return FlowshopScheduling(T)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def visualize(problem, x, path=None, label=True):
|
|
86
|
+
with plt.style.context('ggplot'):
|
|
87
|
+
n_machines, n_jobs = problem.records.shape
|
|
88
|
+
machine_times = problem.get_machine_times(x)
|
|
89
|
+
|
|
90
|
+
fig = plt.figure()
|
|
91
|
+
ax = fig.add_subplot(111)
|
|
92
|
+
|
|
93
|
+
Y = np.flip(np.arange(n_machines))
|
|
94
|
+
|
|
95
|
+
for i in range(n_machines):
|
|
96
|
+
for j in range(n_jobs):
|
|
97
|
+
width = problem.records[i][x[j]]
|
|
98
|
+
left = machine_times[i][j]
|
|
99
|
+
ax.barh(Y[i], width, left=left,
|
|
100
|
+
align='center', color='gray',
|
|
101
|
+
edgecolor='black', linewidth=0.8
|
|
102
|
+
)
|
|
103
|
+
if label:
|
|
104
|
+
ax.text((left + width / 2), Y[i], str(x[j] + 1), ha='center', va='center', color='white',
|
|
105
|
+
fontsize=15)
|
|
106
|
+
ax.set_xlabel("Time")
|
|
107
|
+
ax.set_yticks(np.arange(n_machines))
|
|
108
|
+
ax.set_yticklabels(["M%d" % (i + 1) for i in Y])
|
|
109
|
+
ax.set_title("Makespan: %s" % np.round(problem.makespan(x), 3))
|
|
110
|
+
if path is not None:
|
|
111
|
+
plt.savefig(path)
|
|
112
|
+
plt.show()
|