Part 7 · Chapter 32

Unit Commitment

Economic dispatch assumes the machines are already turning; unit commitment decides which ones should be turning at all — a discrete choice taken hours in advance, against start-up costs that cannot be recovered and minimum run times that cannot be undone.

Electric Power Systems Prof. Mithun Mondal Reading time ≈ 50 min
i What you'll learn
  • Why commitment is a discrete problem while dispatch is a continuous one, and why that single difference changes the whole method of solution.
  • How a start-up cost is built from the heat needed to restore a cooled boiler, and the break-even downtime that decides between banking a unit and letting it cool.
  • What spinning reserve is, the two rules used to size it, and what each one costs.
  • Why minimum up and down times exist, and how they convert a set of independent hourly decisions into one coupled multi-period problem.
  • The priority-list method built on full-load average cost — fast, transparent, and demonstrably not optimal.
  • How dynamic programming reduces an astronomically large search to a table, worked end to end over four periods with minimum-up-time constraints enforced.
  • What mixed-integer programming adds, and why the commitment schedule fixes most of the cost that Chapter 31's dispatch then optimises at the margin.
Section 32-1

The Question Dispatch Cannot Answer

Example 3 of Chapter 31 ended with an awkward result. At a demand of \(110\) MW, unit 3 was pinned at its floor of \(30\) MW with an incremental cost of \(43.50\) Rs/MWh while the system price was only \(37.20\) Rs/MWh. Every megawatt that machine produced was costing more than a megawatt was worth. The dispatch calculation had no way to act on this, because the only instruction it can give a machine is a number between \(P_{\min}\) and \(P_{\max}\). It cannot say stop.

The instruction "stop" is a different kind of decision. It is discrete — a machine is either synchronised or it is not, with nothing in between — and it is irreversible on the time scale of dispatch, because a large thermal set cannot be brought back in minutes. That decision is unit commitment: given a forecast of the load over the next day or week, decide for each generating unit and each hour whether it should be running.

Chapter 30 explained why the question is unavoidable. The daily load curve of a real system swings between a night valley and an evening peak that may be twice as large. If enough plant is kept running to serve the peak, then through the night a great deal of capacity sits at its minimum output burning fuel to produce electricity nobody wants. If instead everything is shut down at night, the morning rise cannot be met, because boilers take hours to bring back. Between those two errors lies a schedule, and finding it is this chapter's subject.

🔑
The two problems compared
Dispatch chooses continuous outputs for a fixed set of running machines over one instant. Commitment chooses a discrete on/off pattern for all machines over many hours, and pays for the transitions between them.

The problems nest: every candidate commitment must be costed by running a dispatch inside it, hour by hour. A commitment program therefore solves thousands of dispatches, and Chapter 31 is a subroutine of Chapter 32.

Economic dispatch (Chapter 31)Unit commitment (this chapter)
Decision variablesContinuous \(P_i\)Binary \(u_i(t)\in\{0,1\}\), plus \(P_i(t)\)
Time horizonA single instant24 hours to one week, in periods of \(\tfrac12\) to 1 hour
Coupling between periodsNoneStart-up costs, minimum up/down times, ramp rates
Nature of the problemConvex, one optimumCombinatorial, many local optima
Solution methodEqual \(\lambda\); λ-iterationPriority list, dynamic programming, mixed-integer programming
Re-solved every2 to 5 minutesOnce a day, revised as the forecast changes
Where the money actually is. Example 1 of Chapter 31 found that optimal dispatch between two similar units saved fifty-six paise an hour. Committing one machine fewer overnight saves the whole of that machine's no-load cost — hundreds or thousands of rupees an hour. Dispatch fine-tunes; commitment decides. That is why a utility will accept an approximate dispatch and will not accept an approximate commitment.
Section 32-2

The Cost of Starting and Stopping

If starting a machine were free, commitment would collapse into a sequence of independent hourly decisions and there would be no chapter to write. It is not free. Bringing a large thermal set from cold to synchronised speed requires the boiler, drum, headers, steam pipework and turbine metal to be heated back to operating temperature, and every degree of that heating is paid for in fuel that produces no electricity. Alongside the fuel there is a crew cost, the auxiliary power drawn from the system while the unit is off-line, and the accelerated wear on thick-walled components from the thermal cycle itself.

The fuel component depends on how far the machine has cooled, which depends on how long it has been down. A boiler loses heat to its surroundings at a rate roughly proportional to the temperature difference, so its temperature decays exponentially towards ambient with a thermal time constant \(\alpha\) of some hours. The heat that must be put back in is correspondingly a saturating function of the downtime.

🔑
Start-up cost after cooling
\[ C_{\text{cold}}(t) \;=\; C_f\,H_c\left(1-e^{-t/\alpha}\right) \;+\; C_{\text{fixed}} \]

\(t\) is the time the unit has been down, \(\alpha\) the boiler's cooling time constant, \(H_c\) the heat needed for a start from fully cold, \(C_f\) the fuel price and \(C_{\text{fixed}}\) the crew and auxiliary cost. For \(t\ll\alpha\) the cost is nearly proportional to \(t\); for \(t\gg\alpha\) it saturates at the full cold-start value.

The alternative to letting the unit cool is to bank it: keep the boiler warm with a small fire, or with steam bled from a running unit, so that no reheating is needed when the machine is called back. Banking consumes fuel at a steady rate \(H_b\) per hour for as long as it continues, so its cost grows linearly with the downtime:

Cost of banking
\[ C_{\text{bank}}(t) \;=\; C_f\,H_b\,t \;+\; C_{\text{fixed}} \]

One curve saturates, the other does not, so they cross exactly once. Below the crossing banking is cheaper; above it, cooling is. The crossing time is the practical rule of thumb an operator carries in his head, and for a large coal-fired set it typically falls somewhere between eight and fifteen hours — which is to say, right in the middle of the overnight valley. Example 2 computes one.

