I don't have maps, but I do have a script in R that can solve the TSP problem (within less than or equal to twice the optimal length of the tour). With a bit more effort (maybe I'll come back to it later), one could extend this to produce some maps/graphics. You can download the dataset that this script uses from OurAirports dot com. You can download R and Rstudio from CRAN and Posit, respectively, to execute the script. There are R online interpreters, but most likely they won't let you install the packages you need to run this script. You can lookup the theory behind the heurstic algorithms by reading the vignette for the TSP package on CRAN (just search CRAN TSP, click on the link, halfway down that ugly text page will be a thing called "vignette" that you can click on that will open a PDF that explains all the math and such).
Feel free to customize the filter to pick which airports you want to find the best route for. Calculating the distance matrix has quadratic space complexity, so you can eat up hundreds of gigabytes of RAM pretty quickly if you have more than say 10,000 airports in the list (I ran out of memory trying to do all airports in the U.S. anyways, and I have 64 Gigs; there are probably more efficient implementations for calculating the distance matrix, though they may not be compatible with the TSP package). Memory usage also scales based on the number of CPU cores you throw at the problem (each core has to have a copy of the data). By the way, the code will max out your CPU if you let it, so feel free to reduce the number of iterations (which may reduce how optimal the result is) or the number of CPUs to match your machine.
I can't post links yet, so below are screenshots, followed by the pasting of the code. In this example, I calculated the route of all open airports, balloonports, and heliports in Arkansas which have a GPS code (per the data source).
View attachment 115003
View attachment 115008
View attachment 115004
View attachment 115005
View attachment 115006
# install.packages(c("TSP", "dplyr", "data.table", "geosphere", "doParallel"))
library(TSP)
library(dplyr)
library(data.table)
library(geosphere)
library(doParallel)
iterations <- 100
numCores <- 16
registerDoParallel(cl = numCores)
airports <- fread("I'm not allowed to post links yet")
desired_airports <- airports %>% filter(type != "closed",
iso_country == "US",
iso_region == "US-AR",
ident != "",
gps_code != "")
distance_matrix <- as.matrix(distm(desired_airports %>% select(longitude_deg, latitude_deg))) / 1000 # convert meters to kilometers
rownames(distance_matrix) <- desired_airports$ident
colnames(distance_matrix) <- desired_airports$ident
methods <- c("nearest_insertion", "cheapest_insertion", "farthest_insertion", "arbitrary_insertion",
"nn", "repetitive_nn", "two_opt")
distTSP <- as.TSP(distance_matrix)
solutions <- lapply(methods, function(m) solve_TSP(distTSP, method = m, two_opt = T, rep = numCores*iterations))
stopImplicitCluster()
tour_lengths <- sapply(solutions, tour_length)
best_solution <- solutions[[which(tour_lengths == min(tour_lengths))]]
print(best_solution)
best_airport_route <- labels(best_solution)