Coal-Blend Optimizer
A vectorized genetic search for cheaper coke
- Year
- 2025
- Kind
- Models
- Status
- Finished
- Built at
- QED Analyticals
150x faster blend optimization
A genetic algorithm that finds the cheapest coal blend whose predicted coke still meets its targets. Scoring the whole population in one batched pass cut a run from 5 hours to under 2 minutes.
Coal is most of what coke costs, and every blend has to make coke that meets strength and reactivity targets. A genetic algorithm searches blends as integer shares that sum to 100, and tree-ensemble models predict each blend's coke CRI, CSR, ash and volatile matter. Fitness is cost plus penalties for weak coke. Scoring the whole population with matrix operations and one model call per generation, instead of one per blend, took a run from about 5 hours to under 2 minutes. Vendor test reports are read into the database by Gemini and approved by a person before use.
The problem
Coke for a blast furnace is made from a blend of several coals, and coal is most of what coke costs. Every coal brings its own ash, volatile matter and coking behaviour, and the finished coke has to meet strength and reactivity targets (CSR and CRI) that no simple average predicts. Choosing a blend was done with manual calculations and trial and error. This optimizer turns it into a search: a genetic algorithm proposes blends, and trained models predict the coke each one would make.
How it works
- 01
Encode a blend as shares that sum to 100
A blend is an integer vector with one entry per available coal, in 1% steps, always summing to exactly 100. Hard limits keep it physical: a minimum and maximum share for each category of coal, and a cap on how many coals one blend may use. A random blend is repaired by rounding and small ±1 adjustments until it fits.
- 02
Predict the coke before mixing anything
Models trained on past production predict the coke's CRI, CSR, ash and volatile matter from a blend's weighted coal properties, its category shares and derived indices such as a basicity index and log maximum fluidity. They are tree ensembles, a random forest, LightGBM and gradient boosting voting together, built with PyCaret.
- 03
Score the whole population in one pass
The original search called the models once per blend, and a run took about five hours. Now one matrix product turns the population's share matrix and the coal property table into weighted properties for every blend at once, costs and category shares are matrix-vector products, and each model runs once per generation on the whole population. A run scores about 50,000 blends in roughly 400 batched model calls instead of 200,000 single-row ones, and finishes in under two minutes.
- 04
Cost, plus penalties for weak coke
Fitness is the share-weighted cost of the coals plus a linear penalty when predicted CRI leaves its band, CSR falls below its minimum or ash rises above its maximum. Breaking a category limit adds a large constant. Keeping quality as a penalty rather than a wall lets the search pass through slightly-off blends on its way to good ones.
- 05
Evolve
Parents are picked by binary tournament, children mix their parents coal by coal with uniform crossover, and mutation moves a share from one coal to another, which keeps the total at 100 without any repair. Each generation 5% of the population is replaced with fresh random blends to keep the search from collapsing early. A run is 500 blends over 100 generations, and it returns the six best distinct blends.
- 06
Read vendor test reports automatically
Coal properties arrive as PDF test reports from vendors. Each page is converted to text and sent to Gemini with a JSON schema of about 60 fields, from oxides to coking indices and petrography. The validated record is saved as unapproved until a person checks it and promotes it to the master table the optimizer reads.
Results
- 150x
- faster: a run went from about 5 hours to under 2 minutes
- ~50,000
- blends scored per run, in about 400 batched model calls
- ~60
- fields extracted from each vendor test report
Decisions
Vectorize the scoring, not the whole algorithm
The time went into model calls, not into the genetic operators. Batching the population through the models gave the speedup, while selection and mutation stay as plain, readable loops.
Mutation as a share swap
Moving one percentage point from one coal to another keeps a blend valid by construction, so mutation never produces something that has to be repaired or thrown away.
Hard composition, soft quality
Category limits are physical and must hold, so breaking one is effectively fatal. Coke quality comes from model predictions, which carry error, so it is penalized in proportion to how far a blend misses rather than rejected outright.
A person approves extracted data
Vendor reports read by a language model go in unapproved. Nothing the optimizer uses comes from a PDF until someone has looked at it.