downtime t (h) cost (Rs) 4 8 12 16 24 500 1000 1500 break-even ≈ 12 h cooling (saturates) banking (linear) bank let it cool
Banking against cooling — one curve is linear, the other saturates, so they cross once

A shut-down cost is charged in the same way against the reverse transition. It is usually much the smaller of the two — the boiler must be taken off load in a controlled manner, purged and put on standby, the crew must be present, and some fuel is burnt in the process — and many textbook formulations set it to zero. It matters in the same way start-up cost matters: it is a fixed charge attached to a transition rather than to a state, and any charge of that kind couples the periods together.

That coupling is the whole difficulty. In dispatch, hour 14 has nothing to do with hour 13. Here a decision to shut a unit at midnight is only sensible if one knows what will be asked of the system at six in the morning, because the cost of the decision is not paid at midnight but at six.

Section 32-3

Spinning Reserve and the Security Constraint

Suppose the commitment problem were solved on cost alone. The answer would commit exactly enough capacity to meet the forecast load and not one megawatt more, and the system would fail on the first occasion a generator tripped, a line was lost, or the forecast was ten per cent low. The commitment must therefore carry a margin, and because that margin must be usable in seconds, it must be spinning.

🔑
Definition
\[ \text{Spinning reserve at time }t \;=\; \sum_{i\,\text{committed}} P_{i,\max} \;-\; P_D(t) \]

It is the unloaded capacity of machines that are already synchronised, governed and able to respond immediately. Capacity that is available but not running — a gas turbine that needs ten minutes to start, a hydro set on standby — is non-spinning or supplemental reserve, and it cannot substitute for spinning reserve on the time scale of a sudden loss.

Two rules are in common use for sizing it, and they are not equivalent.

The percentage rule requires the reserve to be a fixed fraction — commonly \(5\) to \(10\) per cent — of the forecast demand. It is simple, it scales with the size of the system and it is easy to write into a commitment program as a linear constraint. Its weakness is that it takes no account of what the system is actually exposed to: a system with one very large machine and many small ones is far more vulnerable than the percentage suggests.

The largest-unit rule, also called the \(N-1\) criterion, requires the reserve to be at least equal to the capacity of the single largest committed unit, so that the system survives losing it. This is the criterion that grid codes generally impose, and it is the one that connects to Chapters 27 to 29: the sudden loss of a generator is precisely the disturbance whose swing equation and equal-area analysis those chapters studied, and the reserve is what stops the frequency excursion before load shedding is required. Chapter 33 will show how governor droop and automatic generation control convert that reserve into actual megawatts within seconds.

Reserve is not free, and its cost is exactly the point of tension in commitment. Carrying reserve means committing capacity beyond what the load requires, which means either running an extra machine at its minimum output or backing off cheaper machines below their most efficient loading. Both raise the fuel bill. Example 4 measures the price of the \(N-1\) rule on a small system and finds it substantial — which is the honest reason small isolated systems interconnect with their neighbours rather than carrying the reserve alone.

Reserve must also be deliverable. A megawatt of unloaded capacity behind a congested corridor is not reserve, because the network cannot carry it to where the loss occurred. Reserve must further be reachable: a unit's response is limited by its ramp rate, so only the megawatts it can produce within the required time count. Chapter 31's penalty factors and this chapter's reserve requirement are two faces of the same fact — the network is between the generator and the load, and it is never neutral.
Section 32-4

Minimum Up and Down Times

Even where the economics say a machine should be shut down for an hour and restarted, the machine may refuse. Thick-walled boiler drums, superheater headers and turbine rotors develop damaging thermal stresses when they are cycled, and their design life is quoted in a fixed number of start–stop cycles. To protect them, every unit carries two constraints written into its operating instructions.

The run-time constraints
\[ \text{minimum up time } t_i^{\text{up}}: \text{ once started, unit } i \text{ must run at least } t_i^{\text{up}} \text{ hours} \]
\[ \text{minimum down time } t_i^{\text{dn}}: \text{ once stopped, it must stay off at least } t_i^{\text{dn}} \text{ hours} \]

For a large coal-fired set both are measured in hours, often four to eight; for a gas turbine they may be under an hour. The values are not economic quantities — they come from the metallurgy — but they have a decisive economic consequence, because they remove whole schedules from consideration regardless of cost. The two constraints between them are the reason a good commitment cannot be assembled hour by hour: a decision taken now forecloses decisions several hours ahead.

The remaining constraints of a real commitment problem are listed here for completeness, since a student meeting the subject for the first time should know how much the classical treatment leaves out.

ConstraintStatementOrigin
Capacity balanceCommitted capacity \(\ge P_D(t) + R(t)\)Load must be met with reserve (Section 32-3)
Generation limits\(u_i(t)P_{i,\min}\le P_i(t)\le u_i(t)P_{i,\max}\)Boiler stability and machine rating (Chapter 31)
Minimum up / down time\(t^{\text{up}}_i\), \(t^{\text{dn}}_i\)Thermal stress on thick-walled components
Ramp rate\(|P_i(t)-P_i(t-1)|\le R_i\)Rate at which steam conditions can be changed safely
Crew constraintOnly so many units may be started at once at a stationOperators available to supervise a start
Must-run units\(u_i(t)=1\) alwaysVoltage support, contract, nuclear base load, network security
Fuel constraintsTotal fuel over the horizon boundedTake-or-pay gas contracts, coal stock, hydro reservoir energy
Emission constraintsTotal \(\mathrm{SO_2}\)/\(\mathrm{NO_x}\) over the horizon boundedStatutory limits on the station or the system

