deb-python-pulp/examples/test3.py

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()