I’ve been playing around recently with some Travelling Salesperson Problems (TSP), and by extension some Vehicle Routing Problems (VRP). For example, when people come to visit Ottawa, are they being the most optimal with visiting a list of sites, that is, spending the least time or distance in their cars travelling between places? If their trip takes more than one day, does that change the order they see things?
They’d like to know that a) their daily routes are optimized, and b) their stops are optimized to the day. The first question is one of the typical TSP, and the second is a basic VRP. Instead of having, say, 3 vehicles running routes from a single starting point (like a hotel), there’s one vehicle running a route each of the 3 days of their visit.
So, we’ll start from a list of things to see, and go from there. First, we need to process the data and get it into a usable format
The list of museums is given as Name, Street Number, Street, City.
We’ll use the Google Maps Distance Matrix API to calculate the distance between each point. We can then optimize the route visiting each one offline before asking Google for the actual route.
We’ll stitch every part of the location frame together to give a list of places for Google. It does better without a place name. We can then feed this into our API URL creator. Note I add the API key, you’ll have to get your own:
But hold on. The free tier of the Google API only allows for a maximum of 25 origins or destinations at once. And a total of 100 elements per request (where elements = origins x destinations). And a total of 2500 elements in a day . We have to a) make a way to break up our requests, and b) prevent going over 2500/day. We can also only call
We’ll request in chunks:
Request
Origin
Destination
1
1:10
1:10
2
1:10
11:20
…
…
…
k
11:20
1:10
k+1
11:20
11:20
…
…
…
n
40:48
40:48
This gives us a set of requests, by which point we’ll have all of the distance matrices we need. Then we’ll sew them together for one giant matrix.
We can process the returned json with this function. It looks gnarly but will suffice until I rewrite with applys:
We can do this for all calculated request groups:
Time is given in seconds, and distance in meters. I had to hide the names of each place because they made the table too big. Note that these are not symmetrical, because sometimes there are one way streets or other limitations on routes.
Once we have everything available, in lists of matrices, we can stitch them into a majorly big matrix. Again, gnarly until rewritten with applys:
Now that we have the distance matrices, we can start the Travelling Salesperson Problem work with the R package TSP. More in the next post.