Pokemon Team Optimization Using Mixed Integer Programming

Building a Pokemon team is fundamentally a massive combinatorial optimization problem.
As of the release of Pokemon Legends ZA, we have 1,025 unique Pokemon with 130 unique Mega and alternate forms. If you want a team that covers defensive weaknesses while maximizing offensive coverage, human intuition eventually hits a wall. But by translating the game’s 18x18 type matchup grid into a mathematical cost matrix, we can let an algorithm solve it for us.
The Math Behind the Monsters
How do you tell a machine to build a team of up to six Pokemon, ensuring the final team has at least one resistance to every single type and a super-effective counter to every type? You define it as a boolean constraint:
For the nerds: unfortunately, we don’t get the satisfaction of running this with a standard Linear Programming (LP) solver to get that sweet polynomial complexity. Because we’re looking for a clear boolean on whether a Pokemon is in our team (you can’t deploy 4/10ths of a Charizard), the search space we’re looking at is non-convex and can’t be solved by the simplex method.
You could technically set it up as an LP problem and count a Pokemon as “in” if the variable crosses a certain threshold, but that introduces a messy layer of hyperparameter tuning. Instead, we have to run this via Mixed Integer Programming (MIP).
The Solver in Action
Using javascript-lp-solver, I built an engine that ingests the entire Pokedex. To save processing time before the solver even runs, it filters out user-excluded categories (like Megas or Legendaries) to optimize the search space.
It then assigns binary variables to every Pokemon, maximizing for Base Stat Total while satisfying the strict type-coverage constraints. The result? A tool that bypasses human bias and instantly generates mathematically flawless teams.
🪧 INFO: Find the project online at https://pokemonmip.nathaniellamjohnson.com!