The hydro entry deserves a note. A reservoir hydro station has almost no fuel cost and almost no start-up cost, but it has a finite quantity of stored water. Its commitment problem is therefore not "is this hour worth the fuel?" but "is this hour the best of the twenty-four in which to spend the water?" — a scheduling problem coupled across the whole horizon by an energy constraint rather than by a transition cost. The combined problem is hydro-thermal coordination, and it uses the same dynamic-programming machinery developed in Section 32-7.

Section 32-5

How Large the Problem Really Is

It is worth pausing to count, because the size of the search space is the reason the rest of the chapter exists.

With \(N\) units, each period admits \(2^{N}\) on/off patterns, of which \(2^{N}-1\) are usable once the all-off case is discarded. Over \(T\) periods, with no constraints linking them, the number of possible schedules is

Size of the search space
\[ \left(2^{N}-1\right)^{T} \]
\[ N=5,\;T=24:\quad 31^{24}\approx 6\times10^{35}, \qquad N=20,\;T=24:\quad \left(1\,048\,575\right)^{24}\approx 3\times10^{144} \]

The second figure is for a small utility with twenty machines scheduling one day ahead. It exceeds the number of atoms in the observable universe by some sixty orders of magnitude, and each of those schedules would in principle require twenty-four economic dispatches to cost. Exhaustive enumeration is not slow; it is impossible, and no increase in computing speed will ever make it possible.

What makes the problem tractable is that the schedules are not independent. Three structural facts cut the space down.

Most combinations are infeasible in a given period: they cannot meet the load with reserve, or their minimum outputs exceed the load. Most of the survivors are obviously bad: any combination that commits an expensive machine while a cheaper one of the same size is idle can be discarded without computation. And, crucially, the problem has an optimal-substructure property — the cheapest way to arrive at a given commitment state at hour \(t\) does not depend on what happens after hour \(t\). The first two facts give the priority-list method of Section 32-6; the third gives the dynamic programming of Section 32-7.

Section 32-6

The Priority-List Method

The oldest practical method rests on one simple idea: rank the machines once, and commit them in that order as the load rises. Everything then reduces to choosing the ranking.

Incremental cost, the quantity that governed all of Chapter 31, is the wrong ranking criterion here. Incremental cost answers "what does the next megawatt from this machine cost?", which is the right question when the machine is already running. Commitment asks a different question — "what does it cost to run this whole machine?" — and the number that answers it is the full-load average production cost.

🔑
Ranking criterion
\[ \text{FLAC}_i \;=\; \frac{F_i(P_{i,\max})}{P_{i,\max}} \;=\; \frac{a_i}{P_{i,\max}} + b_i + c_iP_{i,\max} \qquad \text{Rs/MWh} \]

Section 31-2 showed that average and incremental cost coincide at the output of best efficiency. Ranking by full-load average cost therefore ranks machines by how cheaply they produce energy when used as they are meant to be used, and it correctly charges each machine for its no-load cost \(a_i\) — the very term that incremental cost throws away.

With the ranking fixed, the procedure is a loop over periods:

StepAction
1Compute FLAC for every unit and sort ascending. This is the priority list.
2For each period, commit units down the list until committed capacity \(\ge P_D(t)+R(t)\).
3Check the committed set's total minimum output does not exceed \(P_D(t)\); if it does, decommit from the bottom of the list.
4Enforce minimum up and down times by extending runs that are too short and suppressing shutdowns that are too early.
5Run an economic dispatch (Chapter 31) in every period to obtain the production cost.

The method's virtues are real. It runs in a fraction of a second, the answer can be explained to an operator in one sentence, and the resulting schedule is usually within a percent or two of optimal. Its defect is equally real, and it is a defect of principle rather than of accuracy: the priority list does not know that start-up costs exist. Deciding period by period, it will happily shut a unit down for one hour and restart it, because in that hour the unit is not needed. It compares the fuel saved during the hour against nothing at all.

The remedy is to compare the fuel saved by a shutdown against the cost of the restart that must follow. That is an easy calculation for a single unit over a single valley — Example 5 does it, and finds a break-even valley length of under three hours — but doing it consistently for many units whose decisions interact requires a method that optimises over the whole horizon at once.

Section 32-7

Dynamic Programming: Stages, States and the Recursion

Dynamic programming is the systematic exploitation of the third structural fact of Section 32-5. Set the problem out as a sequence of stages — one per scheduling period — with a set of admissible states at each stage. A state is a commitment pattern: which units are on. Moving from a state at stage \(k-1\) to a state at stage \(k\) is a transition, and it costs the start-up charges of the units that switch on plus the shut-down charges of those that switch off. Sitting in a state for a period costs the economic dispatch cost of that combination at that period's load.

The essential observation is this. Suppose the cheapest possible schedule ends at stage \(k\) in state \(x\). Then the portion of that schedule up to stage \(k\) must itself be the cheapest way of reaching state \(x\) at stage \(k\) — for if some cheaper way existed, substituting it would improve the whole schedule, contradicting optimality. This is Bellman's principle of optimality, and it means we never need to remember how we reached a state, only what it cost.

🔑
The forward dynamic programming recursion
\[ F_{\text{cum}}(k,x) \;=\; P_{\text{cost}}(k,x) \;+\; \min_{y\,\in\,\mathcal{S}(k-1)}\Big[\,S_{\,y\to x} \;+\; F_{\text{cum}}(k-1,y)\,\Big] \]

\(F_{\text{cum}}(k,x)\) is the least total cost of any schedule that reaches state \(x\) at stage \(k\); \(P_{\text{cost}}(k,x)\) is the economic dispatch cost of combination \(x\) at the load of period \(k\); \(S_{y\to x}\) is the transition cost. The minimisation runs over the states \(y\) admissible at stage \(k-1\) from which \(x\) can legally be reached.

