Extension of GELD (Global-view Encoder and Local-view Decoder) to the Capacitated Vehicle Routing Problem with Time Windows (CVRPTW).
The model keeps GELD's core design — a lightweight global encoder (RALA) and a heavyweight local decoder (AFM) — and adds CVRPTW-specific node features, feasibility masking, beam-search decoding, and reconstruction post-processing. Capacity and time-window constraints are enforced during decoding via the environment mask.
This project uses uv for dependency management.
uv sync
uv sync --extra dev # include pytest
uv sync --extra wandb # optional Weights & Biases logginggeld_cvrptw/
├── model/ # GeldCvrptwModel, Global Encoder, Local Decoder
├── env/ # CVRPTW environment (masking, step, dynamic state)
├── data/ # Loaders, augmentations, instance generation, HGS labelling
├── inference/ # Decoders (greedy, beam search), reconstruction, evaluator
├── training/ # Stage-1 supervised learning trainer
└── cli/ # Command-line entry points
Stage-1 training uses RCT/Luo-style CVRPTW-100 instances on the unit square (capacity 50, depot time window [0, 3], service time 0.2) with HGS distance labels, spanning time-window tightness α ∈ {0.2, …, 3.0}.
Held-out evaluation uses three suites under data/test/. Gaps are excess total travel distance vs HGS (synthetic) or CVRPLIB reference costs (Solomon / Homberger):
| Suite | Source | #Inst. | n | vs training | Location |
|---|---|---|---|---|---|
| Synthetic | Routing-MVMoE | 1000 | 100 | In-distribution (same uniform generator) | data/test/synthetic/ |
| Solomon | CVRPLIB (Solomon 1987) | 56 | 100 | OOD (C / R / RC layouts) | data/test/solomon/ |
| Homberger | CVRPLIB (Gehring & Homberger) | 300 | 200–1000 | OOD (structure + size; 60 per size) | data/test/homberger/ |
Solomon / Homberger use clustered (C), random (R), and mixed (RC) customer layouts. Homberger extends the same families to larger sizes.
Stage-1 supervised learning uses RCT-format CVRPTW-100 instances with HGS reference tours.
Pre-generated training data (RCT-format CVRPTW-100 with HGS labels):
- Download from Google Drive
- Place the
.pklproblem files and matchinghgs_*.pkllabel files indata/training_stage_1/
Each problem file contains instances in RCT format; each hgs_*.pkl file holds the corresponding HGS tour and cost used as training labels. The format follows Rethinking Constraint Tightness.
Generate additional data locally with the Hybrid Genetic Search (HGS) labeller:
uv run python scripts/generate_cvrptw.py --num-samples 10000This writes RCT-format instances and HGS labels to data/training_stage_1/ by default. Use --output-dir to change the destination. The generator follows the same format and HGS settings as the RCT repository.
Evaluation supports three benchmark suites under data/test/:
| Suite | Source | Location |
|---|---|---|
| Solomon | CVRPLIB VRPTW instances | data/test/solomon/ |
| Homberger | CVRPLIB VRPTW instances | data/test/homberger/ |
| Synthetic | Routing-MVMoE | data/test/synthetic/ |
Solomon and Homberger — download and extract from CVRPLIB:
mkdir -p data/test/solomon data/test/homberger
curl -fsSL -o data/test/Solomon.7z \
"https://galgos.inf.puc-rio.br/cvrplib/index.php/en/download/instance-set/22"
curl -fsSL -o data/test/Homberger.7z \
"https://galgos.inf.puc-rio.br/cvrplib/index.php/en/download/instance-set/23"
uv run --with py7zr python - <<'EOF'
import py7zr
from pathlib import Path
root = Path("data/test")
for archive, subdir, nested in [
("Solomon.7z", "solomon", "Solomon"),
("Homberger.7z", "homberger", "Holmberger"),
]:
out = root / subdir
with py7zr.SevenZipFile(root / archive, mode="r") as z:
z.extractall(path=out)
nested_dir = out / nested
if nested_dir.is_dir():
for path in nested_dir.iterdir():
path.rename(out / path.name)
nested_dir.rmdir()
(root / archive).unlink()
EOFEach instance is a .txt file in Solomon format; matching .sol reference solutions are included.
Synthetic — MVMoE-style uniform VRPTW-100 instances with HGS reference costs:
mkdir -p data/test/synthetic
curl -fsSL -o data/test/synthetic/vrptw100_uniform.pkl \
"https://raw.githubusercontent.com/RoyalSkye/Routing-MVMoE/main/data/VRPTW/vrptw100_uniform.pkl"
curl -fsSL -o data/test/synthetic/hgs_vrptw100_uniform.pkl \
"https://raw.githubusercontent.com/RoyalSkye/Routing-MVMoE/main/data/VRPTW/hgs_vrptw100_uniform.pkl"Stage 1 — supervised learning on CVRPTW-100 instances with HGS labels:
uv run geld-cvrptw-train-stage1Common options:
uv run geld-cvrptw-train-stage1 \
--epochs 50 \
--batch-size 1024 \
--cuda-device 0 \
--wandb --wandb-run-name cvrptw-stage1Resume from a checkpoint:
uv run geld-cvrptw-train-stage1 \
--model-load-path result/your_run \
--model-load-epoch 49Quick smoke run:
uv run geld-cvrptw-train-stage1 --debugEvaluate a trained checkpoint on synthetic, Solomon, and Homberger benchmarks:
uv run geld-cvrptw-eval \
--checkpoint-path result/your_run \
--checkpoint-epoch 49 \
--benchmark allUse --benchmark synthetic, solomon, or homberger for a single suite.
Decoding defaults to beam search with reconstruction post-processing. Disable either with --no-beam or --no-rc:
uv run geld-cvrptw-eval \
--checkpoint-path result/your_run \
--checkpoint-epoch 49 \
--benchmark solomon \
--no-rcResults are written under result/<timestamp>/ (eval_instances.csv, eval_summary.json).
For exact thesis table reproduction (bundled checkpoints and bench scripts), use the reproduction branch. Training data: Google Drive.
Each run writes a timestamped folder under result/:
| File | When | Contents |
|---|---|---|
log.txt |
always | Human-readable log |
metrics.csv |
training | One row per epoch |
metrics.json |
training | Same metrics plus run metadata |
plots/*.png |
training | Loss and length curves |
eval_instances.csv |
evaluation | Per-instance gaps |
eval_summary.json |
evaluation | Aggregated gap statistics |
Example — load training curves:
import pandas as pd
df = pd.read_csv("result/20260101_120000_train_stage_1/metrics.csv")
df.plot(x="epoch", y=["train_loss", "train_reference_length"])GELD-CVRPTW builds on the GELD architecture and training pipeline from:
- GELD — GELD: A unified neural model for efficiently solving traveling salesman problems across different scales (Xiao et al., Pattern Recognition, 2026)
- LEHD — original TSP training data and baseline code from the CIAM Group NCO repository
Training data and generation format follow Rethinking Constraint Tightness (CIAM Group). Benchmark instances come from CVRPLIB (Solomon, Homberger) and Routing-MVMoE (synthetic VRPTW). Reference labels are produced with Hybrid Genetic Search (HGS).
The CVRPTW environment draws on ideas from the MVMoE VRPTW environment.
The original GELD paper
@ARTICLE{Xiao2025,
author={Yubin Xiao and Di Wang and Rui Cao and Xuan Wu and Boyang Li and You Zhou},
journal={Pattern Recognition},
title={GELD: A unified neural model for efficiently solving traveling salesman problems across different scales},
year={2026},
volume={173},
pages={1-15},
}