You need to use binary variables to model this in your problem. How you do this is up to you but maybe this reference will help
http://mat.gsia.cmu.edu/orclass/integer/integer.html
I’m trying to solve an storage optimization problem using PULP in Python, where given daily prices I want to maximize the profit, say for the next year (365 days). I have defined a list of 365 variables “net_withdrawals” (positive number for withdrawals and negative if injections), and set an initial lower and upper limits in the declaration.
However, and I also have constraints defined that, the storage stock/inventory level at any time must be between 0 and maximum capacity, and so far so good. I’m having issue with adding another constraints to “futher“ limit the “net_withdrawals” variables for each day between a narrower range, based on the current stock level: e.g, withdrawal rate is halved and injection rate is doubled if the stock goes below 50% of the total capacity, and vice versa.
I can work out the current stock level, however as it is an Affine Expressions, I cannot seem to use if-else conditional statement to check his value and define the new limits for “net_withdrawals” variables. E.g.: total capacity is 1000, and I tried:
Optimization_model = pulp.LpProblem(Model - LP', pulp.LpMaximize)
periods = range(0, NUMBER_OF_DAYS)
net_withdrawals = [pulp.LpVariable("net_withdrawals_%s" % i, lowBound=-50, upBound=50) for i in periods]
For day in periods:
Stock_level -= net_withdrawals[i]
If stock_level < 500:
Optimization_model += net_withdrawals[i] < -25
Optimization_model += net_withdrawals[i] > 50
Else:
Optimization_model += net_withdrawals[i] < -50
Optimization_model += net_withdrawals[i] > 25
I’d like to add different constraints for boundary limits based on different stock levels, e.g. 25%, 50%, 75% etc…
But I could not seem to get this basic logic working.
Would you be able to suggest/advice?
I really appreciate it and thanks in advance.
netInj_flags_1 = [pulp.LpVariable("NW_%s" % i, lowBound=0, upBound=1, cat=pulp.LpInteger) for i in periods]
netInj_vars_1 = [pulp.LpVariable("NW_%s" % i, lowBound=MAX_WITHDRAWAL_RATE/2, upBound=MAX_INJECTION_RATE, cat=pulp.LpInteger) for i in periods]
netInj_flags_2 = [pulp.LpVariable("NW_%s" % i, lowBound=0, upBound=1, cat=pulp.LpInteger) for i in periods]
netInj_vars_2 = [pulp.LpVariable("NW_%s" % i, lowBound=MAX_WITHDRAWAL_RATE, upBound=MAX_INJECTION_RATE/2, cat=pulp.LpInteger) for i in periods]
# ERROR on next line for objectives
gas_model += (
pulp.lpSum(
[netInj_flags_1[i]*netInj_vars_1[i]*-prices[i] + netInj_flags_2[i]*netInj_vars_2[i]*-prices[i] for i in periods]
), "profit")
# ERROR on next line for constraintsgas_model += [netInj_flags_1[i] + netInj_flags_2[i] == 1 for i in periods]stockLevel = INITIAL_STOCK_LEVEL
for i in periods:
stockLevel += netInj_flags_1[i]*netInj_vars_1[i] + netInj_flags_2[i]*netInj_vars_2[i]
gas_model += stockLevel >= 0
gas_model += stockLevel <= 1000
gas_model.solve()