PyPDTSP
Python wrapper for the Pickup-and-Delivery Traveling Salesman Problem (PDTSP)
solvers from vidalt/PDTSP — the
hybrid genetic search (pdphgs) and ruin-and-recreate (pdprr)
implementations accompanying Pacheco, Martinelli, Subramanian, Toffolo &
Vidal, "Exponential-size neighborhoods for the pickup-and-delivery
traveling salesman problem" (Transportation Science, 2022).
Status: alpha. The Python surface may change between minor releases.
Install
Prebuilt wheels for Linux (x86_64) and macOS (x86_64 + arm64):
pip install pdtsp
Windows is not yet supported by prebuilt wheels — Windows users (and
anyone on a platform without a wheel) install from source. That needs
CMake, a C++17 compiler, and Boost (program_options, filesystem,
system, regex):
# Debian/Ubuntu
sudo apt install cmake g++ libboost-program-options-dev libboost-filesystem-dev libboost-system-dev libboost-regex-dev
# macOS
brew install cmake boost
# Windows (MSVC + vcpkg)
vcpkg install boost-program-options boost-filesystem boost-system boost-regex --triplet x64-windows-static-md
# then in a Developer PowerShell:
$env:CMAKE_TOOLCHAIN_FILE = "C:/vcpkg/scripts/buildsystems/vcpkg.cmake"
pip install pdtsp # downloads sdist and builds from source
Quick start
from pdtsp import HGSSolver, HGSParameters
# Index 0 is the depot. Customers 1..4 form two pickup-delivery pairs:
# pickup 1 -> delivery 3
# pickup 2 -> delivery 4
data = {
"x_coordinates": [0.0, 1.0, 2.0, 1.0, 2.0],
"y_coordinates": [0.0, 1.0, 0.0, 0.0, 1.0],
"pickup_delivery_pairs": [(1, 3), (2, 4)],
}
result = HGSSolver(HGSParameters(time_limit=10, seed=42)).solve(data)
print(result.cost) # 4.65...
print(result.route) # [0, 1, 3, 2, 4, 0]
The Ruin & Recreate variant is a drop-in replacement:
from pdtsp import RRSolver, RRParameters
result = RRSolver(RRParameters(time_limit=10, fast=True)).solve(data)
Explicit distance matrix (Grubhub format)
When you have arbitrary integer distances (not Euclidean coordinates), use the matrix mode. Pickup/delivery pairs are implicit: odd indices are pickups, the following even index is the paired delivery.
data = {
"name": "demo",
"distance_matrix": [
[0, 10, 12, 15, 18],
[10, 0, 5, 7, 11],
[12, 5, 0, 6, 8],
[15, 7, 6, 0, 4],
[18, 11, 8, 4, 0],
],
}
result = HGSSolver(HGSParameters(time_limit=5)).solve(data)
Input shape reference
Coordinate mode
| Key | Type | Notes |
|---|---|---|
x_coordinates |
Sequence[float] |
Length N. Depot is index 0. |
y_coordinates |
Sequence[float] |
Same length and convention. |
pickup_delivery_pairs |
Sequence[tuple[int, int]] |
Each (pickup, delivery) uses indices in 1..N-1. Every customer must be in exactly one pair. |
Matrix mode (Grubhub)
| Key | Type | Notes |
|---|---|---|
distance_matrix |
Sequence[Sequence[float]] |
N × N integer (or rounded) distances. N - 1 must be even. |
name (optional) |
str |
Free-form instance label. Default pdtsp_grubhub. |
Parameter reference
HGSParameters mirrors pdphgs --help (defaults from upstream commit
451bc8a5):
| Field | Default | Upstream flag |
|---|---|---|
time_limit |
None (no limit) |
--time-limit |
it |
1_000_000 |
--it |
mu |
25 |
--mu |
lam |
40 |
--lambda |
div |
4000 |
--div |
nb_elite |
1 |
--nb-elite |
nb_close |
2 |
--nb-close |
neighborhoods |
"RELOCATE-2OPT-2KOPT-OROPT-4OPT-BS" |
--neighborhoods |
bs_k |
3 |
--bs-k |
or_k |
30 |
--or-k |
ratio_slow_nb |
1.0 |
--ratio-slow-nb |
seed |
0 |
--seed |
verbose |
False |
--verbose |
RRParameters mirrors pdprr --help:
| Field | Default | Upstream flag |
|---|---|---|
fast |
False |
--fast |
time_limit |
None (no limit) |
--time-limit |
it |
50_000 |
--it |
p_accept |
3.0 |
--p-accept |
c_rate |
0.99987571600000003 |
--c-rate |
seed |
0 |
--seed |
verbose |
False |
--verbose |
Result shape
solver.solve(data) returns a RoutingSolution:
| Field | Type | Notes |
|---|---|---|
cost |
float |
Best tour cost the solver reported. |
time |
float |
Solver's own wall-clock (not subprocess wall time). |
route |
list[int] |
Closed tour, starts and ends at depot index 0. |
raw |
dict|str |
Full parsed JSON (or raw stdout block if JSON parse failed). |
How it works
HGSSolver and RRSolver bundle the upstream native binaries (pdphgs
and pdprr) inside the package. Each solve() call:
- Validates the input dict.
- Writes a temporary
.PDTfile (coordinate mode) or matrix file (Grubhub mode). - Spawns the bundled binary via
subprocess.run. - Parses the JSON document the binary prints to stdout.
Subprocess isolation sidesteps upstream's module-level globals — multiple
solve() calls in the same Python process are safe.
Citing
@article{pacheco2022pdtsp,
title = {Exponential-Size Neighborhoods for the Pickup-and-Delivery
Traveling Salesman Problem},
author = {Pacheco, Toni and Martinelli, Rafael and Subramanian, Anand
and Toffolo, T{\'u}lio A. M. and Vidal, Thibaut},
journal = {Transportation Science},
year = {2022},
doi = {10.1287/trsc.2022.1170}
}
License
PyPDTSP is released under the MIT License. The bundled binaries
are compiled from the MIT-licensed vidalt/PDTSP
codebase (Copyright © 2022 Toni Pacheco) — see LICENSE for the upstream
attribution.
Metadata
Release files for pdtsp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pdtsp-0.1.0.tar.gz | 31.4 kB | With provenance | Details for pdtsp-0.1.0.tar.gz |
Built distributions (wheels)
Total release size: 115.9 MB
Release files / pdtsp-0.1.0.tar.gz
| Download URL | pdtsp-0.1.0.tar.gz |
|---|---|
| Size | 31.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
882bde1ceee9ed0a34aee2ea0aeb7145c517381f1b2804baab216f0ad63448b5
|
|
BLAKE2b-256 checksum How to use checksums |
c7b825a0b1f05bc39871d219c50e84a5e9e56a16870f7a210e77c38f06483147
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 19, 2026.
Transparency logRelease files / pdtsp-0.1.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pdtsp-0.1.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 13.5 MB |
| Tags | CPython 3.13 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
0ce09b42008c26112a11afd40d4e2c2eba539ec25d402991e993fd76cb93624a
|
|
BLAKE2b-256 checksum How to use checksums |
7542da3b5ee4506c698a470715d043551047cff62546f1f927f7f5a1a7b8808a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 19, 2026.
Transparency logRelease files / pdtsp-0.1.0-cp313-cp313-macosx_15_0_arm64.whl
| Download URL | pdtsp-0.1.0-cp313-cp313-macosx_15_0_arm64.whl |
|---|---|
| Size | 15.4 MB |
| Tags | CPython 3.13 macOS 15.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
7b4d40959cf6d9735615c864a5898cacff95883f93d7e445e8457093793be32e
|
|
BLAKE2b-256 checksum How to use checksums |
3981c2261232064f08fddcd28970dc67f4777cd931a24f76acf2732adb8203e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 19, 2026.
Transparency logRelease files / pdtsp-0.1.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pdtsp-0.1.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 13.5 MB |
| Tags | CPython 3.12 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
7fd98eae60e0b129d5ac8277202829770c199d070897491b963de16a981af2db
|
|
BLAKE2b-256 checksum How to use checksums |
d193fd7669e45dcae3f264a422f135dc11edbd688ab08083b111fc502d8c0aea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 19, 2026.
Transparency logRelease files / pdtsp-0.1.0-cp312-cp312-macosx_15_0_arm64.whl
| Download URL | pdtsp-0.1.0-cp312-cp312-macosx_15_0_arm64.whl |
|---|---|
| Size | 15.4 MB |
| Tags | CPython 3.12 macOS 15.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
56e72e29e7fedebe804dfe71e146be428f40d0045df504b456c1a4bebd0a5506
|
|
BLAKE2b-256 checksum How to use checksums |
cb1167548e1efd209d337672c6df53b944227bbbeb9167bcca1bdc36184fcf0b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 19, 2026.
Transparency logRelease files / pdtsp-0.1.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pdtsp-0.1.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 13.5 MB |
| Tags | CPython 3.11 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
6093910fdbead69d78a1a6a9f9d4becdfba3f2617df72ca149ded85362fe1b4a
|
|
BLAKE2b-256 checksum How to use checksums |
a01c4644054bf7bcb738cd298d6c34354d21631b17cff81db5a3f5251a991cd1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 19, 2026.
Transparency logRelease files / pdtsp-0.1.0-cp311-cp311-macosx_15_0_arm64.whl
| Download URL | pdtsp-0.1.0-cp311-cp311-macosx_15_0_arm64.whl |
|---|---|
| Size | 15.4 MB |
| Tags | CPython 3.11 macOS 15.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
1ad4e20c47a21c508f4253e045255ed72eaabebb84e22144f49dcc9c10d331bf
|
|
BLAKE2b-256 checksum How to use checksums |
13c3eee936bf34a33255254c5e299e362069a1688ead7c7c422c6da5239fc51a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 19, 2026.
Transparency logRelease files / pdtsp-0.1.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pdtsp-0.1.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 13.5 MB |
| Tags | CPython 3.10 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
50f063fa167870ff86dd2a74c0120076f96dd4d84a304b75b789186f07480258
|
|
BLAKE2b-256 checksum How to use checksums |
562a5f26ce97aff25511366a3deedcc7973a7d21d803b778fa72881ed78b04b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 19, 2026.
Transparency logRelease files / pdtsp-0.1.0-cp310-cp310-macosx_15_0_arm64.whl
| Download URL | pdtsp-0.1.0-cp310-cp310-macosx_15_0_arm64.whl |
|---|---|
| Size | 15.4 MB |
| Tags | CPython 3.10 macOS 15.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
d15ac061c98b3f219f84c70d4c19f728327fe3cf6daf7f353ded337a04e62058
|
|
BLAKE2b-256 checksum How to use checksums |
7e7b8a98f8ab23624c828fa528d5c21c74e3922559d29a0f68f6e71b64315f0c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 19, 2026.
Transparency logSecurity for pdtsp 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 9 files in this release have been uploaded with provenance metadata.
Attestation for pdtsp-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 19, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.