Honglin Li
  • Research
  • Projects
  • Publications
  • Software
  • Teaching
  • Learn
  • Notes
  • CV
  • Journeys

On or off? Unit commitment as a mixed-integer program

Switch the gas plants on and off, grow a branch-and-bound tree, and see what the prices leave unpaid

Modeler lesson M2 of Energy Systems, Step by Step: give Prairie Town’s gas plants on/off switches, prove the cheapest schedule by branch and bound, and count what prices conditional on that schedule leave unpaid.
  1. Learn
  2. M2
  • Modeler · L3
  • 40 min guided · 45 min lab · about 90 min practice
  • After M1
  • Completed
  1. 1Step by step
  2. 2Explain
  3. 3Check
  4. 4Sources

The idea in one picture: the peaker's switch, 15:00 to 23:00, on 29 July 2025

The peaker's switch hour by hour. In the linear relaxation it sits between off and on: 0.05 at 17:00, 0.2 at 18:00, 0.55 at 19:00, 0.8 at 20:00, 0.45 at 21:00 and 0.2 at 22:00. In the mixed-integer program it is fully on from 17:00 to 22:00, six hours ending at 23:00, and off otherwise. 151617181920212223 RelaxationLP, 0 to 1 0.050.20.550.80.450.2 CommitmentMILP, 0 or 1 on in the six hours from 17:00 to 23:00
Model of the day Cost What it says
Dispatch LP (M1's model) $159,500 The peaker makes 5 MW at 17:00, below its 30 MW minimum.
Relaxation (switches 0 to 1) $168,975 The peaker is 5% on at 17:00: a lower bound, not a schedule.
Unit commitment (MILP) $173,200 Peaker on 17:00 to 22:00; proven by 5 branchings and 11 LPs; no duals.
Switches fixed, LP again $173,200 Conditional prices $40/MWh, and $100/MWh from 19:00 to 21:00; the peaker is $9,200 short of its costs.

With JavaScript on, you add the rules, set the peaker's switches yourself, grow the branch-and-bound tree and re-price the day with a real solver in your browser.

  • Data: demand, wind and solar follow 29 July 2025, the year's summer peak day on the Southwest Power Pool grid (EIA-930), scaled to the town as in lesson 0.
  • Illustrative: Prairie Town, its plants, their switching costs, minimum outputs and run times, and the $3,000/MWh unserved-energy penalty.
  • The day's ends: the combined-cycle plant is on before the day and must be on at 23:00; the peaker starts off. Run and down times count within this day only.
  • Hours: each is named by its start, so 17:00 is 17:00 to 18:00, and "17:00 to 22:00" is six hours, ending at 23:00.
  • Solver: HiGHS (open source), loaded on your first solve (about 3.5 MB, once).

Build it in Python · notebook lab, about 45 minutes, then 90 minutes of practice

The same model with scipy.optimize.milp and linprog(method="highs"); the notebook grows the same tree, and assert cells check every browser number.

  1. Download the notebook; the data are inside it.
  2. Upload it to Google Colab (File → Upload notebook), or open it locally with Python 3, NumPy and SciPy 1.9 or later.
  3. Run all cells, then try the practice questions at the end.

Notebook (.ipynb) Lesson data (JSON)

What you just did, as diagrams

Unit commitment
Which plants are on in each hour, decided together with how much each makes: on/off switches, start-up and no-load costs, minimum outputs and run times.
LP relaxation
The same model with every switch allowed between 0 and 1. Its cost, $168,975, is a lower bound; its schedule, a peaker 5% on, cannot be operated.
Branch and bound
Split a fractional switch into off and on, solve both, and prune any node whose bound cannot beat the best plan. Five branchings proved $173,200.
No shadow prices
HiGHS returns no duals for the mixed-integer solve. Demand added at 23:00 costs $40/MWh, then $3,000/MWh (unserved), then $40/MWh once the peaker stays on: a slope that falls, as no LP's can.
Conditional prices
Fix the switches and re-solve the LP: $40/MWh, and $100/MWh from 19:00 to 21:00, valid for this commitment only.
Uplift
At those prices the peaker is $9,200 short of its costs: start-up, no-load and hours at its minimum. Markets pay such gaps outside the price.
Go deeper · ModelerHow the bound climbs, and why formulations matter

The tree on this page branched only on the peaker’s switches. Each branching fixed one switch “on” and raised the best bound:

Node Fixed so far Bound
Root nothing $168,975
2 on at 19:00 $169,510
4 and 21:00 $169,735
6 and 18:00 $170,575
8 and 22:00 $171,415
10 and 17:00: every switch whole $173,200

The root gap was $4,225, or 2.4% of the best plan. A tighter formulation (other ways to write minimum run times, start-ups and ramps) can raise the relaxation’s bound and may shrink the search, though a tree’s size also depends on the solver’s choices; Knueven, Ostrowski and Watson (2020) compare many.

HiGHS adds presolve, cutting planes and heuristics to the same search. By default it stops once the gap is below 0.01% (mip_rel_gap = 0.0001, HiGHS options); here it reached 0%.

Go deeper · ModelerPrices when plants switch on and off

A dual is the slope of the best cost as one right-hand side changes. In a linear program that slope never falls as demand grows. With switches it can:

MWh added at 23:00 Each extra MWh costs What covers it
0 to 5 $40/MWh the combined-cycle plant, up to its 150 MW
5 to about 5.7 $3,000/MWh nothing: it is unserved
above about 5.7 $40/MWh the peaker, kept on at 30 MW

Keeping the peaker on at 23:00 costs $2,100 ($300 no-load, and 30 MWh at $100/MWh instead of $40/MWh), plus $40/MWh for each MWh added. Above about 5.7 MWh that is cheaper than unserved energy. The cost has no jump here, because demand may go unserved; its slope falls instead.

HiGHS returns no duals for the mixed-integer solve. Fixing the switches gives LP prices again, conditional on that commitment: $40/MWh at 23:00, the slope of the first 5 MWh only.

Fixing the switches and reading the LP’s duals is the starting point of O’Neill, Sotkiewicz, Hobbs, Rothkopf and Stewart (2005), who also price the fixed decisions themselves. FERC describes uplift payments as “the portion of the cost of reliably serving load that is not included in market prices” (Order No. 844, P 7, 2018).

The peaker at conditional prices $ for the day
Paid: 90 MWh at $40/MWh, 180 MWh at $100/MWh $21,600
Running cost: 270 MWh at $100/MWh $27,000
No-load: 6 hours at $300 an hour $1,800
One start $2,000
Short: the uplift $9,200

Other pricing rules have been proposed and used that fold part of these costs into the price, and so move money between plants and loads. Comparing them is a Researcher-tier question.

Go deeperWhat this model leaves out
  • The network: one bus here; M1 put the plants on three buses.
  • Ramp limits: M1's 40 MW/h rule for the combined-cycle plant is left out (practice question 3 adds it back).
  • Reserves: operators also commit spare headroom for a plant that trips.
  • Forecast errors and outages: the day is known in advance here. M8 decides before the uncertainty resolves.
  • Tomorrow and yesterday: the day ends with the combined-cycle plant on, run and down times count within the day (a start at 23:00 owes nothing after midnight), and the hours before it are assumed to meet them; real schedules roll forward.
  • Offers and market rules: costs stand in for offers; real settlements follow each market's tariff.

Modeler's note: M5 sizes a microgrid with a mixed-integer program, and the Modeler checkpoint CK-M asks you to formulate, solve and verify a model you have not seen.

Check yourself

Myth or fact? “A mixed-integer solver returns shadow prices, just like a linear-program solver.”

  • Myth
  • Fact
Answer

Myth. HiGHS returned no duals. And at 23:00 extra demand costs $40/MWh, then $3,000/MWh, then $40/MWh again once the peaker stays on: a falling slope, which no LP has.

Myth or fact? “Rounding the relaxation's switches to 0 or 1 gives a workable schedule.”

  • Myth
  • Fact
Answer

Myth. Here rounding keeps the peaker on only at 19:00 and 20:00 and leaves 90 MWh unserved.

Myth or fact? “A plant in the cheapest schedule can lose money at the conditional prices.”

  • Myth
  • Fact
Answer

Fact. The peaker is paid $21,600 against $30,800 of costs; the $9,200 gap needs an uplift payment.

A node of the tree has a bound of $171,415. Could some plan below that node cost $170,000?

  • Yes, if its switches are whole numbers
  • No: no plan below a node costs less than its bound
  • Only if some demand is unserved
  • It depends on the solver
Answer

No. Plans below a node only add rules to its relaxation, so none can cost less than $171,415.

The peaker's start-up cost doubles to $4,000; its switches stay on from 17:00 to 22:00. The conditional price at 20:00 then…

  • rises by $2,000/MWh
  • rises by about $333/MWh, a sixth of the extra cost
  • stays at $100/MWh, and the uplift rises by $2,000
  • falls
Answer

It stays at $100/MWh. With the switches fixed, a start-up cost is a constant: it moves no dual, so the uplift grows to $11,200.

Numbers, sources and what’s next

Numbers to remember

Number What it means Source
next 24 hours Operators decide which units are online in each hour, typically for the next day, minding minimum and maximum output and minimum run times. FERC Energy Primer (PDF), p. 55 · April 2020 edition
$168,975 ≤ $173,200 The relaxation's cost is a lower bound on the best schedule with whole switches. This lesson's model (illustrative)
$40, $3,000, $40 per MWh Demand added at 23:00, as it grows: the slope falls once the peaker stays on, which no LP's can. This lesson's model (illustrative)
$9,200 What the peaker is short at conditional prices: start-up, no-load and hours at its minimum. This lesson's model (illustrative)
0.01% HiGHS's default relative gap: below it, a mixed-integer solve counts as optimal. HiGHS options · checked 3 Nov 2026

Next

M3 · What should be built? Capacity expansion with representative periods, validated

Related lab: a SciPy/HiGHS notebook that rebuilds the model, grows the same tree and asserts the browser's numbers, about 45 minutes.

In the real world

Utilities, and day-ahead market software in regional markets, optimize which units to commit (FERC Energy Primer, p. 37), with many more units, a network and reserves. Uplift payments cover costs the prices miss.

  • Builds on: M1 (the dispatch LP and its duals), lesson 11 (a peaker with a minimum output) and lesson 0 (the plants).
  • Bridges: B1 and B3.
  • Open tools for larger models: PyPSA, Pyomo and JuMP.

Sources and further reading

  • FERC staff (2020). Energy Primer: A Handbook of Energy Market Basics (PDF), p. 55: day-ahead unit commitment.
  • FERC (2018). Order No. 844, Uplift Cost Allocation and Transparency in Markets Operated by Regional Transmission Organizations and Independent System Operators (PDF), 163 FERC ¶ 61,041, P 7.
  • O'Neill, R. P., Sotkiewicz, P. M., Hobbs, B. F., Rothkopf, M. H. and Stewart, W. R. (2005). Efficient market-clearing prices in markets with nonconvexities. European Journal of Operational Research 164(1), 269–285.
  • Knueven, B., Ostrowski, J. and Watson, J.-P. (2020). On Mixed-Integer Programming Formulations for the Unit Commitment Problem. INFORMS Journal on Computing.
  • EIA. Hourly Electric Grid Monitor (Form EIA-930): the Southwest Power Pool data behind the day.
  • HiGHS. Documentation of the open-source solver used in the page and, through SciPy, in the notebook.

Spotted an error, or stuck? Write to hlli@ksu.edu. Corrections are made in place and dated here.

Text licensed CC BY 4.0, code MIT: teachers and students may reuse and adapt it, with credit to Honglin Li.

© 2026 Honglin Li · Kansas State University · hlli@ksu.edu

 

Last updated: November 2026 · Built with Quarto