我试图在给定范围内最大化两个单调递增函数f(x) = f1(x) + f2(x)
的总和,比如x = 0 to 6
。这两个函数的曲线是:
为了解决这个问题,我正在使用scipy
包中的盆景功能。
我想指定使用边界的约束。具体来说,我希望边界的总和小于或等于常数值。即在我下面的实现中,我希望x[0] + x[1] <= C
位于C = 6
。
在上图中,对于C = 6
,大约x[0] = 2 and x[1] = 4
(4 + 2 =&lt; = 6)将产生最大值。我的问题是如何指定这个约束?如果不可能,还有另一个更适合这个问题的优化函数吗?
from scipy.optimize import basinhopping
from math import tanh
def f(x):
return -(f1(x[0]) + f2(x[1])) # -ve sign for maximization
def f1(x):
return tanh(x)
def f2(x):
return (10 ** (0.2 * x))
# Starting point
x0 = [1., 1.]
# Bounds
xmin = [1., 1.]
xmax = [6., 6.]
# rewrite the bounds in the way required by L-BFGS-B
bounds = [(low, high) for low, high in zip(xmin, xmax)]
minimizer_kwargs = dict(method="L-BFGS-B", bounds=bounds)
result = basinhopping(f,
x0,
minimizer_kwargs=minimizer_kwargs,
niter=200)
print("global max: x = [%.4f, %.4f], f(x0) = %.4f" % (result.x[0], result.x[1], result.fun))
答案 0 :(得分:0)
这可以通过COBYLA约束优化实现,但我不知道如何使用L-BFGS-B。您可以添加如下约束:
def constraint1(x):
return 6 - x[0]
def constraint2(x):
return 6 - x[0] - x[1]
def constraint3(x):
return x[0] - 1
要将这些约束添加到最小化器,请使用:
c1={"type":"ineq","fun":constraint1}
c2={"type":"ineq","fun":constraint2}
c3={"type":"ineq","fun":constraint3}
minimizer_kwargs = dict(method="COBYLA",constraints=(c1,c2,c3))
当我运行此示例时,我得到结果global max: x = [1.0000, 5.0000], f(x0) = -10.7616
注意,我还没有测试是否需要添加x[1]>1
。
有关更多阅读,请参阅cobyla的文档: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_cobyla.html