Two features of the recursion carry all its power. First, the amount of work is proportional to \(T\times X^{2}\), where \(X\) is the number of states retained per stage — not to \(X^{T}\). With four periods and three states that is thirty-six transition evaluations instead of eighty-one whole schedules; with twenty-four periods and fifty states it is sixty thousand evaluations instead of a number with forty-one digits. Second, at every stage each state needs only two things stored: its cumulative cost, and a pointer to the predecessor that achieved it. Following those pointers back from the cheapest final state recovers the optimal schedule. That backward walk is called the trace-back.

Constraints enter in two distinct ways, and confusing them is the commonest error in setting up a DP.

A constraint that depends only on the present period — the load must be met, the reserve must be carried, the committed minimum outputs must not exceed the load — is enforced by excluding states. A combination that fails it simply does not appear at that stage.

A constraint that depends on history — a minimum up time, a minimum down time, a limit on starts per shift — cannot be handled that way, because two schedules arriving at the same commitment pattern may have different futures available to them. Bellman's principle then fails for the naive state definition. The repair is to augment the state: carry, along with the on/off pattern, however much of the history the constraints need — typically the number of periods each recently switched unit has been on or off. With the augmented state the principle holds again, and the recursion is unchanged. Section 32-8 does exactly this, and the augmentation turns out to cost only one extra state.

One further economy is standard. Rather than admitting all \(2^{N}-1\) combinations at each stage, retain only the combinations that appear in the priority list of Section 32-6, optionally with a few neighbours of each. This restricts the DP to a corridor around a schedule already known to be good, reduces \(X\) from thousands to a handful, and in practice loses nothing — the optimum almost never lies far from the priority list. The price is that optimality is now guaranteed only within the retained set, which is the standard bargain of a heuristic search.

Section 32-8

A Worked Four-Period Schedule

The method is best learnt by executing it once completely. Three units are available, with costs in Rs/h and outputs in MW:

UnitFuel cost \(F_i(P_i)\) Rs/h\(P_{\min}\)\(P_{\max}\)FLAC (Rs/MWh)Start-up (Rs)Min up / down (h)
1\(200+9.0P_1+0.005P_1^{2}\)4020011.00must-run
2\(150+9.6P_2+0.008P_2^{2}\)3015011.803502 / 2
3\(100+10.4P_3+0.012P_3^{2}\)2010012.602002 / 2

The full-load average costs are computed as in Section 32-6; for unit 1, \(F_1(200)/200 = 2200/200 = 11.00\) Rs/MWh, and similarly \(1770/150 = 11.80\) and \(1260/100 = 12.60\). The priority order is therefore \(1,\,2,\,3\), and following Section 32-7 we retain only the three priority-ordered combinations

Retained states
\[ A=\{1\}:\;40\text{–}200\ \text{MW}, \qquad B=\{1,2\}:\;70\text{–}350\ \text{MW}, \qquad C=\{1,2,3\}:\;90\text{–}450\ \text{MW} \]

The load over four one-hour periods is \(150\), \(300\), \(400\) and \(250\) MW, and a spinning reserve of \(10\) per cent of load is required. Unit 1 is on at the start, units 2 and 3 have been off long enough to satisfy their minimum down times. Shut-down costs are taken as zero; a non-zero value would simply be added to every on-to-off transition in the same way start-up is added to every off-to-on one.

Step 1 — admissible states. A state is admissible in a period if its capacity covers the load plus reserve and its combined minimum output does not exceed the load. At \(150\) MW, \(A\) gives \(200\ge165\) and admits; \(B\) and \(C\) also admit. At \(300\) MW, \(A\) is out on capacity (\(200<330\)). At \(400\) MW, \(B\) is out (\(350<440\)), leaving only \(C\). At \(250\) MW both \(B\) and \(C\) admit.

Step 2 — production costs. Each admissible pair of state and load is costed by an economic dispatch exactly as in Chapter 31. Two of these entries are instructive. At \(300\) MW with \(B\) committed, equating incremental costs gives \(P_1 = 207.7\) MW, above unit 1's ceiling, so unit 1 clamps at \(200\) MW and unit 2 takes \(100\) MW. At \(400\) MW with \(C\) committed, unit 1 again clamps at \(200\) MW and the remaining \(200\) MW splits between units 2 and 3 at equal incremental cost, giving \(140\) and \(60\) MW. Example 3 works this entry through in full.

State150 MW250 MW300 MW400 MW
\(A=\{1\}\)1662.50
\(B=\{1,2\}\)1796.922843.083390.00
\(C=\{1,2,3\}\)1908.002941.723481.634618.00

Step 3 — the state augmentation. Unit 3's minimum up time of two hours means that a state in which unit 3 has just started is not the same as one in which it has been running. Split \(C\) accordingly into \(C_1\) (unit 3 up for one period, may not shut down next) and \(C_2\) (unit 3 up for two or more periods, free to shut down). Unit 2, as will be seen, runs continuously from the moment it starts, so it needs no augmentation.

Step 4 — the forward recursion. Apply \(F_{\text{cum}}(k,x) = P_{\text{cost}}(k,x)+\min_y\left[S_{y\to x}+F_{\text{cum}}(k-1,y)\right]\) stage by stage. The initial state has unit 1 on and units 2 and 3 off, with zero accumulated cost.

