Scipy:我怎样才能在trust-constr中使用Bounds?

b5buobof  于 2022-12-18  发布在  其他
关注(0)|答案(2)|浏览(144)

对于我的约束问题,我想使用Scipy-Trusted-Constr算法,因为我有一个多变量的约束问题。我不想/不能解析计算Jacobi/Hessian,也不能计算它。但是,在设置边界时,Jacobian的计算崩溃:

File "C:\Python27\lib\site-packages\scipy\optimize\_trustregion_constr\tr_interior_point.py", line 56, in __init__
    self.jac0 = self._compute_jacobian(jac_eq0, jac_ineq0, s0)
  File "C:\Python27\lib\site-packages\scipy\optimize\_trustregion_constr\tr_interior_point.py", line 164, in _compute_jacobian
    [J_ineq, S]]))
  File "C:\Python27\lib\site-packages\numpy\matrixlib\defmatrix.py", line 1237, in bmat
    arr_rows.append(concatenate(row, axis=-1))
ValueError: all the input array dimensions except for the concatenation axis must match exactly

使用旧样式边界和最新的Bounds对象时都会出现错误。我可以使用以下代码重现错误:

import numpy as np
import scipy.optimize as scopt

def RosenbrockN(x):
    result = 0
    for i in range(len(x)-1):
        result += 100*(x[i+1]-x[i]**2)**2+(1-x[i])**2
    return result
x0 = [0.0, 0.0, 0.0]
#bounds = scopt.Bounds([-2.0,-0.5,-2.0],[2.0,0.8,0.7])
bounds = [(-2.0,2.0),(-0.5,0.8),(-2.0,0.7)] 
Res = scopt.minimize(RosenbrockN, x0, \
                    method = 'trust-constr', bounds = bounds, \
                    jac = '2-point', hess = scopt.SR1())

我想我只是误解了界限是如何设定的,但找不到我的错误。谢谢你的建议。
编辑:我也尝试了文档中的代码示例,得到了相同的结果。其他方法如SLSQP可以很好地使用边界。
SciPy版本1.1.0,Python版本2.7.4,操作系统Win 7企业版。

ac1kyiln

ac1kyiln1#

我用“trust-constr”方法试了几次,边界约束都没有被包含进去。我用线性约束作为边界条件解决了这个问题。

from scipy.optimize import minimize, LinearConstraint, Bounds
  
def RosenbrockN(x):
    result = 0
    for i in range(len(x)-1):
        result += 100*(x[i+1]-x[i]**2)**2+(1-x[i])**2
    return result

x0 = [0.0, 0.0, 0.0]

# This will not work:
#bounds = Bounds([-2.0,-0.5,-2.0],[2.0,0.8,0.7])

# This works
lb = [-2.0,-0.5,-2.0]
ub = [2.0,0.8,0.7]
A = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
lcons = LinearConstraint(A, lb=lb, ub=ub, keep_feasible=True)
Res = minimize(RosenbrockN, x0, method = 'trust-constr', constraints=lcons)
jutyujz0

jutyujz02#

我删除了你的jac和hess的论点,让它工作;也许问题就出在这里?

import numpy as np
import scipy.optimize as scopt

def RosenbrockN(x):
    result = 0
    for i in range(len(x)-1):
        result += 100*(x[i+1]-x[i]**2)**2+(1-x[i])**2
    return result

x0 = [0.0, 0.0, 0.0]
#bounds = scopt.Bounds([-2.0,-0.5,-2.0],[2.0,0.8,0.7])
bounds = [(-2.0,2.0),(-0.5,0.8),(-2.0,0.7)] 
Res = scopt.minimize(RosenbrockN, x0, \
                    method = 'SLSQP', bounds = bounds)
print(Res)

结果是

fun: 0.051111012543332675
     jac: array([-0.00297706, -0.50601892, -0.00621008])
 message: 'Optimization terminated successfully.'
    nfev: 95
     nit: 18
    njev: 18
  status: 0
 success: True
       x: array([0.89475126, 0.8       , 0.63996894])

相关问题