Vehicle Routing, End to End · Post 0
History and series map
On this page
Who this series is for
This series is for someone who wants to understand vehicle routing end to end and is starting from zero. You need to be comfortable reading a little Python. Everything else, from graphs to linear programming, is covered in five short primers.
Vehicle routing asks a plain question: given a fleet, a set of stops and a list of rules, which vehicle visits which stops, in what order? The simplest version, one vehicle and no rules, is the Traveling Salesman Problem (TSP). Almost every idea in routing was first tried on the TSP, so the series starts there and adds vehicles, capacities and time windows only once the methods are in place.
The series is concepts first. Code illustrates each idea, but it is not a solver tutorial: by the end you should be able to read a routing paper, judge a solver’s output and know which method fits which problem.
A short history of routing
Routing has a long research history, and almost every method in this series has a name and a date attached. The tables below give the milestones the series builds on, in four eras. The last column says where the series covers each one.
Before computers. The TSP was a puzzle about tours long before it was a computing problem.
| Year | Milestone | Who | Why it matters | Covered in |
|---|---|---|---|---|
| 1800s | Tours through graphs, including the 20-point tours of Hamilton’s Icosian Game | Hamilton, Kirkman | The underlying graph question: is there a cycle through every point? Its hardness returns in Post 2 | Post 2: Why is the TSP hard? |
| 1930 | The “messenger problem”: the shortest path through points whose distances are known | Menger | An early statement of the TSP as an optimization problem | This post |
The first exact methods, 1954–1972. Linear programming arrived, and with it the first proofs that a tour was optimal.
| Year | Milestone | Who | Why it matters | Covered in |
|---|---|---|---|---|
| 1954 | 49 US cities solved to proven optimality with cutting planes | Dantzig, Fulkerson, Johnson | The integer programming model still used today | Post 6: Integer programming formulations |
| 1956 | A nearest-neighbour tour, then repairs of crossing edges | Flood | An early improvement method: fix a complete tour instead of building a new one | Post 11: Neighborhoods and the 2-opt move |
| 1958 | The 2-opt “inversion” move | Croes | The basic move of local search | Post 11: Neighborhoods and the 2-opt move |
| 1959 | The truck dispatching problem: gasoline trucks from one terminal to many service stations | Dantzig, Ramser | The first vehicle routing problem | Post 32: From one tour to many routes |
| 1962 | Dynamic programming for the TSP | Held and Karp; Bellman | O(n²·2ⁿ), the best known worst-case time for about sixty years | Post 4: Dynamic programming: Held-Karp |
| 1964 | The savings algorithm | Clarke, Wright | The classic way to build routes for many vehicles | Post 33: VRP construction heuristics |
| 1965 | 3-opt | Lin | Deeper moves than 2-opt | Post 14: k-opt and Lin-Kernighan |
| 1970–71 | 1-tree lower bounds with Lagrangian penalties | Held, Karp | Strong bounds that prune search trees | Post 5: Branch and bound |
| 1972 | Hamiltonian cycle is NP-complete | Karp | Why no fast exact algorithm is expected | Post 2: Why is the TSP hard? |
Heuristics with structure, 1973–1992. Since exact methods could not scale, researchers built fast methods and studied how good they were.
| Year | Milestone | Who | Why it matters | Covered in |
|---|---|---|---|---|
| 1973 | Lin-Kernighan: moves of variable depth | Lin, Kernighan | The strongest TSP heuristic for over fifteen years | Post 14: k-opt and Lin-Kernighan |
| 1976 | A tour at most 1.5 times optimal, for distances that obey the triangle inequality | Christofides; independently Serdyukov | The best guarantee for decades | Post 10: Approximation algorithms |
| 1977 | Worst-case analysis of nearest neighbour and insertion | Rosenkrantz, Stearns, Lewis | How bad fast construction can get | Post 9: Construction heuristics |
| 1991 | TSPLIB, a shared library of test instances, including berlin52 | Reinelt | Results became comparable across papers | This post, below |
| 1991 | Large-step Markov chains: kick a local optimum with a double bridge, then search again | Martin, Otto, Felten | An early form of iterated local search, and its standard kick | Post 16: The ILS idea |
| 1992 | Neighbor lists and don’t-look bits | Bentley | Local search on million-city instances | Post 13: Making local search fast |
Records and open solvers, 2000–today. Implementations matured, and so did the records.
| Year | Milestone | Who | Why it matters | Covered in |
|---|---|---|---|---|
| 2000 | LKH, an implementation of Lin-Kernighan with 5-opt steps and α-nearness | Helsgaun | The strongest TSP heuristic code | Post 14: k-opt and Lin-Kernighan |
| 2006 | Concorde and all of TSPLIB solved, up to 85,900 cities | Applegate, Bixby, Chvátal, Cook | The exact TSP solver everyone measures against | Post 7: Branch-and-cut and Concorde |
| 2012 | Hybrid genetic search (HGS) | Vidal, Crainic, Gendreau, Lahrichi, Rei | A population method that matched or beat the best known solutions on every multi-depot and periodic VRP benchmark | Post 38: Hybrid Genetic Search (HGS) |
| 2017 | LKH-3: LKH extended to constrained TSPs and VRPs | Helsgaun | The TSP workhorse applied to vehicle routing | Post 14: k-opt and Lin-Kernighan |
| 2021 | Best tour for the 1,904,711-city World TSP, within 0.0471% of optimal | Helsgaun, with LKH | How close heuristics get at enormous scale | Post 14: k-opt and Lin-Kernighan |
| 2022 | HGS-CVRP: an open-source HGS with the SWAP* move | Vidal | A compact, readable state-of-the-art VRP code | Post 38: Hybrid Genetic Search (HGS) |
| 2024 | PyVRP, an open-source VRP solver package for Python | Wouda, Lan, Kool | The solver used for the code from Part 5 on | Post 40: How PyVRP’s ILS works |
| 2025 | A proven optimal walking tour through 81,998 bars in South Korea | Cook, Espinoza, Goycoolea, Helsgaun | Exact methods at a scale of tens of thousands of stops | Post 7: Branch-and-cut and Concorde |
Updated October 2026: two later events matter for the series. In January 2026, PyVRP 0.13 replaced its hybrid genetic search with iterated local search, which is why Part 5 uses it. And in October 2025, Yuichi Nagata’s genetic algorithm, seeded with Helsgaun’s 2021 tour, shortened the World TSP record by 44 metres.
Two patterns run through the tables. Exact and heuristic methods grew up together: the Korea proof started from a tour that LKH found, and Concorde proved nothing shorter exists. And the VRP inherited the TSP’s toolkit, move by move: the 2-opt, Or-opt and double-bridge ideas of Parts 4 and 5 reappear, adapted to many routes, in Part 7.
The series map
The series has 13 parts. Parts 1 to 7 form a chain: each post ends on something the method cannot do yet, and the next post fixes it. Parts 8 to 12 are reference parts you can read in any order once the chain is done.
flowchart TD
P0["Part 0: Start here"] --> P1["Part 1: The TSP"]
P1 --> P2["Part 2: Exact methods"]
P2 --> P3["Part 3: Fast first answers"]
P3 --> P4["Part 4: Local search"]
P4 --> P5["Part 5: Iterated local search"]
P5 --> P6["Part 6: The metaheuristic family"]
P6 --> P7["Part 7: From TSP to VRP"]
P7 --> R{"Reference parts, any order"}
R --> P8["Part 8: VRP variant atlas"]
R --> P9["Part 9: Objectives, uncertainty, scale"]
R --> P10["Part 10: Routing in the real world"]
R --> P11["Part 11: Evaluation and solvers"]
R --> P12["Part 12: The frontier"]Each part answers one question:
| Part | Question it answers | Posts |
|---|---|---|
| 0 Start here | What do I need before the first algorithm? | Post 0, Primers A–E, glossary |
| 1 The Traveling Salesman Problem | What is the problem, and why is it hard? | 1–3 |
| 2 Exact methods | How do you prove a tour is optimal, and when does that stop scaling? | 4–8 |
| 3 Fast first answers | How do you build a decent tour quickly, with or without a guarantee? | 9–10 |
| 4 Local search | How do you improve a tour with small changes, and where does that get stuck? | 11–15 |
| 5 Iterated local search on the TSP | How do you escape a local optimum without starting over? | 16–19 |
| 6 The metaheuristic family | What are the other ways to escape, and how do they compare with ILS? | 20–31 |
| 7 From TSP to VRP | What changes with many vehicles, capacities and time windows? | 32–40 |
| 8 The VRP variant atlas | What does each major variant change, and where does it appear? | 41–54 |
| 9 Objectives, uncertainty and scale | What if there are several goals, an uncertain future, or huge instances? | 55–58 |
| 10 Routing in the real world | What does it take to run routing in production? | 59–63 |
| 11 Evaluation and the solver landscape | How do you judge solvers fairly, and which exist? | 64–66 |
| 12 The frontier | What is still unsolved, and where is the field going? | 67–69 |
The running examples
Two instances appear in almost every post, so you can see each method’s effect on the same problem.
Eight stops for working by hand. Every hand-worked example uses these eight stops. Coordinates are in kilometres on a flat plane, and distances are straight lines, rounded to units of 100 m. The optimal tour is A-B-C-D-H-E-F-G-A, which costs 315: 31.5 km. Step through the diagram to see the stops and then that tour.
The eight stops and their optimal tour
Here are the distances between them. The outlined cells are the legs of the optimal tour, and the strip below adds them up.
Distances between the eight stops, with the optimal tour
| A | B | C | D | E | F | G | H | |
|---|---|---|---|---|---|---|---|---|
| A | · | 41 | 71 | 78 | 76 | 61 | 36 | 106 |
| B | 41 | · | 36 | 63 | 81 | 86 | 45 | 89 |
| C | 71 | 36 | · | 41 | 72 | 94 | 54 | 61 |
| D | 78 | 63 | 41 | · | 36 | 71 | 45 | 28 |
| E | 76 | 81 | 72 | 36 | · | 41 | 41 | 50 |
| F | 61 | 86 | 94 | 71 | 41 | · | 42 | 91 |
| G | 36 | 45 | 54 | 45 | 41 | 42 | · | 72 |
| H | 106 | 89 | 61 | 28 | 50 | 91 | 72 | · |
- A→B41Σ 41
- B→C36Σ 77
- C→D41Σ 118
- D→H28Σ 146
- H→E50Σ 196
- E→F41Σ 237
- F→G42Σ 279
- G→A36Σ 315
Total: 315 × 100 m
berlin52 for measuring. berlin52 is a set of 52 locations in Berlin from TSPLIB, Reinelt’s 1991 library of test instances. Its optimal tour length, 7,542, is known and proven, so every method can report its gap: how far above the optimum it lands. The results so far, as the series has reached them:
| Method | Post | Tour length | Gap |
|---|---|---|---|
| Nearest neighbour, from city 1 | 9 | 8,980 | 19.1% |
| Christofides | 10 | 8,595 | 14.0% |
| 2-opt, from the nearest-neighbour tour | 11 | 7,842 | 4.0% |
| 2-opt plus Or-opt | 12 | 7,749 | 2.7% |
| 3-opt | 14 | 7,741 | 2.6% |
| Simplified Lin-Kernighan | 14 | 7,542 from 39 of 52 starting cities | 0.0% at best |
| Iterated local search | 19 | 7,542 on all 100 random seeds | 0.0% |
Each row is the method of one post, run with that post’s script. The table will grow as the series moves on to vehicle routing, where the instances change but the habit stays: every result is reported against a known optimum or a stated bound.
Reading paths
You can read the series straight through. If you already know some of it, one of these paths may suit you better.
| If you are… | Read | Skip or skim |
|---|---|---|
| New to all of this | Primers A and B, then Parts 1 to 7 in order; pick up Primers C and D when a post asks for them | Nothing |
| An engineer who needs VRP in production | Post 1, Part 3, Part 4, Post 16, Part 7, then Part 10 | Part 2 beyond Post 5; most of Part 6 |
| Interested in algorithms and proofs | Parts 1 to 3 in full, Post 14, Post 15, Posts 26 and 27, Post 39, Part 12 | Part 10 |
| Already fluent in the TSP | This post’s history, then Part 5 and Part 7 | Parts 1 to 3 |
Wherever you start, each post’s “Read first” list names exactly what it builds on, with a one-line refresher of each.
How each post works
Every post in Parts 1 to 7 has the same sections, so you always know where to look:
- Read first: the earlier posts and primers it relies on, each with a one-line refresher, and the question the post answers.
- Intuition: the idea worked by hand on the eight stops, usually as a diagram you can step through.
- The formal idea: just enough math to make it precise, with every symbol defined.
- Common misconceptions: claims that sound right and are not.
- Code: up to Part 4, one short script in plain Python with no libraries, run on berlin52, and its output as a table. From Part 5 on, the same section shows how PyVRP and reinterpretcat/vrp implement the idea.
- Exercise: one small problem with a hint.
- What this method can’t do yet: the concrete limitation the next post fixes. In Part 6 this becomes a comparison with iterated local search instead.
Numbers are shown, not listed. Distances appear as heatmaps with the tour’s legs outlined, as in the matrix above. Moves appear as step-through diagrams in which removed edges are dashed and new ones are drawn thick. Every number in a post comes from running its code, and every historical claim is checked against a primary source.
References
- Menger, K. (1932). “Das Botenproblem.” In K. Menger (ed.), Ergebnisse eines Mathematischen Kolloquiums 2, Teubner, Leipzig, 11–12. Posed at a colloquium in Vienna on 5 February 1930.
- Dantzig, G., Fulkerson, R., and Johnson, S. (1954). “Solution of a Large-Scale Traveling-Salesman Problem.” Journal of the Operations Research Society of America 2(4): 393–410.
- Flood, M. M. (1956). “The Traveling-Salesman Problem.” Operations Research 4(1): 61–75.
- Croes, G. A. (1958). “A Method for Solving Traveling-Salesman Problems.” Operations Research 6(6): 791–812.
- Dantzig, G. B., and Ramser, J. H. (1959). “The Truck Dispatching Problem.” Management Science 6(1): 80–91.
- Bellman, R. (1962). “Dynamic Programming Treatment of the Travelling Salesman Problem.” Journal of the ACM 9(1): 61–63.
- Held, M., and Karp, R. M. (1962). “A Dynamic Programming Approach to Sequencing Problems.” Journal of the Society for Industrial and Applied Mathematics 10(1): 196–210.
- Clarke, G., and Wright, J. W. (1964). “Scheduling of Vehicles from a Central Depot to a Number of Delivery Points.” Operations Research 12(4): 568–581.
- Lin, S. (1965). “Computer Solutions of the Traveling Salesman Problem.” Bell System Technical Journal 44(10): 2245–2269.
- Held, M., and Karp, R. M. (1970). “The Traveling-Salesman Problem and Minimum Spanning Trees.” Operations Research 18(6): 1138–1162.
- Held, M., and Karp, R. M. (1971). “The Traveling-Salesman Problem and Minimum Spanning Trees: Part II.” Mathematical Programming 1(1): 6–25.
- Karp, R. M. (1972). “Reducibility Among Combinatorial Problems.” In R. E. Miller and J. W. Thatcher (eds.), Complexity of Computer Computations, Plenum, 85–103.
- Lin, S., and Kernighan, B. W. (1973). “An Effective Heuristic Algorithm for the Traveling-Salesman Problem.” Operations Research 21(2): 498–516.
- Christofides, N. (1976). “Worst-Case Analysis of a New Heuristic for the Travelling Salesman Problem.” Management Sciences Research Report 388, Carnegie-Mellon University.
- Serdyukov, A. I. (1978). “On some extremal walks in graphs.” Upravlyaemye Sistemy 17: 76–79 (in Russian; submitted 1976).
- Rosenkrantz, D. J., Stearns, R. E., and Lewis, P. M. (1977). “An Analysis of Several Heuristics for the Traveling Salesman Problem.” SIAM Journal on Computing 6(3): 563–581.
- Reinelt, G. (1991). “TSPLIB—A Traveling Salesman Problem Library.” ORSA Journal on Computing 3(4): 376–384.
- Martin, O., Otto, S. W., and Felten, E. W. (1991). “Large-Step Markov Chains for the Traveling Salesman Problem.” Complex Systems 5(3): 299–326.
- Bentley, J. L. (1992). “Fast Algorithms for Geometric Traveling Salesman Problems.” ORSA Journal on Computing 4(4): 387–411.
- Helsgaun, K. (2000). “An Effective Implementation of the Lin-Kernighan Traveling Salesman Heuristic.” European Journal of Operational Research 126(1): 106–130.
- Applegate, D. L., Bixby, R. E., Chvátal, V., and Cook, W. J. (2006). The Traveling Salesman Problem: A Computational Study. Princeton University Press.
- Vidal, T., Crainic, T. G., Gendreau, M., Lahrichi, N., and Rei, W. (2012). “A Hybrid Genetic Algorithm for Multidepot and Periodic Vehicle Routing Problems.” Operations Research 60(3): 611–624.
- Helsgaun, K. (2017). “An Extension of the Lin-Kernighan-Helsgaun TSP Solver for Constrained Traveling Salesman and Vehicle Routing Problems.” Technical report, Roskilde University.
- Vidal, T. (2022). “Hybrid Genetic Search for the CVRP: Open-Source Implementation and SWAP* Neighborhood.” Computers & Operations Research 140: 105643.
- Wouda, N. A., Lan, L., and Kool, W. (2024). “PyVRP: A High-Performance VRP Solver Package.” INFORMS Journal on Computing 36(4): 943–955. Release notes for version 0.13.0 (January 2026): https://github.com/PyVRP/PyVRP
- Cook, W., Espinoza, D., Goycoolea, M., and Helsgaun, K. (2025). “Korea TSPs.” University of Waterloo. https://www.math.uwaterloo.ca/tsp/korea/
- Cook, W., et al. “World TSP.” University of Waterloo. https://www.math.uwaterloo.ca/tsp/world/
- Cook, W. “History of the TSP.” University of Waterloo. https://www.math.uwaterloo.ca/tsp/history/