#!/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()