1

Referring to my code below (only the relevant part of original code), since x0 is a 4 X 3 array, x should also be the same. But I get an 'invalid index to scalar variable' error in constraint1.

I wrote the constraints iteratively as done in the answer in scipy.optimize.minimize (COBYLA and SLSQP) ignores constraints initiated within for loop

Any better (general) way to write the constraints would be great. Thanks in advance!

I need the loop for the constraints as this is just a toy optimization problem and not the original optimization problem(Game theory) I wish to solve.

The code(link to complete code below):

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)

And the error (Please ignore the line numbers as the above is a part of a slightly bigger code):

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.

The complete code: https://pastebin.com/cvYBvW3B

dott
  • 13
  • 3

1 Answers1

0

It seems that optimization task flatten your initial guess and return after each iteration flattened solution array (instead of 4x3 array it returns 1x12 array). That's why you get this kind of error. You should reshape your x array in objective and constraints functions from 1x12 to 4x3. After that, you can access second dimension of x variable and avoid IndexError: invalid index to scalar variable.. Your functions should be like this:

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
Eduard Ilyasov
  • 3,268
  • 2
  • 20
  • 18