Stage 1 — load 150 MW
\[ F(1,A) = 1662.50 + 0 = 1662.50 \]
\[ F(1,B) = 1796.92 + 350 = 2146.92 \]
\[ F(1,C_1) = 1908.00 + (350+200) = 2458.00 \]
Stage 2 — load 300 MW (states B and C only)
\[ F(2,B) = 3390.00 + \min\{\underbrace{1662.50+350}_{\text{from }A},\;\underbrace{2146.92+0}_{\text{from }B}\} = 3390.00+2012.50 = 5402.50 \;\;[\text{from }A] \]
\[ F(2,C_1) = 3481.63 + \min\{\underbrace{1662.50+550}_{\text{from }A},\;\underbrace{2146.92+200}_{\text{from }B}\} = 3481.63+2212.50 = 5694.13 \;\;[\text{from }A] \]
\[ F(2,C_2) = 3481.63 + \underbrace{\left(2458.00+0\right)}_{\text{from }C_1\text{, unit 3 continues}} = 5939.63 \]

Note why \(C_1\) at stage 1 cannot lead to \(B\) at stage 2: shutting unit 3 down after a single hour would violate its minimum up time, so that transition is simply not offered to the minimisation. This is the augmentation doing its work.

Stage 3 — load 400 MW (state C only)
\[ F(3,C_1) = 4618.00 + \underbrace{\left(5402.50+200\right)}_{\text{from }B,\text{ unit 3 starts}} = 10\,220.50 \]
\[ F(3,C_2) = 4618.00 + \min\{\underbrace{5694.13}_{\text{from }C_1},\;\underbrace{5939.63}_{\text{from }C_2}\} = 4618.00+5694.13 = 10\,312.13 \;\;[\text{from }C_1] \]
Stage 4 — load 250 MW
\[ F(4,B) = 2843.08 + \underbrace{10\,312.13}_{\text{from }C_2\text{ only — }C_1\text{ may not shut down}} = 13\,155.21 \]
\[ F(4,C_2) = 2941.72 + \min\{\underbrace{10\,220.50}_{\text{from }C_1},\;\underbrace{10\,312.13}_{\text{from }C_2}\} = 13\,162.22 \]
🔑
Result of the trace-back
\[ \min\{13\,155.21,\;13\,162.22\} = 13\,155.21\ \text{Rs} \quad\text{at state } B, \qquad\text{schedule } A \to C \to C \to B \]

Unit 1 runs throughout. Unit 2 starts at the beginning of hour 2 and runs to the end. Unit 3 starts at the beginning of hour 2, runs hours 2 and 3 — exactly its minimum up time — and shuts down for hour 4.

0 A B C B C C B C 1662.5 2146.9 2458.0 5402.5 5694.1 10220.5 13155.2 13162.2 h1 · 150 h2 · 300 h3 · 400 h4 · 250
The dynamic programming trellis — the bold path is the optimal commitment

Compare this with what the priority list of Section 32-6 would have produced. Committing by load alone gives \(A\) at \(150\) MW, \(B\) at \(300\) MW, \(C\) at \(400\) MW and \(B\) again at \(250\) MW — the sequence \(A\to B\to C\to B\), which costs \(12\,513.58\) in production plus \(550\) in start-ups, or \(13\,063.58\) Rs. That is cheaper than the dynamic programme's answer, and it is infeasible: unit 3 would run for a single hour, violating its minimum up time. Repairing the violation by keeping unit 3 on through hour 4 gives \(A\to B\to C\to C\) at \(13\,162.22\) Rs. The dynamic programme instead repairs it by starting unit 3 an hour early, at \(13\,155.21\) Rs.

ScheduleProduction (Rs)Start-ups (Rs)Total (Rs)Status
\(A\to B\to C\to B\)12 513.5855013 063.58Infeasible — unit 3 up 1 h
\(A\to B\to C\to C\)12 612.2255013 162.22Feasible — priority list repaired
\(A\to C\to C\to B\)12 605.2155013 155.21Optimal
\(A\to C\to C\to C\)12 703.8655013 253.86Feasible, dearer
\(B\to C\to C\to B\)12 739.6355013 289.63Feasible, dearer

The margin is \(7.01\) Rs over four hours, which on this toy system is negligible, and it would be dishonest to pretend otherwise. Two things about it are not negligible. The reason the dynamic programme wins is structural — it can pay a cost in hour 2 to unlock a saving in hour 4, and no period-by-period rule can ever do that. And the margin scales with the system: with fifty units, a hundred and sixty-eight half-hourly periods and start-up costs in lakhs of rupees, the same structural advantage is worth a fraction of a per cent of a very large fuel bill, which is why every serious utility computes the schedule and does not read it off a list.

The infeasible row deserves one last look, because it is a genuine lower bound. Relaxing the minimum-up-time constraint gave \(13\,063.58\) Rs; the constrained optimum is \(13\,155.21\) Rs. The difference of \(91.63\) Rs is the price of unit 3's metallurgy, and it happens to equal exactly the extra cost of running combination \(C\) rather than \(B\) at \(300\) MW — \(3481.63-3390.00\) — because that is the single change the optimum had to make. Relaxation bounds of this kind are the foundation of the Lagrangian relaxation and branch-and-bound methods of Section 32-9.

0 100 200 300 400 500 MW 150 MW 300 MW 400 MW 250 MW {1} {1,2,3} {1,2,3} {1,2} h1 h2 h3 h4 shaded strip above each bar = spinning reserve
The optimal commitment — committed capacity behind the load, reserve in the gap
Section 32-9

What Modern Practice Adds

Dynamic programming was the industry standard for three decades and remains the right way to learn the subject, because the recursion makes the structure of the problem visible. It has one weakness that eventually became decisive: the number of states grows exponentially with the number of units, so a full DP over fifty machines is as impossible as enumeration. Restricting the state set, as Section 32-8 did, controls the growth but surrenders the guarantee of optimality.

