流域优化中的自定义边界约束

时间:2015-12-15 17:35:17

标签: python optimization scipy

我试图在给定范围内最大化两个单调递增函数f(x) = f1(x) + f2(x)的总和,比如x = 0 to 6。这两个函数的曲线是:enter image description here

为了解决这个问题,我正在使用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))

1 个答案:

答案 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

的约束4

有关更多阅读,请参阅cobyla的文档: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_cobyla.html