Algorithm design
Implementing evolutionary operators that respect a hard constraint — every route must visit every city exactly once, which rules out the textbook way of combining two solutions.
The Traveling Salesperson Problem
A van must visit 42 cities, each exactly once, and return to where it started. Which order makes the trip shortest? That question is the Traveling Salesperson Problem, and there are 1.7 × 1049 possible answers — far too many for any computer to check.
This project finds a route within 1.9% of the proven shortest one, using a genetic algorithm: keep a pool of routes, let the short ones breed, repeat.
starting
A van has 42 stops to make and has to end up back at the depot. Which order should it visit them in to drive the fewest miles?
That question is called the Traveling Salesperson Problem, and it is famously hard — not because any single route is difficult to measure, but because there are so many of them. With 42 stops there are roughly 1.7 × 1049 possible routes. To put that number in perspective: if you could check a billion routes every second, and had started at the Big Bang, you would still have looked at almost none of them.
Nobody knows a method that reliably finds the single best route without effectively trying them all. So the practical goal changes from find the best to find something very good, quickly — which is exactly what real routing, scheduling and logistics software has to do every day.
This project does that with a genetic algorithm: start with a hundred random routes, keep the shortest ones, combine them to make "child" routes, occasionally introduce a random change, and repeat for a few hundred rounds. Good structure survives, bad structure dies out. Nothing in the program knows what a map is.
Implementing evolutionary operators that respect a hard constraint — every route must visit every city exactly once, which rules out the textbook way of combining two solutions.
The original results beat a mathematically proven optimum, which is impossible. Tracking that down to a single mistyped digit is the piece of work I am most pleased with.
The operator with the best single result was not the one most likely to produce a good result. Reporting reliability, not just the record, changes which one you would actually ship.
Rewriting the algorithm in another language is only useful if it behaves identically. I tested it against the original on 400 random inputs rather than assuming.