123 lines
3.4 KiB
Python
123 lines
3.4 KiB
Python
#!/usr/bin/env python
|
|
# @(#) $Jeannot: test3.py,v 1.3 2004/03/20 17:06:54 js Exp $
|
|
|
|
# Deterministic generation planning using mixed integer linear programming.
|
|
|
|
# The goal is to minimise the cost of generation while satisfaying demand
|
|
# using a few thermal units and an hydro unit.
|
|
# The thermal units have a proportional cost and a startup cost.
|
|
# The hydro unit has an initial storage.
|
|
|
|
from pulp import *
|
|
from math import *
|
|
|
|
prob = LpProblem("test3", LpMinimize)
|
|
|
|
# The number of time steps
|
|
tmax = 9
|
|
# The number of thermal units
|
|
units = 5
|
|
# The minimum demand
|
|
dmin = 10.0
|
|
# The maximum demand
|
|
dmax = 150.0
|
|
# The maximum thermal production
|
|
tpmax = 150.0
|
|
# The maximum hydro production
|
|
hpmax = 100.0
|
|
# Initial hydro storage
|
|
sini = 50.0
|
|
|
|
# Time range
|
|
time = list(range(tmax))
|
|
# Time range (and one more step for the last state of plants)
|
|
xtime = list(range(tmax+1))
|
|
# Units range
|
|
unit = list(range(units))
|
|
# The demand
|
|
demand = [dmin+(dmax-dmin)*0.5 + 0.5*(dmax-dmin)*sin(4*t*2*3.1415/tmax) for t in time]
|
|
# Maximum output for the thermal units
|
|
pmax = [tpmax / units for i in unit]
|
|
# Minimum output for the thermal units
|
|
pmin = [tpmax / (units*3.0) for i in unit]
|
|
# Proportional cost of the thermal units
|
|
costs = [i+1 for i in unit]
|
|
# Startup cost of the thermal units.
|
|
startupcosts = [100*(i+1) for i in unit]
|
|
|
|
# Production variables for each time step and each thermal unit.
|
|
p = LpVariable.matrix("p", (time, unit), 0)
|
|
for t in time:
|
|
for i in unit:
|
|
p[t][i].upBound = pmax[i]
|
|
|
|
# State (started/stopped) variables for each time step and each thermal unit
|
|
d = LpVariable.matrix("d", (xtime, unit), 0, 1, LpInteger)
|
|
|
|
# Production constraint relative to the unit state (started/stoped)
|
|
for t in time:
|
|
for i in unit:
|
|
# If the unit is not started (d==0) then p<=0 else p<=pmax
|
|
prob += p[t][i] <= pmax[i]*d[t][i]
|
|
# If the unit is not started then p>=0 else p>= pmin
|
|
prob += p[t][i] >= pmin[i]*d[t][i]
|
|
|
|
# Startup variables: 1 if the unit will be started next time step
|
|
u = LpVariable.matrix("u", (time, unit), 0)
|
|
|
|
# Dynamic startup constraints
|
|
# Initialy, all groups are started
|
|
for t in time:
|
|
for i in unit:
|
|
# u>=1 if the unit is started next time step
|
|
prob += u[t][i] >= d[t+1][i] - d[t][i]
|
|
|
|
# Storage for the hydro plant (must not go below 0)
|
|
s = LpVariable.matrix("s", xtime, 0)
|
|
|
|
# Initial storage
|
|
s[0] = sini
|
|
|
|
# Hydro production
|
|
ph = [s[t]-s[t+1] for t in time]
|
|
for t in time:
|
|
# Must be positive (no pumping)
|
|
prob += ph[t] >= 0
|
|
# And lower than hpmax
|
|
prob += ph[t] <= hpmax
|
|
|
|
# Total production must equal demand
|
|
for t in time:
|
|
prob += demand[t] == lpSum(p[t]) + ph[t]
|
|
|
|
# Thermal production cost
|
|
ctp = lpSum([lpSum([p[t][i] for t in time])*costs[i] for i in unit])
|
|
# Startup costs
|
|
cts = lpSum([lpSum([u[t][i] for t in time])*startupcosts[i] for i in unit])
|
|
# The objective is the total cost
|
|
prob += ctp + cts
|
|
|
|
# Solve the problem
|
|
prob.solve()
|
|
|
|
print("Minimum total cost:", prob.objective.value())
|
|
|
|
# Print the results
|
|
print(" D S U ", end=' ')
|
|
for i in unit: print(" T%d " %i, end=' ')
|
|
print()
|
|
|
|
for t in time:
|
|
# Demand, hydro storage, hydro production
|
|
print("%5.1f" % demand[t], "%5.1f" % value(s[t]), "%5.1f" % value(ph[t]), end=' ')
|
|
for i in unit:
|
|
# Thermal production
|
|
print("%4.1f" % value(p[t][i]), end=' ')
|
|
# The state of the unit
|
|
if value(d[t][i]): print("+", end=' ')
|
|
else: print("-", end=' ')
|
|
# Wether the unit will be started
|
|
if value(u[t][i]): print("*", end=' ')
|
|
else: print(" ", end=' ')
|
|
print()
|