Lagrangian relaxation was the first escape. The constraint that couples the units — the system power balance in every period — is moved into the objective with a multiplier, exactly as \(\lambda\) was introduced in Chapter 31. What remains decomposes into \(N\) independent single-unit problems, each solved by a small dynamic programme in the unit's own on/off history, and the multipliers are then updated to drive the aggregate towards the load. The relaxed solution is a lower bound on the true optimum, and the gap between the bound and the best feasible schedule found is a genuine measure of how close the answer is — the first method able to say how good its own answer was.

Mixed-integer linear programming is what utilities and market operators use today. The commitment variables \(u_i(t)\in\{0,1\}\) and start-up indicators are declared as integers, the quadratic cost curves are replaced by piecewise-linear approximations, and all the constraints of Section 32-4 are written as linear inequalities. A branch-and-bound solver then explores the integer tree, using the linear relaxation at each node as a bound to prune whole subtrees. What changed the practice was not the formulation, which is old, but the arrival of solvers fast enough to close a large problem within the operational deadline.

Two extensions matter for the systems being built now, and both point forward in this book.

Security-constrained unit commitment adds the network. A load flow (Chapters 19 and 20) is run inside the commitment for the base case and for a list of credible contingencies, and line flow limits are enforced in each. The commitment must then not merely meet the load with reserve but do so in a pattern the network can carry, both intact and after any single outage. The penalty factors of Chapter 31 and the reserve requirement of Section 32-3 both appear as special cases of this larger statement.

Stochastic and reserve-aware commitment addresses the load forecast itself. A schedule built on a single forecast is exposed if the forecast is wrong, and with large wind and solar penetration the forecast error has become comparable to the load variation the schedule was designed for. Modern formulations commit against an ensemble of scenarios, or against explicit up- and down-reserve requirements derived from the forecast uncertainty, and they value flexibility — the ability to ramp — alongside energy. Chapter 39 returns to this when it takes up renewable integration.

The order of magnitude to remember. Optimal dispatch between similar units on one busbar saves fractions of a per cent of fuel cost. Loss coordination saves around one per cent. Good commitment saves several per cent, because it is the only one of the three that can remove a machine's no-load cost from the bill entirely. The chapters are presented in increasing order of difficulty and, not coincidentally, in increasing order of value.
Section 32-10

Worked Examples

1 Building a priority list

Problem. For the three units of Section 32-8, construct the priority list and the table of commitment against load, requiring a spinning reserve of \(10\) per cent of the load.

Solution. Evaluate each cost function at full load and divide by the rating:

Full-load average production cost
\[ \text{Unit 1: } \frac{200+9.0(200)+0.005(200)^{2}}{200} = \frac{200+1800+200}{200} = \frac{2200}{200} = 11.00\ \text{Rs/MWh} \]
\[ \text{Unit 2: } \frac{150+9.6(150)+0.008(150)^{2}}{150} = \frac{150+1440+180}{150} = \frac{1770}{150} = 11.80\ \text{Rs/MWh} \]
\[ \text{Unit 3: } \frac{100+10.4(100)+0.012(100)^{2}}{100} = \frac{100+1040+120}{100} = \frac{1260}{100} = 12.60\ \text{Rs/MWh} \]

The priority order is \(1,2,3\). Committing down the list until capacity reaches \(1.1P_D\):

Units committedCapacity (MW)Minimum output (MW)Load range served (MW)
12004040 – 181.8
1, 235070181.8 – 318.2
1, 2, 345090318.2 – 409.1

The upper end of each range is \(P_{\max}/1.1\) — capacity divided by the reserve factor — and the lower end of each range is the upper end of the one before. The minimum-output column must also be checked: committing all three units is impossible below \(90\) MW, since the three machines together cannot be turned down further, and the surplus would have to be dumped.

Note how the reserve requirement shrinks each unit's useful range. Without reserve, units 1 and 2 would cover up to \(350\) MW; with ten per cent reserve they cover only \(318\) MW, and the third machine must be started \(32\) MW earlier. That difference, multiplied across a system's whole plant list, is what spinning reserve actually costs.

2 Bank the boiler, or let it cool?

Problem. A thermal unit needs \(380\) heat units for a start from fully cold and loses heat with a time constant \(\alpha=4\) h. Banking consumes \(30\) heat units per hour. Fuel costs \(2.0\) Rs per heat unit, and crew and auxiliary costs are \(500\) Rs in either case. Find the downtime at which banking and cooling cost the same.

Solution. With \(C_fH_c = 2.0(380) = 760\) Rs and \(C_fH_b = 2.0(30) = 60\) Rs/h,

The two cost curves
\[ C_{\text{cold}}(t) = 760\left(1-e^{-t/4}\right)+500, \qquad C_{\text{bank}}(t) = 60t+500 \]
Downtime \(t\) (h)\(C_{\text{cold}}\) (Rs)\(C_{\text{bank}}\) (Rs)Cheaper policy
4980.4740.0Bank
81157.1980.0Bank
121222.21220.0Bank, marginally
161246.11460.0Cool
241258.11940.0Cool

Setting the fixed costs aside, the break-even satisfies \(760\left(1-e^{-t/4}\right) = 60t\). At \(t=12\) the left side is \(722.2\) and the right \(720.0\); at \(t=12.1\) they are \(723.1\) and \(726.0\). The crossing is at

Break-even downtime
\[ t^{*} \approx 12.0\ \text{h} \]

Below about twelve hours, bank the boiler; above it, let the unit cool. The result explains the shape of real operating practice. An overnight valley of eight or ten hours falls below the break-even, so units taken off in the evening peak-shoulder are banked and are cheap to bring back for the morning rise. A weekend shutdown of forty hours falls far above it, and there is no point banking — the machine is allowed to go cold, and its Monday start is budgeted as a full cold start.

3 One entry of the production cost table

Problem. For the units of Section 32-8, compute the economic dispatch cost of committing all three units at a load of \(400\) MW, and confirm the optimality conditions.

