Paper Symmetry-preserving graph attention network to solve routing problems at multiple resolutions:
https://arxiv.org/pdf/2310.15543.pdf
Contributors:
- Thong Bach
- Tran Cong Dao
- Hy Truong Son (Correspondent / PI)
- Python>=3.8
- NumPy
- SciPy
- PyTorch>=1.7
- tqdm
- tensorboard_logger
- Matplotlib (optional, only for plotting)
For training TSP instances with 20 nodes and using rollout as REINFORCE baseline:
python run.py --graph_size 20 --baseline rollout --run_name 'tsp20_rollout'
Training data is generated on the fly. To generate validation and test data (same as used in the paper) for all problems:
python generate_data.py --problem all --name validation --seed 4321
python generate_data.py --problem all --name test --seed 1234
For training TSP instances with 20 nodes and using rollout as REINFORCE baseline and using the generated validation set:
python run.py --graph_size 20 --baseline rollout --run_name 'tsp20_rollout' --val_dataset data/tsp/tsp20_validation_seed4321.pkl
python run.py --graph_size 20 --baseline rollout --run_name 'tsp20_rollout' --val_dataset data/tsp/tsp20_validation_1000_seed1000.pkl
By default, training will happen on all available GPUs. To disable CUDA at all, add the flag --no_cuda
.
Set the environment variable CUDA_VISIBLE_DEVICES
to only use specific GPUs:
CUDA_VISIBLE_DEVICES=2,3 python run.py
Note that using multiple GPUs has limited efficiency for small problem sizes (up to 50 nodes).
You can initialize a run using a pretrained model by using the --load_path
option:
python run.py --graph_size 100 --load_path pretrained/tsp_100/epoch-99.pt
The --load_path
option can also be used to load an earlier run, in which case also the optimizer state will be loaded:
python run.py --graph_size 20 --load_path 'outputs/tsp_20/tsp20_rollout_{datetime}/epoch-0.pt'
The --resume
option can be used instead of the --load_path
option, which will try to resume the run, e.g. load additionally the baseline state, set the current epoch/step counter and set the random number generator state.
To evaluate a model, you can add the --eval-only
flag to run.py
, or use eval.py
, which will additionally measure timing and save the results:
python eval.py data/tsp/tsp20_test_seed1234.pkl --model pretrained/tsp_20 --decode_strategy greedy
If the epoch is not specified, by default the last one in the folder will be used.
To report the best of 1280 sampled solutions, use
python eval.py data/tsp/tsp20_test_seed1234.pkl --model pretrained/tsp_20 --decode_strategy sample --width 1280 --eval_batch_size 1
Beam Search (not in the paper) is also recently added and can be used using --decode_strategy bs --width {beam_size}
.
Baselines for different problems are within the corresponding folders and can be ran (on multiple datasets at once) as follows
python -m problems.tsp.tsp_baseline farthest_insertion data/tsp/tsp20_test_seed1234.pkl data/tsp/tsp50_test_seed1234.pkl data/tsp/tsp100_test_seed1234.pkl
To run baselines, you need to install Compass by running the install_compass.sh
script from within the problems/op
directory and Concorde using the install_concorde.sh
script from within problems/tsp
. LKH3 should be automatically downloaded and installed when required. To use Gurobi, obtain a (free academic) license and follow the installation instructions.
python run.py -h
python eval.py -h
See plot_vrp.ipynb
for an example of loading a pretrained model and plotting the result for Capacitated VRP with 100 nodes.
Thanks to pemami4911/neural-combinatorial-rl-pytorch for getting me started with the code for the Pointer Network.
This repository includes adaptions of the following repositories as baselines:
- https://github.com/MichelDeudon/encode-attend-navigate
- https://github.com/mc-ride/orienteering
- https://github.com/jordanamecler/PCTSP
- https://github.com/rafael2reis/salesman
@misc{tran2023symmetrypreserving,
title={Symmetry-preserving graph attention network to solve routing problems at multiple resolutions},
author={Cong Dao Tran and Thong Bach and Truong Son Hy},
year={2023},
eprint={2310.15543},
archivePrefix={arXiv},
primaryClass={cs.LG}
}