Я мисти c автор. Я не уверен, что вы хотите ... Вы написали ограничения в виде мягких ограничений (то есть штрафов), поэтому я буду go с этим.
Чтобы связать штрафы, вы можете использовать сопряжение типа mystic.coupler.and_
, или вы можете использовать декоратор штрафа, например:
>>> import mystic as my
>>>
>>> def penalty1(x):
... return x[0]*x[1]*x[2]*x[3] - 25.0
...
>>> def penalty2(x):
... return 40.0 - sum(i*i for i in x)
...
>>> x
[4, 5, 1, 9]
>>>
>>> @my.penalty.linear_equality(penalty1)
... @my.penalty.linear_equality(penalty2)
... def penalty(x):
... return 0.0
...
>>> penalty(x)
23800.0
>>>
Затем, если все, что вы хотите сделать, это решить, где размер штрафа наименьший, вы можете использовать diffev
на непосредственно штраф:
>>> my.solvers.diffev(penalty, [10,10,10,10], npop=100)
Optimization terminated successfully.
Current function value: 0.001920
Iterations: 167
Function evaluations: 16800
array([1.92486578, 0.86032337, 2.89649062, 5.21201382])
>>>
Если вы хотите применить их в качестве штрафа при решении какой-либо другой функции, то вы бы сделали это следующим образом:
>>> from mystic.models import rosen # the Rosenbrock test function
>>> my.solvers.diffev(rosen, [0,0,0,0], penalty=penalty, npop=100)
Optimization terminated successfully.
Current function value: 2.263629
Iterations: 182
Function evaluations: 18300
array([1.24923882, 1.53972652, 2.35201514, 5.5259994 ])
Если вы хотите жесткие ограничения, это другое дело:
>>> def constraint1(x, val=29):
... res = my.constraints.normalize([i*i for i in x], val)
... return [i**.5 for i in res]
...
>>> def constraint2(x, val=24):
... return my.constraints.impose_product(val, x)
...
>>> constraint3 = my.constraints.integers()(lambda x:x)
>>>
>>> constraint = my.constraints.and_(constraint1, constraint2, constraint3)
>>>
>>> x = [1,2,3]
>>> z = constraint(x)
>>>
>>> assert constraint1(z) == z
>>> assert constraint2(z) == z
>>> assert constraint3(z) == z
>>> z
[2.0, 3.0, 4.0]
Они применяются к решателям с ключевым словом constraints
.