Repair OperatorΒΆ
A simple approach is to handle constraints through a repair function. This is only possible if the equation of the constraint is known. The repair makes sure every solution that is evaluated is, in fact, feasible. Let us consider the equality constraint example.
Let us define a Repair
operator that always satisfies the equality constraint (the inequality constraint is simply ignored and will be figured out by the algorithm)
[2]:
from pymoo.core.repair import Repair
class MyRepair(Repair):
def _do(self, problem, X, **kwargs):
X[:, 0] = 1/3 * X[:, 1]
return X
Now the algorithm object needs to be initialized with the Repair
operator and then can be run to solve the problem:
[3]:
from pymoo.algorithms.soo.nonconvex.ga import GA
from pymoo.optimize import minimize
algorithm = GA(repair=MyRepair())
res = minimize(ConstrainedProblemWithEquality(),
algorithm,
('n_gen', 20),
seed=1,
verbose=True)
print("Best solution found: \nX = %s\nF = %s\nCV = %s" % (res.X, res.F, res.CV))
=================================================================================
n_gen | n_eval | cv_min | cv_avg | f_avg | f_min
=================================================================================
1 | 100 | 0.000000E+00 | 0.3516478340 | 1.1816456287 | 1.0001924199
2 | 200 | 0.000000E+00 | 0.0192240408 | 1.1532524043 | 1.0001924199
3 | 300 | 0.000000E+00 | 0.000000E+00 | 1.1005567442 | 1.0001924199
4 | 400 | 0.000000E+00 | 0.000000E+00 | 1.0423303243 | 1.0001732916
5 | 500 | 0.000000E+00 | 0.000000E+00 | 1.0214569210 | 1.0001143855
6 | 600 | 0.000000E+00 | 0.000000E+00 | 1.0112639832 | 1.0001143855
7 | 700 | 0.000000E+00 | 0.000000E+00 | 1.0063985649 | 1.0000835458
8 | 800 | 0.000000E+00 | 0.000000E+00 | 1.0042655553 | 1.0000835458
9 | 900 | 0.000000E+00 | 0.000000E+00 | 1.0029222610 | 1.0000804747
10 | 1000 | 0.000000E+00 | 0.000000E+00 | 1.0017479510 | 1.0000540459
11 | 1100 | 0.000000E+00 | 0.000000E+00 | 1.0008203740 | 1.0000448415
12 | 1200 | 0.000000E+00 | 0.000000E+00 | 1.0001879254 | 1.0000426034
13 | 1300 | 0.000000E+00 | 0.000000E+00 | 1.0001294281 | 1.0000414669
14 | 1400 | 0.000000E+00 | 0.000000E+00 | 1.0001048756 | 1.0000414669
15 | 1500 | 0.000000E+00 | 0.000000E+00 | 1.0000798570 | 1.0000414669
16 | 1600 | 0.000000E+00 | 0.000000E+00 | 1.0000641902 | 1.0000400124
17 | 1700 | 0.000000E+00 | 0.000000E+00 | 1.0000536662 | 1.0000400124
18 | 1800 | 0.000000E+00 | 0.000000E+00 | 1.0000493836 | 1.0000398293
19 | 1900 | 0.000000E+00 | 0.000000E+00 | 1.0000461424 | 1.0000395511
20 | 2000 | 0.000000E+00 | 0.000000E+00 | 1.0000436532 | 1.0000395511
Best solution found:
X = [0.25000989 0.75002966]
F = [1.00003955]
CV = [0.]
If you would like to compare the solution without a repair you will see how searching only in the feasible space helps:
[4]:
from pymoo.algorithms.soo.nonconvex.ga import GA
from pymoo.optimize import minimize
algorithm = GA()
res = minimize(ConstrainedProblemWithEquality(),
algorithm,
('n_gen', 20),
seed=1,
verbose=True)
print("Best solution found: \nX = %s\nF = %s\nCV = %s" % (res.X, res.F, res.CV))
=================================================================================
n_gen | n_eval | cv_min | cv_avg | f_avg | f_min
=================================================================================
1 | 100 | 0.0168997810 | 1.1966219666 | - | -
2 | 200 | 0.0082848537 | 0.5046020034 | - | -
3 | 300 | 0.0029693797 | 0.1776405901 | - | -
4 | 400 | 0.0009258613 | 0.0596529505 | - | -
5 | 500 | 0.0005056684 | 0.0288759017 | - | -
6 | 600 | 0.0003567486 | 0.0169237558 | - | -
7 | 700 | 0.0003567486 | 0.0121468316 | - | -
8 | 800 | 0.0003567486 | 0.0085924525 | - | -
9 | 900 | 0.0002721305 | 0.0056338874 | - | -
10 | 1000 | 0.0002721305 | 0.0038791059 | - | -
11 | 1100 | 0.0002721305 | 0.0022950025 | - | -
12 | 1200 | 0.0002721305 | 0.0017183819 | - | -
13 | 1300 | 0.0000264663 | 0.0013707858 | - | -
14 | 1400 | 0.000000E+00 | 0.0012435913 | 1.3318479164 | 1.3318479164
15 | 1500 | 0.000000E+00 | 0.0009793862 | 1.3318479164 | 1.3318479164
16 | 1600 | 0.000000E+00 | 0.0007594017 | 1.3318479164 | 1.3318479164
17 | 1700 | 0.000000E+00 | 0.0006334001 | 1.3301094441 | 1.3266896822
18 | 1800 | 0.000000E+00 | 0.0005198833 | 1.3305265785 | 1.3266896822
19 | 1900 | 0.000000E+00 | 0.0003956834 | 1.2728496075 | 1.0421417236
20 | 2000 | 0.000000E+00 | 0.0002388947 | 1.3017516728 | 1.0421417236
Best solution found:
X = [0.26055515 0.78158657]
F = [1.04214172]
CV = [0.]