Solution. The incremental costs are \(9.0+0.01P_1\), \(9.6+0.016P_2\) and \(10.4+0.024P_3\) Rs/MWh. By the direct formula of Chapter 31,

Unconstrained solution
\[ \sum\frac{1}{2c_i} = 100+62.5+41.667 = 204.167, \qquad \sum\frac{b_i}{2c_i} = 900+600+433.33 = 1933.33 \]
\[ \lambda = \frac{400+1933.33}{204.167} = 11.4286\ \text{Rs/MWh}, \qquad P_1 = \frac{11.4286-9.0}{0.01} = 242.9\ \text{MW} \]

Unit 1 exceeds its ceiling of \(200\) MW, so clamp it there and redispatch the remaining \(200\) MW between units 2 and 3:

Reduced problem
\[ 9.6+0.016P_2 = 10.4+0.024P_3 \;\Longrightarrow\; P_2 = 50+1.5P_3, \qquad P_2+P_3 = 200 \]
\[ 2.5P_3 = 150 \;\Longrightarrow\; P_3 = 60\ \text{MW}, \quad P_2 = 140\ \text{MW}, \quad \lambda = 9.6+0.016(140) = 11.84\ \text{Rs/MWh} \]

Both lie inside their bands, and unit 3's incremental cost is \(10.4+0.024(60) = 11.84\) Rs/MWh — equal, as required. At its ceiling unit 1 has \(9.0+0.01(200) = 11.00\) Rs/MWh, which is less than \(\lambda\), satisfying the Kuhn–Tucker condition of Section 31-5. The costs are

Production cost of state C at 400 MW
\[ F_1 = 200+9.0(200)+0.005(200)^{2} = 2200.0 \]
\[ F_2 = 150+9.6(140)+0.008(140)^{2} = 150+1344.0+156.8 = 1650.8 \]
\[ F_3 = 100+10.4(60)+0.012(60)^{2} = 100+624.0+43.2 = 767.2 \]
\[ P_{\text{cost}} = 4618.0\ \text{Rs/h} \]

This single number is one cell of the table in Section 32-8. Every other cell is produced the same way, which is the sense in which economic dispatch is a subroutine of unit commitment — and, when the horizon runs to a week of half-hourly periods and the state set to a few dozen combinations, the reason a commitment program spends most of its time inside a dispatch routine.

4 The price of the \(N-1\) reserve criterion

Problem. Test the optimal schedule of Section 32-8 against the largest-unit reserve rule, in which the spinning reserve must at least equal the capacity of the largest committed unit. Where the rule is violated, state the shortfall and, where possible, the cheapest remedy.

Solution. Unit 1 at \(200\) MW is the largest machine and is committed in every period, so the requirement is \(200\) MW of reserve throughout.

HourLoad (MW)CommittedCapacity (MW)Reserve (MW)Required (MW)Shortfall (MW)
1150{1}20050200150
2300{1,2,3}45015020050
3400{1,2,3}45050200150
4250{1,2}350100200100

Only hour 4 can be repaired from within the system: committing unit 3 as well raises the capacity to \(450\) MW and the reserve to exactly \(200\) MW. The cost of doing so is the difference between the two production costs at \(250\) MW,

Cost of satisfying the rule in hour 4
\[ 2941.72 - 2843.08 = 98.64\ \text{Rs/h} \]

In hours 1, 2 and 3 no commitment satisfies the rule at all. In hour 3 the entire installed capacity is \(450\) MW against a load of \(400\) MW, so losing unit 1 leaves \(250\) MW of plant to serve \(400\) MW of load and \(150\) MW must be shed or imported. In hour 1 the position is worse in relative terms: unit 1 alone is carrying the whole load, and its loss is a total blackout.

The conclusion is not that the calculation has failed but that the system is too small to be self-sufficient, and the arithmetic says so precisely. An isolated system must either carry reserve that is a large fraction of its own peak — ruinously expensive — or interconnect, so that the reserve is shared across a pool in which no single machine is a large fraction of the total. This is the economic argument for interconnection that Chapter 2 introduced qualitatively, now with a number attached to it. It is also why the percentage rule and the largest-unit rule diverge so sharply on small systems and converge on large ones.

5 How long a valley justifies a shutdown

Problem. During an overnight valley the load falls to \(150\) MW, which unit 1 alone can carry. Using the data of Section 32-8, find the length of valley beyond which it pays to shut unit 2 down rather than keep it running at part load.

Solution. The two options are costed against each other hour by hour. Keeping unit 2 on means dispatching state \(B\) at \(150\) MW; shutting it down means dispatching state \(A\):

Hourly penalty for keeping unit 2 running
\[ \Delta = P_{\text{cost}}(B,150) - P_{\text{cost}}(A,150) = 1796.92 - 1662.50 = 134.42\ \text{Rs/h} \]

Shutting down and restarting costs \(350\) Rs once, regardless of the valley's length. Over a valley of \(n\) hours the two policies cost \(134.42n\) and \(350\) respectively, so the shutdown pays when

Break-even valley length
\[ 134.42\,n \;\gt\; 350 \quad\Longrightarrow\quad n \;\gt\; 2.60\ \text{hours} \]

A valley of two hours or less: keep unit 2 running. Three hours or more: shut it down. And since unit 2's minimum down time is two hours, the economics and the metallurgy happen to agree here — any valley long enough to justify the shutdown is also long enough to permit it. That agreement is a coincidence of these numbers, not a general rule, and where the two disagree the metallurgy always wins.

The calculation also shows why a priority list gets this wrong. Judged on hour 1 alone, state \(A\) is cheaper than state \(B\) by \(134.42\) Rs and the list would decommit unit 2 without hesitation. Only by looking ahead to the restart does the true comparison appear — which is the whole argument for Section 32-7.

