CYBERTEC Logo

Traveling Salesman problem with PostGIS and pgRouting

03.2021 / Category: / Tags: |

Last time, we experimented with lesser known PostGIS functions to extract areas of interest for sales. Now, let’s extend our example regarding catchment areas by optimizing trips within the area of interest we generated in our previous example, which is around Hamburg. Let’s ask the following question:
which order should we visit our major cities in so that we can optimize our trip’s costs?

This optimization problem is commonly known as the Traveling Salesman Problem (or TSP).

Apart from PostGIS, pgRouting will be used to tackle this challenge within PostgreSQL only. pgRouting is served as a PostgreSQL extension, which adds a lot of geospatial routing functionality on top of PostGIS.
I recommend you check out its online documentation, located at https://pgrouting.org/, to get an overview.



Figure 1 Area of interest around Hamburg / Figure 2 Area of interest around Hamburg, Zoom

This article is organized as follows:

  1. Dataset import
  2. Layer setup
  3. Extract shortest round trip
  4. Final thoughts and outlook

Dataset import

We will re-use osm files and datasets processed in my last blogpost, so first, please play through the blogpost sections involved. Subsequently, an intermediate table “tspPoints” must be created, which contains major cities and airports covered by our preferred area around Hamburg only (see the annex for ddl).
To solve TSP by utilizing our pgRouting functionality, we must generate a graph out of osm data. Different tools like osm2pgrouting or osm2po exist, which generate a routable graph from plain osm data. Due to limited memory resources on my development machine, I decided to give osm2po a try.

So then - let’s start. After downloading the latest osm2po release from https://osm2po.de/releases/,
we need to adapt its configuration, in order to generate the desired graph  as an sql file.
Please uncomment the following line in osm2po.config to accomplish this task.

Now we’re ready to generate our graph by executing

The outputted sql file can easily be imported to PostGIS by calling

the resulting graph table contains geometries for edges only (see annex for ddl). To generate source and target nodes too, let’s utilize pgr_createverticestable as follows:

Layer setup

Slowly, we’re getting closer 😊. Figure 3 to 5 represent our stacked layer setup on top of OpenStreetMap, which is based upon the following tables:

  • tspPoints contains intermediate stops
  • de_2po_4pgr stores graphs’ edge geometries
  • de_2po_4pgr_vertices persists graphs’ node geometries

Figure 3 Intermediate trip stops


Figure 4 Edges around Hamburg



Figure 5 Edges + nodes around Hamburg


Solving TSP

Now let’s ask pgRouting to solve our traveling salesmen problem by querying

This command results in the optimal order of intermediate stops (edges next to our cities) forming our trip. It’s worth pointing out that the optimal route (order) depends on the cost-matrix’s respective cost-function, which was defined to calculate the edge’s weights. In our case, the cost function is prescribed by osm2po and expressed as length/kmh.

To export the sequence of city names to pass through, the nodes returned by pgr_TSP must be joined back to tspPoints. Please consult the annex for this particular query extension. From figure 6 we now realize that the optimal route goes from Hamburg Airport to Kiel, Lübeck, Rostock and Hamburg before bringing us back to our airport.

Figure 6 Optimal order of stops

Final thought and outlook

This time, we took a quick look at pgRouting to solve a basic traveling salesman problem within PostGIS. Feel free to experiment with further cost functions and to move on to calculating detailed routes between cities by utilizing further pgRouting functions.

Annex

0 0 votes
Article Rating
Subscribe
Notify of
guest
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Сергей Бирюков
Сергей Бирюков
2 years ago

Do I need to somehow additionally process the tspPoints layer? I fully named all the tables as you have, but PGAdmin gives an error https://uploads.disquscdn.com/images/7ae15155930b085f6ee31166dfdf7931436077dc7cb0517b92807fa2e6446916.jpg

Florian Nadler
Florian Nadler
1 year ago

There is no need to further process tsppoints, just insert geometries representing your stops.

CYBERTEC Logo white
CYBERTEC PostgreSQL International GmbH
Römerstraße 19
2752 Wöllersdorf
Austria

+43 (0) 2622 93022-0
office@cybertec.at

Get the newest PostgreSQL Info & Tools


    This site is protected by reCAPTCHA and the Google Privacy Policy & Terms of Service apply.

    ©
    2024
    CYBERTEC PostgreSQL International GmbH
    phone-handsetmagnifiercrosscross-circle
    linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram