在scipy中为fmin_cobyla指定约束
我在用 Python 2.5。
我正在给 cobyla 优化算法传递一些边界条件:
import numpy
from numpy import asarray
Initial = numpy.asarray [2, 4, 5, 3] # Initial values to start with
#bounding limits (lower,upper) - for visualizing
#bounds = [(1, 5000), (1, 6000), (2, 100000), (1, 50000)]
# actual passed bounds
b1 = lambda x: 5000 - x[0] # lambda x: bounds[0][1] - Initial[0]
b2 = lambda x: x[0] - 2.0 # lambda x: Initial[0] - bounds[0][0]
b3 = lambda x: 6000 - x[1] # same as above
b4 = lambda x: x[1] - 4.0
b5 = lambda x: 100000 - x[2]
b6 = lambda x: x[2] - 5.0
b7 = lambda x: 50000 - x[3]
b8 = lambda x: x[3] - 3.0
b9 = lambda x: x[2] > x[3] # very important condition for my problem!
opt= optimize.fmin_cobyla(func,Initial,cons=[b1,b2,b3,b4,b5,b6,b7,b8,b9,b10],maxfun=1500000)
根据初始值 Initial
和边界条件 b1
到 b10
,这些值会传递给 opt()
函数。但是这些值偏离了预期,尤其是 b9
的情况。这对我的问题来说是一个非常重要的边界条件!
“传给我函数 opt()
的值 x[2]
在每次迭代中必须始终大于 x[3]
”——我该如何做到这一点呢?
我的边界定义(b1
到 b9
)有没有什么问题?
或者有没有更好的方法来定义我的边界?
请帮帮我。
2 个回答
2
对于 b10,一个可能的选择是:
b10 = lambda x: min(abs(i-j)-d for i,j in itertools.combinations(x,2))
这里的 d 是一个增量,应该大于你希望在变量之间的最小差值(比如说 0.001)。
3
fmin_cobyla()
不是一种内部点方法。这意味着在优化过程中,它会把一些超出限制的点(也就是“不可行点”)传递给函数。
你需要修正的一点是,b9
和 b10
的格式不符合 fmin_cobyla()
的要求。边界函数需要返回一个正数,如果点在边界内;返回0.0,如果点正好在边界上;返回负数,如果点超出了边界。理想情况下,这些函数应该是平滑的。fmin_cobyla()
会尝试对这些函数进行数值导数计算,以帮助它了解如何回到可行区域。
b9 = lambda x: x[2] - x[3]
不过,我不太确定如何实现 b10
,让 fmin_cobyla()
能够使用。