如何在 Mystic 中以函数形式指定多个约束?
How to specify multiple constraints in function form in Mystic?
使用Mystic求解器如何输入多个约束?例如,我有这两个函数来描述我的两个约束:
def constraint1(x):
return x[0]*x[1]*x[2]*x[3]-25.0
def constraint2(x):
sum_eq = 40.0
for i in range(4):
sum_eq = sum_eq - x[i]**2
return sum_eq
使用diffev(...)
时,输入这些约束的正确方法是什么?
我是神秘的作者。我不确定你想要什么......你已经以软约束(即惩罚)的形式编写了约束,所以我会接受它。
要耦合惩罚,您可以使用像 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
的求解器。
使用Mystic求解器如何输入多个约束?例如,我有这两个函数来描述我的两个约束:
def constraint1(x):
return x[0]*x[1]*x[2]*x[3]-25.0
def constraint2(x):
sum_eq = 40.0
for i in range(4):
sum_eq = sum_eq - x[i]**2
return sum_eq
使用diffev(...)
时,输入这些约束的正确方法是什么?
我是神秘的作者。我不确定你想要什么......你已经以软约束(即惩罚)的形式编写了约束,所以我会接受它。
要耦合惩罚,您可以使用像 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
的求解器。