设置 x0 的特定数组子集的边界 scipy python

Setting bounds of a specific array subset of x0 scipy python

我需要在 scipy.optimize.minimize() 函数中为 x0 数组的每个子集设置不同的边界。

这是我到目前为止尝试过的:

    x0 = np.zeros(20)
    
    # disp = x0[0:5]
    # w = x0[5:10]
    # qi = x0[10:15]
    # qai = x0[15:20]
    
    #bonds
    bnds = (((-np.inf, np.inf) for i in x0[0:5]), ((0, 1) for i in x0[5:10]), ((0, np.inf) for i in x0[10:15]), ((int(-1000000), int(100000000)) for i in x0[15:20]))

cons = [{'type': 'ineq', 'fun': lambda x: x[10:15] - lotMin * x[5:10]},
        {'type': 'eq', 'fun': lambda x: x[15:20] - x[10:15] / arrot},
        {'type': 'ineq', 'fun': lambda x: x[0:5]},
        {'type': 'ineq', 'fun': lambda x: x[15:20] - D},
        {'type': 'ineq', 'fun': lambda x: -(x[10:15] - M * x[5:10])},
        {'type': 'ineq', 'fun': lambda x: x[10:15] - x[5:10]},
        {'type': 'eq', 'fun': lambda x: x[0:5] - Disp_0 - x[10:15] + D}]

res = minimize(fun=lambda x: sum(x[0:4]*ho)+co*sum(x[5:9]), constraints=cons, x0=x0, bounds=bnds,
               method='SLSQP', options=dict(ftol=1e-6))

这是我得到的错误:

Traceback (most recent call last):
  File "C:\Users\davide.tamagnini.con\AppData\Roaming\JetBrains\PyCharmCE2021.1\scratches\scratch_1.py", line 84, in <module>
    res = minimize(fun=lambda x: sum(x[0:4]*ho)+co*sum(x[5:9]), constraints=cons, x0=x0, bounds=bnds,
  File "C:\Python\Python395\lib\site-packages\scipy\optimize\_minimize.py", line 627, in minimize
    return _minimize_slsqp(fun, x0, args, jac, bounds,
  File "C:\Python\Python395\lib\site-packages\scipy\optimize\slsqp.py", line 259, in _minimize_slsqp
    new_bounds = old_bound_to_new(bounds)
  File "C:\Python\Python395\lib\site-packages\scipy\optimize\_constraints.py", line 323, in old_bound_to_new
    lb, ub = zip(*bounds)
ValueError: too many values to unpack (expected 2)

有没有人遇到同样的问题?

提前致谢, 大卫

正如评论中已经提到的,bounds 必须是一个元组序列。因此,您可以这样做:

# Bounds
bnds = []
for i, _ in enumerate(x0):
    if i <= 4:
        bnds.append((-np.inf, np.inf))
    elif 5 <= i <= 9:
        bnds.append((0, np.inf))
    else:
        bnds.append(-1000000, 100000000)