2017-10-08 43 views
1

参考我的代码如下(只有原代码的相关部分),因为x0是一个4×3的数组,x也应该是相同的。但是我在constraint1中得到'标量变量无效索引'错误。Scipy优化最小化迭代约束不认可x为数组

我写的制约反复在回答做过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

回答

0

看来,优化任务平坦化你的初始猜测和返回后,每次迭代展平解决方案数组(而不是4x3数组它返回s 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 
+0

这个工程。非常感谢!愚蠢的我不检查x的大小 – dott