Implementing storage model optimisation with dependencies across time

326 views Asked by At

Trying to put together a simple linear optimisation problem that has dependencies across time. It is a storage model where there are inflows coming into a storage and it needs to release water to maximise the water * price revenue stream - storage levels are carried over to the next period. There is a maximum storage level and maximum release amount per period.

I have no idea how to implement the constraint and setting up of the storage parameter in PULP. See my attempt below:

EDIT: How do I implement these 2 constraints:
1. storage[t+1] == storage[t] + inflow[t] - release[t] + spill[t]
2. storage[T] == storage[0] (so that end storage = start storage)
3. storage < maximum storage level for all t

Also not sure if I need really 'spill' as a variable as that can be inferred from constraint (1).

startstorage = 30
maxstorage = 35
maxrelease = 15

data = pd.DataFrame(data={'inflow':[5,3,13,62,11,1,5,9,7,8],
                          'PRICES':[1,2,3,1,3,5,3,4,2,6]})

#do I need to initialise storage and set an upper bound on storage?
#storage = [0] * len(data)
#storage[0] = startstorage

prob = pulp.LpProblem("My LP Problem", pulp.LpMaximize)
release = pulp.LpVariable.dicts('release',data.index, lowBound=0, upBound = maxrelease, cat='Continuous')
spill = pulp.LpVariable.dicts('spill',data.index, lowBound=0, cat='Continuous')
prob += sum([release[t] * data['PRICES'][t] for t in data.index])
# constraint (1)
prob += [storage[t+1] == storage[t] + data['inflow'][t] - release[t] + spill[t] for t in data.index[:-1]]
# constraint (2)
prob += storage[-1:] == storage[0] 

prob.solve()

Hope this makes sense and thanks in advance!

1

There are 1 answers

0
sixpear On

I realised several rookie errors after reading through more examples. Here it is which achieves what I was after.

startstorage = 30
maxstorage = 35
maxrelease = 15

data = pd.DataFrame(data={'inflow':[5,3,13,62,11,1,5,9,7,8],'PRICES':[1,2,3,1,3,5,3,4,2,6]})

prob = pulp.LpProblem("My LP Problem", pulp.LpMaximize)
storage = pulp.LpVariable.dicts('storage',data.index, lowBound=0, upBound = maxstorage, cat='Continuous')
release = pulp.LpVariable.dicts('release',data.index, lowBound=0, upBound = maxrelease, cat='Continuous')
spill = pulp.LpVariable.dicts('spill',data.index, lowBound=0, cat='Continuous')
prob += lpSum([release[t] * data['PRICES'][t] for t in data.index])
for t in data.index[:-1]:
    prob += storage[t] + data['inflow'][t] - release[t] - spill[t] == storage[t+1]
prob += storage[0] == startstorage
prob += storage[9] == startstorage
prob.solve()