Skip to content
Subramanyam-LabPublic

About

Codes and datasets for the paper Neural Embedded Mixed-Integer Optimization for Location-Routing Problems

Resources

Stars

22 stars

Watchers

2 watching

Forks

Repository files navigation

Neural Embedded Optimization for Location-Routing Problems

arXiv IISE preliminary License Python

This repository contains the implementation, datasets, pre-trained models, and training data for the Neural Embedded Optimization approach for solving Location-Routing Problems. We provide everything needed to reproduce our results: benchmark instances, pre-trained neural networks, data sampling and label generation scripts, and training code. The original Graph Transformer related code was contributed by Doyoung (#8, #10) and Dr. Kwon (#9), later restructured and integrated.

Naming Convention: We refer to our approach as NEO-LRP. In the paper and codebase:

  • NEO-DS = NEO-LRP using DeepSets surrogate
  • NEO-GT = NEO-LRP using Graph Transformer surrogate

Table of Contents


Repository Structure

NEO-LRP/
├── benchmark_instances/            # Benchmark datasets (compressed)
│   ├── B_barreto.tar.gz            # Barreto benchmark (12 instances)
│   ├── P_prodhon.tar.gz            # Prodhon benchmark (30 instances)
│   ├── S_schneider.tar.gz          # Schneider benchmark (203 instances)
│   └── T_tuzun.tar.gz              # Tuzun benchmark (36 instances)
│
├── trained_models/                 # Pre-trained neural networks
│   ├── deepsets/
│   │   ├── scaled/                 # For P_prodhon, S_schneider
│   │   │   ├── phi/
│   │   │   └── rho/
│   │   └── unscaled/               # For T_tuzun, B_barreto
│   │       ├── phi/
│   │       └── rho/
│   └── graph_transformer/
│       └── scaled/
│
├── neo-lrp/                        # Main NEO-LRP implementation
│   ├── run.py                      # Main runner script
│   ├── combine_results.py          # Combine array job Excel files
│   ├── verify_solutions.py         # Verify solution correctness
│   ├── submit.sh                   # SLURM/bash submission script
│   ├── configs/                    # Dataset configs and BKS values
│   │   ├── {P_prodhon,S_schneider,T_tuzun,B_barreto}.json
│   │   ├── schneider_instances.txt
│   │   └── BKS/                    # Best Known Solutions (from the literature)
│   └── core/                       # Core modules
│       ├── dataparse.py            # Data parsing utilities
│       ├── lrp_model.py            # Neural embedded LRP model
│       ├── network_ds.py           # DeepSets network wrapper
│       ├── network_gt.py           # Graph Transformer network wrapper
│       └── solver.py               # CVRP solvers (VROOM, ORTools, VRPSolverEasy)
│
├── training/                       # Training pipeline (see training/README.md)
│   ├── data/                       # Pre-sampled training data
│   ├── sampling/                   # CVRP instance generation (GVS sampling)
│   ├── labeling/                   # Label generation using VROOM
│   └── scripts/                    # Training scripts
│       ├── train_deepsets/
│       └── train_graph_transformer/
│
├── flpvrp/                         # FLP-VRP ablation study (see flpvrp/README.md)
│
└── utils/
    └── tables_and_figures/         # Generate paper figures (see its README.md)

Installation

  1. Clone the Repository
git clone https://github.com/Subramanyam-Lab/NEO-LRP.git
cd NEO-LRP
  1. Extract Benchmark Instances
cd benchmark_instances
tar -xzf B_barreto.tar.gz
tar -xzf P_prodhon.tar.gz
tar -xzf S_schneider.tar.gz
tar -xzf T_tuzun.tar.gz
cd ..
  1. Create Conda Environment
conda create --name neolrp python=3.11
conda activate neolrp
pip install -r requirements.txt

Some Notes

  • For macOS users: If you encounter version conflicts, some packages (like torch and ortools) have different available versions on macOS vs Linux. Use python -m pip install -r requirements.txt to ensure packages install to the correct environment.
  • In our current implementation we use Gurobi-ML package to write the neural network constraints and solve the model using Gurobi and so a license is required and you can get one from Gurobi Academic Program.

Running NEO-LRP

Arguments

Argument Options Description
--dataset P_prodhon, S_schneider, T_tuzun, B_barreto Benchmark dataset
--normalization raw, minmax, cost_over_fi, cost_over_fi_minmax Use model trained with this target normalization
--N 110, 1100, 11000, 110000 Use model trained on N instances
--solver vroom, ortools, vrpeasy VRP solver for generating final routes
--model_type deepsets, graph_transformer Trained neural network architecture
--num_runs Integer >= 1 Number of runs per instance
--instance (optional) Single instance filename

If using --solver vrpeasy, you need to install VRPSolverEasy separately.

Using Python

cd neo-lrp

# All instances in a dataset
python run.py --dataset P_prodhon --normalization cost_over_fi --N 110000 --solver vroom --model_type deepsets --num_runs 5

# Single instance
python run.py --dataset S_schneider --instance 100-5-1c.json --normalization cost_over_fi --N 110000 --solver vroom --model_type deepsets --num_runs 1

Using Bash

Edit submit.sh to set BASE_DIR and conda environment, then remove or comment out #SBATCH lines:

cd neo-lrp
bash submit.sh P_prodhon cost_over_fi 110000 vroom deepsets 5

Using SLURM

cd neo-lrp

# Edit submit.sh: set BASE_DIR and conda environment

# DeepSets on Prodhon
sbatch --job-name=prodhon_ds submit.sh P_prodhon cost_over_fi 110000 vroom deepsets 5

# Graph Transformer on Prodhon
sbatch --job-name=prodhon_gt submit.sh P_prodhon cost_over_fi 110000 vroom graph_transformer 5

# Array jobs for large datasets (e.g., Schneider with 203 instances)
sbatch --job-name=schneider_ds --array=1-203 submit.sh S_schneider cost_over_fi 110000 vroom deepsets 1 configs/schneider_instances.txt

Output

Results are saved to neo-lrp/output/<DATASET>/:

  • Solution JSONs: <model_type>_<solver>_<normalization>_<N>/<instance>/run_<i>.json
  • Excel summary: <DATASET>_<model_type>_<N>_<normalization>_<solver>.xlsx

Utilities

Combine array job results:

python combine_results.py --dataset S_schneider --normalization cost_over_fi --N 110000 --solver vroom --model_type deepsets --instances_file configs/schneider_instances.txt --delete_temp

Verify solutions:

python verify_solutions.py --dataset P_prodhon --model_type deepsets --solver vroom --normalization cost_over_fi --N 110000

Training Neural Networks

For training new models from scratch, see training/README.md.

The training pipeline consists of:

  1. Data Sampling - Generate synthetic CVRP instances (GVS sampling)
  2. Label Generation - Solve instances using VROOM to obtain routing cost labels
  3. Model Training - Train DeepSets or Graph Transformer architectures

Pre-trained models and pre-sampled data are provided.


Ablation Studies

Value of Location Allocation Decisions (FLP-VRP Comparison)

See flpvrp/README.md for instructions on running the FLP-VRP ablation study.

Other Ablation Studies

After running NEO-LRP on all benchmarks, ablation study results can be generated using scripts in utils/tables_and_figures/prodhon/:

Ablation Script
Effect of sample size ablation_samplesize.py
Effect of routing solver ablation_solvers.py
Effect of neural network architecture ablation_neods_neogt.py
Effect of target normalization ablation_norm_compare.py

Generating Figures and Tables

After running NEO-LRP on all benchmarks, see utils/tables_and_figures/README.md for instructions on generating all figures and tables presented in the paper.


Running on Your Own Instances

Tip

You can directly apply our pre-trained models to new LRP instances without retraining.

  1. Determine your problem type:

    • Scaled: Distances = int(100 * euclidean), fixed route cost = 1000 → use scaled models
    • Unscaled: Float distances, no fixed route cost → use unscaled models
  2. Add your benchmark: Place instances in benchmark_instances/H_hypothetical/, create config in neo-lrp/configs/H_hypothetical.json (copy existing), optionally add BKS to neo-lrp/configs/BKS/

  3. Run:

    python run.py --dataset H_hypothetical --normalization cost_over_fi --N 110000 --solver vroom --model_type deepsets --num_runs 1

    The code automatically selects scaled/unscaled models based on your config.


Citation

If you find this repository helpful, use our pre-trained models, code, or training data in your research, or work on similar problems, we would appreciate a citation to our papers:

@article{kaleem2026neolrp,
      title={Neural Embedded Mixed-Integer Optimization for Location-Routing Problems}, 
      author={Waquar Kaleem and Doyoung Lee and Changhyun Kwon and Anirudh Subramanyam},
      year={2026},
      eprint={2412.05665},
      archivePrefix={arXiv},
      url={https://arxiv.org/abs/2412.05665}, 
}

@inproceedings{kaleem2024neuraliise,
  title={Neural Embedded Optimization for Integrated Location and Routing Problems},
  author={Kaleem, Waquar and Ayala, Harshita and Subramanyam, Anirudh},
  booktitle={IISE Annual Conference. Proceedings},
  pages={1--6},
  year={2024},
  organization={Institute of Industrial and Systems Engineers (IISE)}
}

If you find this work useful, consider giving the repository a ⭐!

For questions and support, please open an issue in the repository.

About

Codes and datasets for the paper Neural Embedded Mixed-Integer Optimization for Location-Routing Problems

Resources

Stars

22 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages