[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.3516478340 | 1.1816456287 | 1.0001924199
2 | 200 | 0.000000E+00 | 0.0190154493 | 1.1582876952 | 1.0001924199
3 | 300 | 0.000000E+00 | 0.000000E+00 | 1.1007694294 | 1.0001924199
4 | 400 | 0.000000E+00 | 0.000000E+00 | 1.0455278980 | 1.0000751839
5 | 500 | 0.000000E+00 | 0.000000E+00 | 1.0240097894 | 1.0000751839
6 | 600 | 0.000000E+00 | 0.000000E+00 | 1.0122687799 | 1.0000751839
7 | 700 | 0.000000E+00 | 0.000000E+00 | 1.0065700992 | 1.0000751839
8 | 800 | 0.000000E+00 | 0.000000E+00 | 1.0035541231 | 1.0000751839
9 | 900 | 0.000000E+00 | 0.000000E+00 | 1.0020027789 | 1.0000734926
10 | 1000 | 0.000000E+00 | 0.000000E+00 | 1.0011629318 | 1.0000734926
11 | 1100 | 0.000000E+00 | 0.000000E+00 | 1.0006807512 | 1.0000673740
12 | 1200 | 0.000000E+00 | 0.000000E+00 | 1.0002122873 | 1.0000443796
13 | 1300 | 0.000000E+00 | 0.000000E+00 | 1.0001351986 | 1.0000427008
14 | 1400 | 0.000000E+00 | 0.000000E+00 | 1.0001147938 | 1.0000427008
15 | 1500 | 0.000000E+00 | 0.000000E+00 | 1.0000930356 | 1.0000427008
16 | 1600 | 0.000000E+00 | 0.000000E+00 | 1.0000772331 | 1.0000394598
17 | 1700 | 0.000000E+00 | 0.000000E+00 | 1.0000714031 | 1.0000394598
18 | 1800 | 0.000000E+00 | 0.000000E+00 | 1.0000658372 | 1.0000394598
19 | 1900 | 0.000000E+00 | 0.000000E+00 | 1.0000616017 | 1.0000394598
20 | 2000 | 0.000000E+00 | 0.000000E+00 | 1.0000568967 | 1.0000394598
Best solution found:
X = [0.25000986 0.75002959]
F = [1.00003946]
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.5140031853 | - | -
3 | 300 | 0.0082848537 | 0.2037348213 | - | -
4 | 400 | 0.0035724722 | 0.0693818119 | - | -
5 | 500 | 0.0027335643 | 0.0333759183 | - | -
6 | 600 | 0.0020718948 | 0.0210356793 | - | -
7 | 700 | 0.0008449391 | 0.0133758351 | - | -
8 | 800 | 0.000000E+00 | 0.0096977061 | 1.2513217304 | 1.2513217304
9 | 900 | 0.000000E+00 | 0.0071439108 | 1.2513217304 | 1.2513217304
10 | 1000 | 0.000000E+00 | 0.0058541556 | 1.1754600320 | 1.0995983336
11 | 1100 | 0.000000E+00 | 0.0052902209 | 1.1754600320 | 1.0995983336
12 | 1200 | 0.000000E+00 | 0.0049327884 | 1.1754600320 | 1.0995983336
13 | 1300 | 0.000000E+00 | 0.0043883970 | 1.1754600320 | 1.0995983336
14 | 1400 | 0.000000E+00 | 0.0038476002 | 1.1754600320 | 1.0995983336
15 | 1500 | 0.000000E+00 | 0.0034046822 | 1.1754600320 | 1.0995983336
16 | 1600 | 0.000000E+00 | 0.0027531895 | 1.1754600320 | 1.0995983336
17 | 1700 | 0.000000E+00 | 0.0022305012 | 1.1754600320 | 1.0995983336
18 | 1800 | 0.000000E+00 | 0.0018260365 | 1.1754600320 | 1.0995983336
19 | 1900 | 0.000000E+00 | 0.0014214863 | 1.1797710466 | 1.0995983336
20 | 2000 | 0.000000E+00 | 0.0012825097 | 1.1797710466 | 1.0995983336
Best solution found:
X = [0.27488696 0.82471138]
F = [1.09959833]
CV = [0.]