CBC vs CP-SAT: My Lineup Optimizer Got 8x Faster

Two months ago I wrote about CBC vs HiGHS on my staff scheduler, where swapping solvers turned a model that took minutes into one that took seconds. So when my daily fantasy lineup optimizer started feeling slow, I reached for the same fix — and HiGHS came back three times slower. This is the story of CBC vs CP-SAT on that model, why my own previous result did not transfer, and the failure mode I found on the way that was worse than being slow.

Continue reading “CBC vs CP-SAT: My Lineup Optimizer Got 8x Faster”

A Free NFL Lineup Optimizer for DraftKings and FanDuel

The NFL lineup optimizer is live. It is free, there is no account, no email, and no cap on how many lineups you can build. It works with DraftKings and FanDuel, and it hands you a CSV formatted for direct re-upload to whichever one you came from.

It is the football version of the baseball optimizer I put up in June, built on the same solver with a different set of rules on top.

NFL Lineup Optimizer rules screen showing QB stacking, bring-back, exposure cap, and cooldown settings

Continue reading “A Free NFL Lineup Optimizer for DraftKings and FanDuel”

Nine Named Ranges and a Macro Called alternate_qb

The football folder had twelve .xlsm files in it, all with the same file date because I had copied them off an old drive in one go. Windows was no help. The real dates were inside — every Office file carries its own modified timestamp in docProps/core.xml, and a spreadsheet is just a zip archive, so you can read it without opening Excel at all — which is how I tracked down the file that became this NFL lineup optimizer for DraftKings and FanDuel.

Eleven of them were from 2014 and 2015. One was from October 2021, had nineteen worksheets instead of five, and was called fanduel football 2021 fast.xlsm. That was the one worth porting.

Screenshot of the alternate_qb VBA macro from the original Excel workbook: eight named-range assignments shifting seventh_last_qb into eigth_last_qb and so on down to last_qb, then a loop over player_picked building a constraint string from every selected player whose position is QB.
The macro the post is named after — nine named ranges shuffled one slot along, and a constraint string built by walking the picked players. This is what the Python port replaced.
Continue reading “Nine Named Ranges and a Macro Called alternate_qb”

In Baseball You Stack a Team. In Football You Stack a Throw.

I have had a baseball lineup optimizer running on this site since June. Pointing it at football looked like a small job — swap ten roster slots for nine, swap a $50,000 cap for a $60,000 one, done. That part took an afternoon. The part that took actual thought was NFL DFS stacking: baseball and football are correlated in completely different ways, and correlation is the whole game.

In baseball, the correlation is sequential. Batters score in a chain: a single sets up the double that drives him in. That is why my MLB optimizer has a constraint forcing four hitters from one team into consecutive batting-order spots — 3-4-5-6, not 2-5-7-9. In football there is no batting order. The correlation is simultaneous, and it is much sharper.

NFL Lineup Optimizer site and player pool screen showing DraftKings salary CSV upload
Continue reading “In Baseball You Stack a Team. In Football You Stack a Throw.”

How Route Optimization Algorithms Actually Work

People hear “route optimization algorithm” and picture something exotic — a black box, maybe a little AI magic. It isn’t. Underneath every routing tool, mine included, is a decades-old idea from combinatorial search, dressed up with a few tricks to make it fast enough to run in your browser instead of overnight on a mainframe. I’ve spent twenty-plus years building these models for real fleets, and the algorithm part is the least mysterious piece of the whole system. Here’s what’s actually happening when you click “optimize.”

Continue reading “How Route Optimization Algorithms Actually Work”