https://github.com/tuprolog/ortools-tsp-example
2P-Kt example binding Goodle OR-Tools via primitives to support resolution of the TSP
https://github.com/tuprolog/ortools-tsp-example
Last synced: about 2 months ago
JSON representation
2P-Kt example binding Goodle OR-Tools via primitives to support resolution of the TSP
- Host: GitHub
- URL: https://github.com/tuprolog/ortools-tsp-example
- Owner: tuProlog
- License: apache-2.0
- Created: 2020-12-27T10:32:22.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-12-15T05:10:17.000Z (over 2 years ago)
- Last Synced: 2025-12-27T13:15:26.243Z (6 months ago)
- Language: Kotlin
- Size: 66.4 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Travelling Salesman Problem (TSP) in 2P-Kt
Brief example showing how [Google's OR-Tools](https://developers.google.com/optimization) can exploited in Prolog, to solve the TSP problem. Our solution leverages the notion of __primitives__ from the [2P-Kt](https://github.com/tuProlog/2p-kt) Prolog implementation.
A standard Prolog solver can be extended with a predicate of the form:
```prolog
tsp(?SetOfCities, ?Circuit, ?Cost)
```
which enumerates all minimally-`Cost`ly `Circuit`s for any possible `SetOfCities`, provided that the Prolog solver's KB contains a number of `path/3` facts describing the undirected edges of a city graph, like, e.g.:
```prolog
path(city1, city2, cost12).
path(city2, city3, cost23).
path(city3, city1, cost31).
% etc...
```
To solve the TSP, 2P-Kt solvers treat Google OR-Tools solvers as producers of __streams__ of solutions, to be _lazily_ enumerated as part of a standard Prolog resolution strategy.
Thus, users as well may lazily consume solutions to the TSP, via backtracking.
Furthermore, the `tsp/3` predicate is fully relational, thus users may perform a wide range of queries.
For example, users may be willing to solve a particular instance of the TSP, involving e.g. cities `city1`, `city2`, and `city3`:
```prolog
tsp({city1, city2, city3}, Circuit, Cost), Circuit = [city2 | OtherCities].
```
The query above enumerates all the minimally-`Cost`ly `Circuit`s starting from `city2` and involving exactly those 3 cities.
Conversely, the following query
```prolog
tsp({city1, city2, city3, MoreCities}, Circuit, Cost), Circuit = [city2 | OtherCities].
```
enumerates all the the minimally-`Cost`ly `Circuit`s starting from `city2` and stepping through _at least_ 3 cities, namely `city1`, `city2`, and `city3`.
Finally, the general query
```prolog
tsp(Cities, Circuit, Cost).
```
enumerates all the the minimally-`Cost`ly `Circuit`s involving all non-empty subsets of cities mentioned in the KB.
## How to run the example
### Prerequisites
- JDK 11+
- \[Optionally\] Gradle 6.7+
- \[Alternatively\] Docker
### Walkthrough
1. Start a new command line Prolog interpreter by running
```bash
gradlew -q run --args="-T /path/to/your/map-theory.pl"`
```
for instance, you may use `./src/test/resource/mini-map.pl`
0. Alternatively, you may start the interpreter by simply running
```bash
gradlew -q run
```
and later _consult_ a graph theory via the query:
```prolog
consult('file:/path/to/your/map-theory.pl').
```
for instance, you may write
```prolog
consult('file:./src/test/resource/mini-map.pl').
```
0. Write your `.`-terminated Prolog query of the form `tsp(Cities, Circuit, Cost).` and press Enter
0. The first solution will appear: press ; and then Enter to show the next one
+ or just Enter to interrupt the solution stream and provide a new query
0. You may add new edges to the map graph by asserting new facts in the theory, e.g.:
```prolog
assert(path(city3, city4, cost34)).
```
0. Terminate the interpreter by querying `halt.`, or simply by pressing Ctrl+ D
### In case of issues, try using Docker
1. You may dockerify this demo on your own machine by running:
```bash
docker build . -t pikalab/demos:2p-kt-tsp
```
2. Then you may then start the dockerified interpreter by running:
```bash
docker run -it --rm pikalab/demos:2p-kt-tsp
```
(In presence of an Internet connection this step may also work without requiring the previous one, as the image `pikalab/demos:2p-kt-tsp` is publicly available on DockerHub)