使用lambda作为约束函数

1 投票
1 回答
2871 浏览
提问于 2025-04-15 14:45
import numpy 
from numpy import asarray

Initial = numpy.asarray [2.0, 4.0, 5.0, 3.0, 5.0, 6.0]       # Initial values to start with


bounds = [(1, 5000), (1, 6000), (2, 100000), (1, 50000), (1.0, 5000), (2, 1000000)] 

# actual passed bounds

b1 = lambda x: numpy.asarray([1.4*x[0] - x[0]])  
b2 = lambda x: numpy.asarray([1.4*x[1] - x[1]])  
b3 = lambda x: numpy.asarray([x[2] - x[3]])     
constraints = numpy.asarray([b1, b2, b3])

opt= optimize.fmin_slsqp(func,Initial,ieqcons=constraints,bounds=bounds, full_output=True,iter=200,iprint=2, acc=0.01)

问题: 我想要传入不等式约束。假设我有6个参数

[ a, b, c, d, e, f]

Initial值中,我的约束是:

a<=e<=1.4*a   ('e' varies from a to 1.4*a)
b<=f<=1.4*b   ('f' varies from b to 1.4*b)
c>d           ('c' must always be greater than d)

但是这样做不太奏效。我不知道哪里出错了。 有没有更好的方法可以把我的约束作为一个函数传入? 请帮帮我。

1 个回答

1

根据Robert Kern的评论,我已经删除了之前的回答。下面是作为连续函数的约束条件:

b1 = lambda x: x[4]-x[0] if x[4]<1.2*x[0] else 1.4*x[0]-x[4]
b2 = lambda x: x[5]-x[1] if x[5]<1.2*x[1] else 1.4*x[1]-x[5]
b3 = lambda x: x[2]-x[3]

注意:这个语法需要Python 2.5或更高版本。1

为了得到约束条件 a<=e<=1.4*a,我们注意到 1.2*aa1.4*a 之间的中间点。

在这个中间点以下,也就是所有 e<1.2*a 的情况,我们使用连续函数 e-a。因此,当 e<a 时,整体约束函数是负值,这表示低于下限的情况;当 e==a 时,值为零;然后当 e>a 时,值为正,直到中间点。

在中间点以上,也就是所有 e>1.2*a 的情况,我们使用连续函数 1.4*a-e。这意味着当 e>1.4*a 时,整体约束函数是负值,表示超出上限的情况;当 e==1.4*a 时,值为零;然后当 e<1.4*a 时,值为正,直到中间点。

在中间点 e==1.2*a 时,这两个函数的值是相同的。这意味着整体函数是连续的。

参考资料:关于 ieqcons 的文档

1 - 这里是Python 2.5之前的语法:b1 = lambda x: (1.4*x[0]-x[4], x[4]-x[0])[x[4]<1.2*x[0]]

撰写回答