Two-Stage Learning to Branch in Branch-Price-and-Cut Algorithms for Solving Vehicle Routing Problems Exactly
This archive is distributed in association with the journal Operations Research under the MIT License.
The software and data in this repository are a snapshot of the software and data that were used in the research reported in the paper Two-Stage Learning to Branch in Branch-Price-and-Cut Algorithms for Solving Vehicle Routing Problems Exactly by Zhengzhong You, Yu Yang, Xinshang Wang, and Wotao Yin.
To cite the contents of this repository, please cite both the paper and this repo, using their respective DOIs.
https://doi.org/10.1287/opre.2023.0615
https://doi.org/10.1287/opre.2023.0615.cd
Below is the BibTex for citing this snapshot of the repository.
@misc{you2023twostage,
author = {You, Zhengzhong and Yang, Yu and Wang, Xinshang and Yin, Wotao},
publisher = {Operations Research},
title = {{Two-Stage Learning to Branch in Branch-Price-and-Cut Algorithms for Solving Vehicle Routing Problems Exactly}},
year = {2025},
doi = {10.1287/opre.2023.0615.cd},
note = {Available for download at https://github.com/ORJournal/2023.0615},
}
The goal of this repository is to replicate the numerical experiments in the paper "Two-Stage Learning to Branch in Branch-Price-and-Cut Algorithms for Solving Vehicle Routing Problems Exactly" by Zhengzhong You, Yu Yang, Xinshang Wang, and Wotao Yin.
This replication package reproduces all tables and figures in Sections 6.1–6.3 and the Electronic Companion (Sections EC.7–EC.8) of the paper. See Section-to-Output Mapping for the complete mapping.
- VRPSolver binary: We cannot redistribute VRPSolver. The VRPSolver row in Table 6 is retrieved from logs generated on our original machine. See Table 6 and VRPSolver Scaling for details.
- Training data generation (Section EC.7.1): Pre-generated training data is included; regeneration requires HiPerGator cluster access.
- Repository Layout
- System Requirements & Dependencies
- Quick Start
- Replication Workflow (Step‑by‑Step)
- Batch Size, Hardware, and Parallelization
- Generating Tables & Figures
- Section-to-Output Mapping
- Table 6 and VRPSolver Scaling
- SLURM (HiPerGator) — Optional
- Paths & Environment Variables
- Approximate Wall‑Clock Times
- Notes on Cross-Machine Reproducibility
- Large Files Notice
- Troubleshooting
- Licenses & Attribution
- Ongoing Development
- Support
.
├── RouteOpt/ # Solver source (archived in-repo)
│ └── Dependency/
│ ├── cvrpsep/ # Vendored fork-of-a-fork (with license/attribution)
│ ├── hgs/ # Vendored Hybrid Genetic Search (with license/attribution)
│ ├── eigen-3.4.0/ # Eigen (header-only)
│ └── xgb/ # XGBoost (C API, v2.0.0; built by build.py)
├── experiments/ # Replication drivers by paper section
│ ├── <section>/include, src # Section-specific headers/sources copied into RouteOpt/…/CVRP
│ ├── <section>/data/2lbb_* # Paper’s archived outputs (where applicable)
│ ├── <section>/data/tmp_out/ # Outputs generated when you run a section
│ ├── common/ # Shared utilities
│ ├── generate_data.py # Creates tables/figures from tmp_out
│ └── categorize_tmp_out.py # Postprocesses raw outputs
├── paper/
│ ├── tables/ # Replicated tables (text/CSV/LaTeX)
│ └── figures/ # Replicated figures (PNG/PDF)
├── scripts/
│ └── slurm/run_section.sbatch # SLURM template (optional)
├── build.py # Build third-party deps + prepare solver
├── run_exp.py # Section selector, builder, and runner
├── set_path_variable.py # Helper for setting paths
├── requirements.txt # Pinned Python packages (pip-compile)
├── LICENSE
└── third_party/NOTICE_AND_LICENSES.md
OS
- Workstations (paper): Ubuntu 20.04 LTS
- Cluster: RHEL 8.8 (HiPerGator)
Compilers & Build Tools
- GCC / g++ ≥ 9 (tested 12.2, 12.3)
- CMake ≥ 3.26 (tested 3.30.2)
- Ninja ≥ 1.11 (tested 1.12.1)
make(forcvrpsep)
Libraries
- Boost 1.83.0
- Eigen 3.4.0 (header‑only; vendored)
- XGBoost 2.0.0 (C API built from source; Python wheel pinned if used)
- Gurobi 10.0.0 (user‑installed; not redistributed)
- CPLEX Studio 22.1 (user‑installed; not redistributed)
Python
- Python 3.10.x
- Pinned packages in
requirements.txt(includingxgboost==2.0.0)
Note. We explicitly list GCC and Ninja as prerequisites because they are required for successful builds on many systems.
Working‑directory rule: run each Python helper from the folder where it resides (e.g.,
run_exp.pyfrom./experiments,build.pyfrom the repo root).
-
Install Python deps
pip install -r requirements.txt
-
Build dependencies and prepare the solver (from repo root)
python3 build.py
This will:
- Update
data/idx/*.inswith absolute instance paths - Fetch/build XGBoost 2.0.0 (C API) under
RouteOpt/Dependency/xgb/ - Fetch Eigen 3.4.0
- Build cvrpsep and hgs
- Update
-
Set paths
python3 set_path_variable.py
-
Run experiments (from repo root)
python3 run_exp.py
Choose a section, enter batch size, and optionally the parallel batch size (within the same section only).
-
Generate tables & figures (from
./experiments)python3 generate_data.py tmp --sections <section_name>
Artifacts are written to
experiments/results/. The repository also ships the final artifacts underpaper/tables/andpaper/figures/.
-
Build third‑party and solver code
python3 build.py
Expected results:
-
data/idx/*.insrewritten with absolute instance paths -
XGBoost v2.0.0 cloned to
RouteOpt/Dependency/xgb, configured with CMake (-GNinja, C++17), built with Ninja-
Artifacts (platform‑dependent):
- Linux:
RouteOpt/Dependency/xgb/build/lib/libxgboost.so - macOS:
RouteOpt/Dependency/xgb/build/lib/libxgboost.dylib - Windows:
RouteOpt/Dependency/xgb/build/bin/xgboost.dll
- Linux:
-
-
Eigen 3.4.0 present at
RouteOpt/Dependency/eigen-3.4.0 -
cvrpsep built in place with
make -j -
hgs built/installed locally via CMake (library under
RouteOpt/Dependency/hgs/lib/) -
Console ends with
All tasks completed.on success
-
-
Set paths
python3 set_path_variable.py
These are consumed by
RouteOpt/Application/CVRP/CMakeLists.txt.We also update the
CMakeLists.txtinsidesection_EC8_4_effectiveness_bkf_bc_methods_x50(independent Branch‑and‑Cut preliminary study). -
Select a section & build
python3 run_exp.py
Choose, e.g.,
1forsection_06_1_case_study_i_cvrp_01_superiority_no_opt. The script:- Copies
experiments/<section>/{include,src}toRouteOpt/Application/CVRP/{include,src} - Builds the section under
RouteOpt/build/ - Places the binary under
RouteOpt/Application/CVRP/bin/
- Copies
-
Execute experiments
run_exp.pyprompts for batch size and parallel batch size (jobs within the same section).- Raw results are saved to
experiments/<section>/data/tmp_out/ - On completion,
categorize_tmp_out.pyauto‑organizes outputs
-
Generate tables & figures
cd experiments python3 generate_data.py tmp --sections <section_name>
- Calls the section’s
table_.py/figure_.py - Writes artifacts to
experiments/results/
- Calls the section’s
Batch size. The number of instances to run in a section. Each section’s default equals the paper’s setting
(e.g., section_06_1_case_study_i_cvrp_01_superiority_no_opt uses 90 instances). You can run a subset; instances are chosen deterministically (first N by index).
Hardware (paper workstations).
- Ubuntu 20.04 LTS, Intel® Core™ i9‑12900K @ 3.2 GHz, 128 GB RAM
- Single thread per job for timed experiments
Memory note. Some difficult instances are memory‑intensive. With ≤ 32 GB RAM, we do not recommend running multiple jobs concurrently; memory pressure can slow jobs or trigger failures.
Internally, each experiment section builds a queue of tasks, where each task is one (instance, method) pair. For every instance, we always run four methods: 2LBB, 3PB, 2LBB-DY, 3PB-DY. These four tasks for the same instance are placed consecutively in the queue.
The "parallel batch size" parameter k (prompted in run_exp.py) controls how many tasks are executed at the same time:
-
k = 1(default): All tasks execute strictly one after another. This is the setting under which CPU times in the paper were obtained. -
k > 1: Up toktasks from the queue run concurrently. In practice, this means different methods for the same instance often run in parallel on the same machine.
Advantages of k > 1:
- Methods for the same instance run in similar, stable conditions, so relative timing is less affected by background load.
Recommended use:
- For reproducing the CPU times reported in the paper, use
k = 1. - For faster replication when focusing on performance trends and method comparisons,
k > 1is acceptable. Avoid mixing extremely heavy open instances with lighter instances in the same parallel batch, as this can introduce timing noise.
Concurrency safety. run_exp.py uses separate build/output directories per job within a section to avoid races in shared build directories.
Important: Do not run different sections concurrently when comparing runtimes across sections.
-
Included artifacts:
paper/tables/—table_3.txt,table_4.txt, …,table_ec9.txtpaper/figures/—figure_5.png,figure_6.png,figure_7.png,figure_8.png,figure_ec3.png, …,figure_ec7.png -
Recreate from outputs (example):
cd experiments python3 generate_data.py tmp --sections section_06_1_case_study_i_cvrp_01_superiority_no_optArtifacts are written to
experiments/results/.
The table below shows the explicit mapping between run_exp.py menu numbers, directory names, and the paper outputs they generate:
| Menu # | Section Directory | Instance Set | Paper Output |
|---|---|---|---|
| 1 | section_06_1_case_study_i_cvrp_01_superiority_no_opt |
CVRP-150-90-1 | Table 4, Figure 5 |
| 2 | section_06_1_case_study_i_cvrp_01_superiority_opt |
CVRP-150-90-1 | Table 3 |
| 3 | section_06_1_case_study_i_cvrp_02_generalization |
CVRP-120/150/180 | Figure 6 |
| 4 | section_06_1_case_study_i_cvrp_03_benchmark |
CVRP-V-42-X | Table 5 |
| 5 | section_06_1_case_study_i_cvrp_04_cplex_2lbb |
CVRP-V-42-X | Table 6 |
| 6 | section_06_2_case_study_ii_vrptw_01_superiority_no_opt |
VRPTW-180-60-1 | Table 8, Figure 7 |
| 7 | section_06_2_case_study_ii_vrptw_01_superiority_opt |
VRPTW-180-60-1 | Table 7 |
| 8 | section_06_2_case_study_ii_vrptw_02_generalization |
VRPTW-160/180/200 | Figure 8 |
| 9 | section_06_2_case_study_ii_vrptw_03_benchmark |
VRPTW-200-22-H2 | Table 9 |
| 10 | section_06_3_open_cvrp_instances |
Open CVRP | Table 10 |
| 11 | section_EC7_2_standalone_performance_m1_cvrp_150_90_1 |
CVRP-150-90-1 | Table EC6 |
| 12 | section_EC7_3_standalone_performance_m2_cvrp_150_90_1 |
CVRP-150-90-1 | Table EC7 |
| 13 | section_EC8_1_8_3_superiority_bkf_static_schemes_cvrp_150_90_1 |
CVRP-150-90-1 | Figures EC3,4,5 |
| 14 | section_EC8_2_superiority_bkf_dynamic_schemes_cvrp_150_90_1 |
CVRP-150-90-1 | Table EC8 |
| 15 | section_EC8_4_effectiveness_bkf_bc_methods_x50 |
CVRP-X50 | Table EC9 |
Note on Section 6.3 (Open CVRP instances): This section contains the heaviest computational jobs. On our workstations, they require approximately 135 hours (X-n294-k50) and 10 hours (X-n344-k43) per method on average. For most users, it is not necessary to rerun these instances. The tables and figures can be regenerated from the archived logs by:
- Unzipping the archived logs in
experiments/section_06_3_open_cvrp_instances/data/ - Running
python3 generate_data.py 2lbb --sections section_06_3_open_cvrp_instances
The raw logs are stored under experiments/section_06_3_open_cvrp_instances/data/.
Two-Stage Solution Process for Open Instances
The default configuration is optimized for the first stage only: once a branch-and-bound node reaches the enumerated state (all necessary columns enumerated), the node is immediately discarded without saving enumeration columns externally. This design accelerates evaluation of branching strategies, as first-stage performance is the dominant factor.
To fully solve an open instance using the two-stage approach (using strategy
2lbb-dyas an example):Stage 1: Write Enumeration Trees
Modify
experiments/section_06_3_open_cvrp_instances/config/config_2lbb-dy.txt:
KILL_ENUMERATION_TREES:falseWRITE_ENUMERATION_TREES:trueREAD_ENUMERATION_TREES:falseRecompile and run. Two folders will be generated in
RouteOpt/Application/CVRP/:
EnuTree/: Tree files (e.g.,X-n344-k43_0.tree)EnuColPool/: Column pool files (e.g.,X-n344-k43.pool)Default paths are defined via
TREE_FOLDERandCOL_POOL_FOLDERinRouteOpt/Application/CVRP/include/MACRO.hpp.Stage 2: Read and Solve Enumeration Trees
Modify the configuration file:
KILL_ENUMERATION_TREES:falseWRITE_ENUMERATION_TREES:falseREAD_ENUMERATION_TREES:trueRecompile and run with
-c(column pool) and-t(tree file) arguments:./bin/2lbb-dy -c X-n344-k43.pool -t X-n344-k43_0.treeRepeat for each
.treefile generated in Stage 1.This process can be parallelized on high-performance computing (HPC) clusters (e.g., HiPerGator) by solving multiple tree files concurrently, which in our case typically reduces the wall-clock time to within one day.
Table 6 compares our 2LBB-dy method with VRPSolver on the CVRP-V-42-X benchmark. Due to licensing restrictions, we cannot redistribute the VRPSolver binary. This creates an important consideration for replication:
- The 2LBB-dy row is recomputed on the user's machine by running our code.
- The VRPSolver row is retrieved from log files generated on our original machine.
When running on hardware slower than our original machine (Intel Core i9-12900K), the 2LBB-dy times will be proportionally larger, while the VRPSolver times remain fixed. This can make it appear that 2LBB-dy is slower than VRPSolver at the root node, even though it is actually faster on equivalent hardware.
Solution: The table_6.py script now outputs two versions of the VRPSolver row:
- VRPSolver (original): Times from our original machine (for reference).
- VRPSolver (scaled): Times scaled to match your machine's speed.
The scaling factor α is computed as:
α = (geometric mean of 2LBB-dy root times on your machine) / (geometric mean of 2LBB-dy root times on our machine)
When comparing performance, use the VRPSolver (scaled) row against your recomputed 2LBB-dy results.
VRPSolver is a Branch-Cut-and-Price exact solver for vehicle routing problems, built on top of BaPCod. It is available via Julia, Python (VRPSolverEasy), or C++ (native BaPCod).
VRPSolver and dependencies version numbers:
| Component | Version |
|---|---|
| BaPCod | v0.74 |
| VRPSolver extension | v0.5.24 |
| CPLEX (for VRPSolver comparison) | 22.1.0 |
| Boost | 1.76 |
| LEMON | 1.3.1 |
| CMake | 3.30.2 |
Configuration: Single thread, default VRPSolver/BaPCod parameters.
Licensing note: BaPCod is distributed under an academic-use-only license and must be obtained directly from the BaPCod download page. It cannot be redistributed as part of this replication package. Detailed installation instructions are available in the BaPCod documentation.
We provide a sample SLURM script at
scripts/slurm/run_section.sbatch, adapted from the reviewer's configuration. Below is an overview of the key parameters:
#!/bin/bash
#SBATCH --job-name=routeopt-replication # Job name in queue listings
#SBATCH --output=Report/section_%A.out # Standard output (%A = job ID)
#SBATCH --error=Report/section_%A.err # Standard error
#SBATCH --nodes=1 # Single compute node
#SBATCH --ntasks=1 # Single task (the Python script)
#SBATCH --cpus-per-task=20 # 20 cores for parallel execution
#SBATCH --mem=128gb # 128GB RAM (required for heavy instances)
#SBATCH --time=10-00:00:00 # 10-day time limit
#SBATCH --mail-type=ALL # Email on start/end/fail
export PARALLEL="${SLURM_CPUS_PER_TASK}"
# Load modules (adjust for your cluster)
module load python/3.10.10 gcc/12.3.0 cmake/3.26.3 ninja/1.12.1
module load gurobi/11.0.1 cplex/22.1 boost/1.86.0-atomic
cd /path/to/2023.0615
# Force single-threaded numerical libraries for consistent timing
export OMP_NUM_THREADS=1
export MKL_NUM_THREADS=1
export OPENBLAS_NUM_THREADS=1
python -u run_exp.py << EOF
${SECTION_CHOICE}
${PARALLEL}
EOFKey parameters explained:
| Parameter | Description |
|---|---|
--cpus-per-task=20 |
Number of CPU cores allocated. This value is passed to run_exp.py as the parallel batch size, allowing up to 20 (instance, method) pairs to run concurrently. |
--mem=128gb |
Memory allocation. 128GB is sufficient for all experiments including the memory-intensive open CVRP instances. |
--time=10-00:00:00 |
Wall-clock time limit (10 days). Adjust based on which section you are running. |
OMP_NUM_THREADS=1 |
Forces single-threaded execution in numerical libraries to ensure consistent timing. |
SECTION_CHOICE |
Environment variable specifying which section to run (1–15). Set before submitting. |
Usage:
export SECTION_CHOICE=5 # Run section 5 (Table 6)
sbatch scripts/slurm/run_section.sbatchOur Cluster environment: HiPerGator, RHEL 8.8; nodes with dual AMD EPYC 7702 (64‑core) @ 2.0 GHz and 1003 GB RAM. Access to 1080 CPU cores / 8640 GB RAM.
You can set paths with:
python3 set_path_variable.py(Recommended.) For example:
GUROBI_HOME=/home/yzz/gurobi1000/linux64
CPLEX_HOME=/home/yzz/opt/ibm/ILOG/CPLEX_Studio221
BOOST_ROOT=/home/yzz/boost_1_83_0
BOOST_LIBRARYDIR=/home/yzz/boost_1_83_0/stage/lib
EIGEN3_INCLUDE_DIR=$PWD/RouteOpt/Dependency/eigen-3.4.0
XGB_ROOT=$PWD/RouteOpt/Dependency/xgbRouteOpt/Application/CVRP/CMakeLists.txt consumes these variables.
You may also edit the paths directly in that CMakeLists.txt if preferred.
Times below assume a Dell workstation (single‑thread mode) comparable to Intel Core i9‑12900K @ 3.2 GHz, 128 GB RAM. Actual runtimes vary with hardware, OS, load, and instance mix. When comparing with the paper, please run sequentially.
Section 6.1 Case Study I: CVRP
- Superiority of 2LBB on instance set CVRP‑150‑90‑1 with two upper bounds (the optimal value and (1.0 + 0.1%) × optimal value): 5 days
- Generalization capability — four methods (3PB, 3PB‑dy, 2LBB, 2LBB‑dy) on instance sets CVRP‑120‑90‑1, CVRP‑150‑90‑1, CVRP‑180‑90‑1: 15 days
- Benchmark performance on instance set CVRP‑V‑42‑X: 7 days
- Comparison with VRPSolver on instance set CVRP‑V‑42‑X: 4 days
Section 6.2 Case Study II: VRPTW
- Superiority of 2LBB on instance set VRPTW‑180‑60‑1 with two upper bounds (the optimal value and (1.0 + 0.1%) × optimal value): 3 days
- Generalization capability — four methods (3PB, 3PB‑dy, 2LBB, 2LBB‑dy) on instance sets VRPTW‑160‑60‑1, VRPTW‑180‑60‑1, VRPTW‑200‑60‑1: 9 days
- Benchmark performance on instance set VRPTW‑200‑22‑H2: 3 days
Section 6.3 Open CVRP instances
- 24 days on the workstation + 1 day on HiPerGator (≈1000 jobs in parallel)
Section EC.7.1 (Training data generation)
- Using instance set CVRP‑150‑270‑0: 1 day on HiPerGator (≈1000 jobs in parallel; can be skipped with data provided)
Section EC.7.2
- Standalone performance of M1 on instance set CVRP‑150‑90‑1: 4 days
Section EC.7.3
- Standalone performance of M2 on instance set CVRP‑150‑90‑1: 3 days
Section EC.8.1
- Superiority of BKF to static schemes on instance set CVRP‑150‑90‑1: 28 days
Section EC.8.2
- Superiority of BKF to other dynamic schemes on instance set CVRP‑150‑90‑1: 2 days
Section EC.8.4
- Effectiveness of BKF in B&C methods on instance set X50: 21 days
- Dell workstation: Intel Core i9‑12900K @ 3.2 GHz, NVIDIA GeForce RTX 2080 SUPER, 128 GB RAM
When running experiments on different hardware, users may observe some variations in results. This section explains expected behaviors and provides guidance.
If your CPU is slower than our reference machine (Intel Core i9-12900K @ 3.2 GHz), runtimes will be proportionally larger. A factor of 2–3× is common on older or lower-clocked CPUs. The number of explored nodes should remain similar, confirming the implementation is executing correctly.
On slower machines, you may observe slightly larger root gaps (e.g., 0.12% vs. 0.11% in Table 5). This occurs because:
-
Instance heterogeneity: The X-series instances vary in pricing difficulty. On slower hardware, harder instances trigger more aggressive tail-off in cut generation, leading to fewer cuts and a weaker root bound and thus a larger B&B tree.
-
Static vs. dynamic schemes: For 2LBB and 3PB, we use a fixed LP-test parameter value of 10. On slower machines where the search tree may grow larger, this static value can be more favorable, reducing the performance gap relative to dynamic variants (2LBB-dy, 3PB-dy).
Recommended tuning for slower machines: If you observe noticeably larger root gaps, consider using a slightly more relaxed tail-off threshold for cut generation. This allows more cuts to be generated even when pricing is slower. This is an optional stability tuning and does not change the baseline experiment settings.
Minor visual deviations in the performance profile figures are expected when running on different machines. These can arise from:
- Slight differences in runtimes that shift the curves horizontally,
- Randomness in cut generation, which slightly affects lower bounds and thus tree sizes,
- Rounding and binning effects when aggregating results.
These variations do not change the qualitative conclusions: the relative ordering of methods and the main performance trends remain consistent. Small shifts in the curve positions do not affect the findings reported in the paper.
All experiments were run on machines with 128 GB RAM. For the open CVRP instances (Section 6.3), memory usage stays within this limit. If running on a cluster, we recommend requesting 128 GB per job for these heavy instances.
Some data/ outputs exceed GitHub’s 100 MB limit and are shipped as archives. After cloning, unzip if needed.
Examples (>100 MB):
./section_06_3_open_cvrp_instances/data/2lbb_open_ins/2lbb/2lbb_X-n294-k50.out(148.07 MB)./section_06_3_open_cvrp_instances/data/2lbb_open_ins/2lbb-dy/2lbb-dy_X-n294-k50.out(142.85 MB)./section_06_3_open_cvrp_instances/data/2lbb_open_ins/3pb/3pb_X-n294-k50.out(189.84 MB)./section_06_3_open_cvrp_instances/data/2lbb_open_ins/3pb-dy/3pb-dy_X-n294-k50.out(124.64 MB)./section_EC7_1_9_1_9_2_training_details/cvrp_data/2lbb_learning_data/lp_3.train(132.12 MB)./section_EC7_1_9_1_9_2_training_details/cvrp_data/2lbb_learning_data/temp_lp_3.train(102.86 MB)./section_EC7_1_9_1_9_2_training_details/tw_data/2lbb_learning_data/lp_3.train(189.13 MB)./section_EC7_1_9_1_9_2_training_details/tw_data/2lbb_learning_data/lp_3.vali(112.36 MB)
error in XGBoosterLoadModel(...):
Check failed: str[0] == '{' (b vs. {)
Cause: model format/library mismatch.
Fix: use XGBoost 2.0.0 for both the C API (built via build.py) and the Python package (if used):
pip install "xgboost==2.0.0"If running many jobs simultaneously created build conflicts previously, note that run_exp.py now uses per‑job build/output directories within the same section. Avoid running different sections concurrently when comparing runtimes.
- The solver and replication drivers are licensed under this repository’s LICENSE.
- Third‑party components (
cvrpsep,hgs,eigen,xgboost) are included or fetched under their respective licenses. Seethird_party/NOTICE_AND_LICENSES.mdand the license files shipped inside each third‑party directory.
This package is based on RouteOpt 1.0 (archived here for replication). Active development continues in RouteOpt 2.0: https://github.com/Zhengzhong-You/RouteOpt.
Please open issues here: https://github.com/ORJournal/2023.0615/issues/new
1. section_06_1_case_study_i_cvrp_01_superiority_no_opt
2. section_06_1_case_study_i_cvrp_01_superiority_opt
3. section_06_1_case_study_i_cvrp_02_generalization
4. section_06_1_case_study_i_cvrp_03_benchmark
5. section_06_1_case_study_i_cvrp_04_cplex_2lbb
6. section_06_2_case_study_ii_vrptw_01_superiority_no_opt
7. section_06_2_case_study_ii_vrptw_01_superiority_opt
8. section_06_2_case_study_ii_vrptw_02_generalization
9. section_06_2_case_study_ii_vrptw_03_benchmark
10. section_06_3_open_cvrp_instances
11. section_EC7_2_standalone_performance_m1_cvrp_150_90_1
12. section_EC7_3_standalone_performance_m2_cvrp_150_90_1
13. section_EC8_1_8_3_superiority_bkf_static_schemes_cvrp_150_90_1
14. section_EC8_2_superiority_bkf_dynamic_schemes_cvrp_150_90_1
15. section_EC8_4_effectiveness_bkf_bc_methods_x50
For each selection,
run_exp.pywill prompt for batch size and parallel batch size (1 = sequential).
