[1]:
%%capture
%run ./index.ipynb
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.3621675497 | 1.1485625824 | 1.0040402769
2 | 200 | 0.000000E+00 | 0.0158069271 | 1.1498265069 | 1.0040402769
3 | 300 | 0.000000E+00 | 0.000000E+00 | 1.0718734487 | 1.0037909824
4 | 400 | 0.000000E+00 | 0.000000E+00 | 1.0264063007 | 1.0005680041
5 | 500 | 0.000000E+00 | 0.000000E+00 | 1.0135248142 | 1.0005680041
6 | 600 | 0.000000E+00 | 0.000000E+00 | 1.0079679473 | 1.0004249358
7 | 700 | 0.000000E+00 | 0.000000E+00 | 1.0041360700 | 1.0003566881
8 | 800 | 0.000000E+00 | 0.000000E+00 | 1.0030012306 | 1.0002548659
9 | 900 | 0.000000E+00 | 0.000000E+00 | 1.0021661237 | 1.0002548659
10 | 1000 | 0.000000E+00 | 0.000000E+00 | 1.0013170367 | 1.0002548659
11 | 1100 | 0.000000E+00 | 0.000000E+00 | 1.0007981978 | 1.0002548659
12 | 1200 | 0.000000E+00 | 0.000000E+00 | 1.0005585282 | 1.0002322437
13 | 1300 | 0.000000E+00 | 0.000000E+00 | 1.0004702926 | 1.0002322437
14 | 1400 | 0.000000E+00 | 0.000000E+00 | 1.0004153861 | 1.0002101821
15 | 1500 | 0.000000E+00 | 0.000000E+00 | 1.0003517422 | 1.0002101821
16 | 1600 | 0.000000E+00 | 0.000000E+00 | 1.0003141463 | 1.0002100191
17 | 1700 | 0.000000E+00 | 0.000000E+00 | 1.0002773131 | 1.0001809339
18 | 1800 | 0.000000E+00 | 0.000000E+00 | 1.0002411187 | 1.0001788899
19 | 1900 | 0.000000E+00 | 0.000000E+00 | 1.0002244580 | 1.0001788899
20 | 2000 | 0.000000E+00 | 0.000000E+00 | 1.0002157044 | 1.0001747918
Best solution found:
X = [0.2500437 0.75013109]
F = [1.00017479]
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.0101808244 | 1.2505054323 | - | -
2 | 200 | 0.0088255124 | 0.4965367190 | - | -
3 | 300 | 0.0030724079 | 0.2476582052 | - | -
4 | 400 | 0.0016607398 | 0.1208656844 | - | -
5 | 500 | 0.0001622390 | 0.0598781939 | - | -
6 | 600 | 0.0001622390 | 0.0259155713 | - | -
7 | 700 | 0.0001622390 | 0.0174156380 | - | -
8 | 800 | 0.0001622390 | 0.0112338474 | - | -
9 | 900 | 0.0001571776 | 0.0071670057 | - | -
10 | 1000 | 0.0001314248 | 0.0052259997 | - | -
11 | 1100 | 0.0001314248 | 0.0041169119 | - | -
12 | 1200 | 0.0001314248 | 0.0034804459 | - | -
13 | 1300 | 1.823665E-07 | 0.0027195562 | - | -
14 | 1400 | 0.000000E+00 | 0.0022023378 | 1.2884812540 | 1.2524952187
15 | 1500 | 0.000000E+00 | 0.0018922102 | 1.2884812540 | 1.2524952187
16 | 1600 | 0.000000E+00 | 0.0015428272 | 1.2884812540 | 1.2524952187
17 | 1700 | 0.000000E+00 | 0.0011870588 | 1.2884812540 | 1.2524952187
18 | 1800 | 0.000000E+00 | 0.0010150449 | 1.2977760558 | 1.2524952187
19 | 1900 | 0.000000E+00 | 0.0009024870 | 1.3043750371 | 1.2524952187
20 | 2000 | 0.000000E+00 | 0.0007492699 | 1.3113910652 | 1.2524952187
Best solution found:
X = [0.31314134 0.93935388]
F = [1.25249522]
CV = [0.]