Scipy optimize.minimize 函数
Scipy optimize.minimize function
我尝试使用 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
这就是约束看起来像那样的原因。
您的参数 space 似乎是 5 维的。参数中的一个点
space 将是 z = (r, x1, y1, x2, y2)
。因此要最小化的函数
-- 以及约束函数 -- 应该接受一个点 z
和
return 标量值。
因此而不是
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 <= r <= 1
等简单约束。如果 x1
、y1
、x2
、y2
的范围是从 -1 到 1,那么您可能还需要更改
x1 = np.linspace(0, 1, 100)
...
至
x1 = np.linspace(-1, 1, 100)
...
然而,数组r
、x1
、y1
、x2
、y2
不需要最小化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.])
我尝试使用 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
这就是约束看起来像那样的原因。
您的参数 space 似乎是 5 维的。参数中的一个点
space 将是 z = (r, x1, y1, x2, y2)
。因此要最小化的函数
-- 以及约束函数 -- 应该接受一个点 z
和
return 标量值。
因此而不是
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 <= r <= 1
等简单约束。如果 x1
、y1
、x2
、y2
的范围是从 -1 到 1,那么您可能还需要更改
x1 = np.linspace(0, 1, 100)
...
至
x1 = np.linspace(-1, 1, 100)
...
然而,数组r
、x1
、y1
、x2
、y2
不需要最小化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.])