SCIPY - построение ограничений без перечисления каждой переменной отдельно - PullRequest
3 голосов
/ 06 мая 2020

Я использую SCIPY для оптимизации хранилища, которое использует форвардные цены на срок сделки 1 год. Газ может закачиваться и забираться с этого объекта на основе месячных спрэдов (например, спред 21 марта по сравнению с 20 мая), которые достаточно высоки для покрытия переменных затрат на эксплуатацию. Прикрепленное изображение представляет проблему (значения здесь произвольные, не соответствуют значениям в коде; pi c только для концепции)

enter image description here

Ячейки синего цвета - это «изменяющиеся ячейки», объемы, которые SCIPY будет корректировать, чтобы максимизировать прибыль. Ограничения необходимо устанавливать для каждого месяца отдельно. Я получаю ошибки, когда пытаюсь установить эти ограничения в SCIPY. Вот воспроизводимая версия проблемы:

 import numpy as np
import scipy.optimize as opt

p= np.array([4, 5, 6.65, 12]) #p = prices
pmx = np.triu(p - p[:, np.newaxis]) #pmx = price matrix, upper triangular

q =np.triu(np.ones((4,4))) # q = quantity, upper triangular

def profit(q):
    profit = -np.sum(q.flatten() * pmx.flatten())
    return profit

bnds = (0,10)
bnds = [bnds for i in q.flatten()]

def cons1(q):
    np.sum(q,axis=1) -  10

#def cons2(q):
#    np.sum(q,axis=0) -  8

#con1 = {'type':'ineq','fun':cons1}
#con2 = {'type':'ineq','fun':cons2}
cons = [con1]    # using only  1 constraint (con1) to test the model

#sol = opt.minimize(profit,q,method='SLSQP', bounds= bnds,constraints = cons)
sol = opt.minimize(profit,q,method='SLSQP', bounds= bnds)
sol

Модель работает нормально, когда я исключаю ограничения. Когда я добавляю одно из ограничений, я получаю следующее сообщение об ошибке:

AxisError: axis 1 is out of bounds for array of dimension 1

Я думаю, это связано с тем, как я указываю ограничения ... Я не уверен. Что касается ограничений, мне нужно определить инъекции и изъятия, а также установить ограничения, как показано на рисунке. Помощь будет оценена. Спасибо!

1 Ответ

3 голосов
/ 07 мая 2020

В качестве альтернативы Scipy.minimize.optimize вот решение с Python gekko .

import numpy as np
import scipy.optimize as opt
from gekko import GEKKO

p= np.array([4, 5, 6.65, 12]) #p = prices
pmx = np.triu(p - p[:, np.newaxis]) #pmx = price matrix, upper triangular

m = GEKKO(remote=False)
q = m.Array(m.Var,(4,4),lb=0,ub=10)
# only upper triangular can change
for i in range(4):
    for j in range(4):
        if j<=i:
            q[i,j].upper=0 # set upper bound = 0

def profit(q):
    profit = np.sum(q.flatten() * pmx.flatten())
    return profit

for i in range(4):
    m.Equation(np.sum(q[i,:])<=10)
    m.Equation(np.sum(q[:,i])<=8)
m.Maximize(profit(q))

m.solve()

print(q)

Это дает решение:

[[[0.0] [2.5432017412] [3.7228765674] [3.7339217013]]
 [[0.0] [0.0] [4.2771234426] [4.2660783187]]
 [[0.0] [0.0] [0.0] [0.0]]
 [[0.0] [0.0] [0.0] [0.0]]]
...