6 The system incremental cost across the schedule

Problem. For the optimal schedule of Section 32-8, find the system incremental cost \(\lambda\) in each hour and compare it with the average cost of the day's energy.

Solution. Each hour's \(\lambda\) comes from the dispatch of that hour's committed set.

HourLoad (MW)CommittedDispatch (MW)\(\lambda\) (Rs/MWh)
1150{1}15010.50
2300{1,2,3}193.9 / 83.7 / 22.410.94
3400{1,2,3}200 / 140 / 6011.84
4250{1,2}176.9 / 73.110.77

The total energy is \(150+300+400+250 = 1100\) MWh and the total cost \(13\,155.21\) Rs, so the average cost is

Average against marginal
\[ \frac{13\,155.21}{1100} = 11.96\ \text{Rs/MWh}, \qquad \lambda \in [10.50,\;11.84]\ \text{Rs/MWh} \]

The average exceeds every hourly incremental cost. It must: the no-load costs \(a_i\) and the \(550\) Rs of start-ups are recovered in the average and are entirely invisible to the margin. Chapter 30's two-part tariff exists to collect exactly this difference, and Example 6 of Chapter 31 found the same gap before any start-up cost was even counted.

One subtlety in hour 2 rewards attention. Committing unit 3 there raises the hour's production cost from \(3390.00\) to \(3481.63\) Rs, yet it lowers the incremental cost, because without unit 3 the dispatch would push unit 1 to its ceiling and leave unit 2 setting the margin at \(11.20\) Rs/MWh, against \(10.94\) with unit 3 on. Total cost and marginal cost move in opposite directions across a change of commitment, and any argument that reasons from one to the other is unsound. This is the same trap that makes a priority list built on incremental cost give the wrong ranking — the reason Section 32-6 uses full-load average cost instead.

Review

Chapter Summary

Discrete, not continuous

Commitment chooses \(u_i(t)\in\{0,1\}\) over many hours; dispatch chooses \(P_i\) at one instant.

Start-up cost

\(C_fH_c(1-e^{-t/\alpha})+C_{\text{fixed}}\) saturates; banking rises linearly. They cross once.

Spinning reserve

Committed capacity minus load. Sized by a percentage of load or by the largest committed unit.

Run-time limits

Minimum up and down times come from thermal stress and couple the periods together.

Priority list

Rank by full-load average cost \(F_i(P_{i,\max})/P_{i,\max}\) and commit down the list. Fast, not optimal.

DP recursion

\(F_{\text{cum}}(k,x)=P_{\text{cost}}(k,x)+\min_y[S_{y\to x}+F_{\text{cum}}(k-1,y)]\), then trace back.

History constraints

Minimum up/down times need the state augmented with run-time counters, or Bellman's principle fails.

Look ahead

Only a whole-horizon method can pay a cost now to unlock a saving later — the priority list cannot.

Practice

Practice Problems

Problems 3 to 7 use the three units of Section 32-8. Set out every dynamic programme as a table of cumulative costs with a predecessor pointer beside each entry, and state explicitly which transitions the run-time constraints forbid.

  1. Three units have \(F_1 = 300+8.4P_1+0.0025P_1^{2}\) with \(100\le P_1\le 500\) MW, \(F_2 = 220+9.1P_2+0.0040P_2^{2}\) with \(60\le P_2\le 300\) MW and \(F_3 = 90+10.2P_3+0.0090P_3^{2}\) with \(30\le P_3\le 150\) MW. Construct the priority list and the table of load ranges served by each combination, first with no reserve requirement and then with a reserve of \(8\) per cent of load.
  2. A unit requires \(500\) heat units for a cold start, has a cooling time constant of \(5\) h and can be banked at \(45\) heat units per hour. Fuel costs \(1.8\) Rs per heat unit. Find the break-even downtime. Repeat for a time constant of \(10\) h and explain, physically, why the break-even moves the way it does.
  3. For the units of Section 32-8, tabulate the economic dispatch production cost of every admissible combination at loads of \(100\), \(200\), \(350\) and \(450\) MW. Identify every entry at which a generation limit is binding and verify the corresponding Kuhn–Tucker inequality.
  4. Re-solve the four-period commitment of Section 32-8 with unit 3's start-up cost raised to \(900\) Rs, everything else unchanged. Does the optimal schedule change? Explain the result by comparing the start-up charges paid on each candidate path.
  5. Re-solve the four-period commitment with the loads changed to \(150\), \(250\), \(400\) and \(150\) MW. Take care with the admissible states in the last period, and state which constraint decides the answer.
  6. Repeat the commitment of Section 32-8 with the spinning reserve requirement raised to \(15\) per cent of load. Show that state \(C\) no longer satisfies the requirement in hour 3, and state what a system operator's options then are.
  7. Using the schedule of Section 32-8, compute the total fuel cost, the total start-up cost and the average cost per MWh if unit 2 were declared must-run for all four hours. How much does that single operating restriction cost over the four hours?
  8. A system has \(N\) units and schedules \(T\) half-hourly periods. Write down the number of on/off patterns to be searched by exhaustive enumeration and by a dynamic programme that retains \(X\) states per stage. Evaluate both for \(N=12\), \(T=48\), \(X=15\), and comment on why the second number is a computation and the first is not.
Tip: every commitment answer should be checked against three things before its cost is believed. Add the committed capacities in each period and confirm they cover the load plus the required reserve. Add the committed minimum outputs and confirm they do not exceed the load — a schedule that must dump energy is not feasible. Then walk each unit's on/off string from left to right and count run lengths against its minimum up and down times. A schedule that fails any of these is not a cheap schedule, it is not a schedule at all, and a cost figure computed from it is meaningless.