Aegean Placement
Twenty real Aegean ports, and the question of where to put a handful of supply depots among them. Asked two ways — and the difference between the two ways is the point.
Nothing here is computed on our side. The page loads a WebAssembly module, Go's runtime bridge and a packed coastline — three static files — and solves everything locally. There is no endpoint behind this page. Nothing on this page touches a chain.
One algorithm has a proof. The other does not.
Max-coverage — guaranteed
Serve as much population as possible within a radius of some depot. Coverage is monotone and submodular, so plain greedy is proven to return at least 63.2% of the true optimum — that is 1 − 1/e, and it is a worst case, known before the solver runs.
p-median — no guarantee
Minimize total weighted travel to the nearest depot. There is no approximation bound for the interchange heuristic that solves it. It is very good in practice and it is guaranteed nothing, and this page never calls its answer optimal.
Up to 4 depots the page also runs an exhaustive search and shows the true optimum beside the heuristic's answer, so you watch the bound hold rather than take our word for it. Past 4 the exhaustive search stops being cheap, and the page says the optimum was not computed rather than going quiet about it.
The map
Loading the solver…
The answer
- Heuristic
- —
- Exhaustive optimum
- —
- Gap
- —
- Work
- —
Depots: —
The ports
Every port below is a real place, and its weight is its population. Total demand across the 20 ports is 7980753.
| Port | Country | Population | Lat | Lon |
|---|---|---|---|---|
| Athens | Greece | 3242000 | 37.985 | 23.731 |
| İzmir | Turkey | 2587000 | 38.438 | 27.150 |
| Thessaloniki | Greece | 828000 | 40.698 | 22.883 |
| Piraeus | Greece | 466065 | 37.950 | 23.700 |
| Iraklio | Greece | 137154 | 35.325 | 25.130 |
| Volos | Greece | 110632 | 39.370 | 22.950 |
| Çanakkale | Turkey | 87791 | 40.146 | 26.406 |
| Hania | Greece | 78728 | 35.512 | 24.016 |
| Chalkida | Greece | 71842 | 38.464 | 23.612 |
| Kavala | Greece | 59240 | 40.941 | 24.402 |
| Rodos | Greece | 56969 | 36.441 | 28.223 |
| Katerini | Greece | 53293 | 40.272 | 22.502 |
| Alexandroupoli | Greece | 52979 | 40.849 | 25.874 |
| Lamia | Greece | 47246 | 38.899 | 22.434 |
| Mitilini | Greece | 29328 | 39.110 | 26.555 |
| Hios | Greece | 26891 | 38.368 | 26.136 |
| Kos | Greece | 19244 | 36.894 | 27.289 |
| Ermoupoli | Greece | 12260 | 37.450 | 24.933 |
| Sitia | Greece | 8833 | 35.200 | 26.099 |
| Polygyros | Greece | 5258 | 40.381 | 23.453 |
Where the data comes from
Coastline and ports are
Natural Earth 1:10m, public domain. The map is decimated with
Ramer-Douglas-Peucker at 0.002°, and that figure is read from the artifact's own
header rather than typed here. Ports are the populated places inside the crop that sit within
12 km of a coastline vertex — a computed filter, not a hand-picked list. Population is
Natural Earth's POP_MAX, used as the demand weight and nothing else: it is not a
claim about a port's throughput or a current census.
The crop stops at the Dardanelles. A box reaching far enough north for Kavala and Alexandroupoli also reaches over the strait and picks up Istanbul, which is not an Aegean port and has more people than the rest of the table combined — every depot would go there and the map would be one dot.
The solver is a separate public module: github.com/pigfox/aegean-solver. p-median interchange, lazy-greedy max-coverage and the distance model, with their own tests and 100% statement coverage. The bound is checked there against exhaustive search over 480 instances rather than cited.