Ant colony optimisation applied to a seven-city travelling salesman problem: pheromone trails, a distance heuristic, evaporation, and deposits weighted by tour length — the whole metaheuristic in one short file, with a second variant that adds NumPy and seeded randomness.
Measured result
The list of transition weights is named probabilities and is never sampled — the next city is its argmax. With three ants pinned to fixed starting cities, the colony is deterministic and every iteration retraces the same three tours.
ant.py, select_next_city
Ants walking a graph leave pheromone in proportion to how good their tour was, and the trail evaporates. Repeat, and the colony converges on short routes without anything ever computing a route directly. It is a genuinely elegant idea and it fits in well under a hundred lines: the transition rule weighs pheromone against inverse distance with the usual two exponents, and the update evaporates every edge before depositing along each tour.
The short version builds the transition weights correctly — pheromone raised to alpha, inverse distance raised to beta — stores them in a list named probabilities, and then takes the argmax instead of sampling from them. Nothing normalises that list and nothing draws from it. Combined with three ants pinned to fixed starting cities, the run is deterministic: every iteration retraces the same three tours, and the pheromone update reinforces a decision that was never in doubt.
The second variant restores what the first is missing: proper probabilistic selection with a seeded generator, so the colony actually explores and the pheromone trail has something to bias. The pair is worth keeping side by side, because the gap between them is precisely the part of the algorithm that does the work.