【问题标题】:Scipy optimize.minimize functionScipy optimize.minimize 函数
【发布时间】:2016-06-13 02:05:21
【问题描述】:

我尝试使用 scipy.optimize.minimize 解决非线性编程任务

max r
x1**2 + y1**2 <= (1-r)**2
(x1-x2)**2 + (y1-y2)**2 >= 4*r**2
0 <= r <= 1

所以我写了下一段代码:

r = np.linspace(0, 1, 100)
x1 = np.linspace(0, 1, 100)
y1 = np.linspace(0, 1, 100)
x2 = np.linspace(0, 1, 100)
y2 = np.linspace(0, 1, 100)


fun = lambda r: -r
cons = ({'type': 'ineq',
     'fun': lambda x1, r: [x1[0] ** 2 + x1[1] ** 2 - (1 - r) ** 2],
     'args': (r,)},
    {'type': 'ineq',
     'fun': lambda x2, r: [x2[0] ** 2 + x2[1] ** 2 - (1 - r) ** 2],
     'args': (r,)},
    {'type': 'ineq',
     'fun': lambda x1, x2, r: [(x1[0] - x2[0]) ** 2 + (x1[1] - x2[1]) ** 2 - 4 * r ** 2],
     'args': (x2, r,)})
bnds = ((0, 1), (-1, 1), (-1, 1), (-1, 1), (-1, 1))
x0 = [0, 0, 0, 0, 0]
minimize(fun, x0, bounds=bnds, constraints=cons)

但我有下一个错误

File "C:\Anaconda2\lib\site-packages\scipy\optimize\slsqp.py", line 377, in _minimize_slsqp
c = concatenate((c_eq, c_ieq))
ValueError: all the input arrays must have same number of dimensions

请帮我找出我的错误并编写正确的代码

统一更新: 感谢@unutbu,我已经了解如何正确构建它。

fun = lambda x: -x[0]
cons = ({'type': 'ineq',
     'fun': lambda x: -x[1] ** 2 - x[2] ** 2 + (1 - x[0]) ** 2},
    {'type': 'ineq',
     'fun': lambda x: -x[3] ** 2 - x[4] ** 2 + (1 - x[0]) ** 2},
    {'type': 'ineq',
     'fun': lambda x: (x[1] - x[3]) ** 2 + (x[1] - x[4]) ** 2 - 4 * x[0] ** 2})
bnds = ((0, 1), (-1, 1), (-1, 1), (-1, 1), (-1, 1))
x0 = [0.5, 0.3, 0.5, 0.3, 0.5]
answer = minimize(fun, x0, bounds=bnds, constraints=cons)

在最小化任务中,我们必须将约束引入这种形式:

g(x) >= 0

这就是约束看起来像这样的原因。

【问题讨论】:

  • 可能是第三个cons 函数需要2个参数。其他一切都使用 1,根据x0,它是一个 5 元素数组。

标签: python scipy nonlinear-optimization


【解决方案1】:

您的参数空间似乎是 5 维的。参数中的一个点 空间将是z = (r, x1, y1, x2, y2)。因此要最小化的函数 -- 还有约束函​​数 -- 应该接受一个点z 和 返回一个标量值。

因此而不是

fun = lambda r: -r

使用

def func(z):
    r, x1, y1, x2, y2 = z
    return -r

而不是

lambda x1, r: [x1[0] ** 2 + x1[1] ** 2 - (1 - r) ** 2]

使用

def con1(z):
    r, x1, y1, x2, y2 = z
    return x1**2 + y1**2 - (1-r)**2

等等。


请注意,可以通过设置bounds 参数而不是定义约束来处理简单的约束,例如0 &lt;= r &lt;= 1。如果x1y1x2y2 的范围是从 -1 到 1,那么您可能还需要更改

x1 = np.linspace(0, 1, 100)
...

x1 = np.linspace(-1, 1, 100)
...

但是,数组rx1y1x2y2 不需要最小化func,因此您也可以完全从脚本中消除它们。


import numpy as np
import scipy.optimize as optimize

"""
max r
x1**2 + y1**2 <= (1-r)**2
(x1-x2)**2 + (y1-y2)**2 >= 4*r**2
0 <= r <= 1
"""

def func(z):
    r, x1, y1, x2, y2 = z
    return -r

def con1(z):
    r, x1, y1, x2, y2 = z
    return x1**2 + y1**2 - (1-r)**2

def con2(z):
    r, x1, y1, x2, y2 = z
    return 4*r**2 - (x1-x2)**2 - (y1-y2)**2 

cons = ({'type': 'ineq', 'fun': con1}, {'type': 'ineq', 'fun': con2},)
bnds = ((0, 1), (-1, 1), (-1, 1), (-1, 1), (-1, 1))
guess = [0, 0, 0, 0, 0]
result = optimize.minimize(func, guess, bounds=bnds, constraints=cons)
print(result)

产量

     fun: -1.0
     jac: array([-1.,  0.,  0.,  0.,  0.,  0.])
 message: 'Optimization terminated successfully.'
    nfev: 14
     nit: 2
    njev: 2
  status: 0
 success: True
       x: array([ 1.,  0.,  0.,  0.,  0.])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-27
    • 2015-10-02
    • 1970-01-01
    • 2020-07-14
    • 2016-09-28
    • 2018-03-12
    • 2019-03-12
    • 1970-01-01
    相关资源
    最近更新 更多