问题
I am using SCIPY to optimize a storage facility that uses forward prices for a deal term of 1 year. Gas can be injected and withdrawn from this facility, based on monthly spreads (e.g. March 21 vs May 20 spread) being high enough to cover the variable cost of operation. The attached picture represents the problem (the values here are arbitrary, don't match the values in the code; pic is just for concept)
The cells in blue are the "changing cells", volumes that SCIPY will adjust to maximize profits. The constraints need to be set up for each month separately. I get errors when I attempt to set up these constraints in SCIPY. Here's a reproducible version of the problem:
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
The model runs fine when I exclude the constraints. When I add one of the constraints, the error I get is:
AxisError: axis 1 is out of bounds for array of dimension 1
I think this has to do with the the way I'm specifying the constraints....I'm not sure though. For the constraints, I do need to identify injections and withdrawals and set the constraints as shown in the picture. Help would be appreciated. Thanks!
回答1:
As an alternative to Scipy.minimize.optimize, here is a solution with 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)
This gives the solution:
[[[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]]]
来源:https://stackoverflow.com/questions/61623986/scipy-building-constraints-without-listing-each-variable-separately