【问题标题】:Scipy optimize minimize iterated constraints do not recognize x as an arrayScipy 优化最小化迭代约束不将 x 识别为数组
【发布时间】:2017-10-09 01:01:34
【问题描述】:

参考我下面的代码(仅原始代码的相关部分),由于 x0 是一个 4 X 3 数组,x 也应该是相同的。但我在约束 1 中收到“标量变量的无效索引”错误。

我按照scipy.optimize.minimize (COBYLA and SLSQP) ignores constraints initiated within for loop 中的答案迭代地编写了约束

编写约束的任何更好(通用)方式都会很棒。提前致谢!

我需要约束循环,因为这只是一个玩具优化问题,而不是我希望解决的原始优化问题(博弈论)。

代码(下面的完整代码链接):

def constraint1(i):
  def g(x):
    con = 20
    for k in range(3):
      con = con - x[i][k]
    return con
  return g

x0 = np.array([[5,5,5],[5,5,5],[5,5,5],[5,5,5]])

cons = []

for i in range(4):
  cons.append({'type': 'ineq', 'fun': constraint1(i)})

solution = minimize(objective,x0,method='SLSQP',\
                    bounds=None,constraints=cons)

还有错误(请忽略行号,因为上面是稍大代码的一部分):

Traceback (most recent call last):
  File "opt.py", line 44, in <module>
    bounds=None,constraints=cons)
  File "C:\Users\dott\Anaconda2\lib\site-packages\scipy\optimize\_minimize.py", line 458, in minimize constraints, callback=callback, **options)
  File "C:\Users\dott\Anaconda2\lib\site-packages\scipy\optimize\slsqp.py", line 312, in _minimize_slsqp
    mieq = sum(map(len, [atleast_1d(c['fun'](x, *c['args'])) for c in cons['ineq']]))
  File "opt.py", line 15, in g
    con = con - x[i][k]
IndexError: invalid index to scalar variable.

完整代码:https://pastebin.com/cvYBvW3B

【问题讨论】:

    标签: python scipy


    【解决方案1】:

    似乎优化任务使您的初始猜测变平,并在每次迭代后返回展平解决方案数组(而不是 4x3 数组,它返回 1x12 数组)。这就是为什么你会得到这种错误。您应该将目标函数和约束函数中的 x 数组从 1x12 重塑为 4x3。之后,您可以访问x 变量的第二维并避免IndexError: invalid index to scalar variable.。你的函数应该是这样的:

    def objective(x):
        global q
        sum = 0
        x = x.reshape((4, 3))
        for i in range(4):
            for j in range(3):
                sum = sum + x[i][j]*q[i][j]
        return -1*sum
    
    def constraint1(i):
        def g(x):
            con = 20
            x = x.reshape((4, 3))
            for k in range(3):
                con = con - x[i][k]
            return con
        return g
    
    def constraint2(k):
        def h(x):
            sum_eq = 20
            x = x.reshape((4, 3))
            for i in range(4):
                sum_eq = sum_eq - x[i][k]
            return sum_eq
        return h
    

    【讨论】:

    • 这行得通。太感谢了!我很傻,不检查 x 的大小
    猜你喜欢
    • 2017-08-01
    • 2013-12-03
    • 2016-05-27
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 2014-07-13
    相关资源
    最近更新 更多