我是神秘作家。我不确定你想要什么......你已经以软约束(即惩罚)的形式编写了约束,所以我会这样做。
要耦合惩罚,您可以使用类似的耦合器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
。