[![INFORMS Journal on Computing Logo](https://INFORMSJoC.github.io/logos/INFORMS_Journal_on_Computing_Header.jpg)](https://pubsonline.informs.org/journal/ijoc)

# A Trilevel Programming Model and Nested Generalized Benders Decomposition for the Bus Line Contracting Problem

This archive is distributed in association with the [INFORMS Journal on Computing](https://pubsonline.informs.org/journal/ijoc) under the [MIT License](LICENSE).

The software and data in this repository are a snapshot of the software and data that were used in the research reported on in the paper:
[A Trilevel Programming Model and Nested Generalized Benders Decomposition for the Bus Line Contracting Problem](https://doi.org/10.1287/ijoc.2025.1527)
by Zhitao Hu, Zhiyuan Liu, Di Huang, Shuaian Wang, and Pengli Mo. 

## Cite

To cite the contents of this repository, please cite both the paper and this repo, using their respective DOIs.

https://doi.org/10.1287/ijoc.2025.1527

https://doi.org/10.1287/ijoc.2025.1527.cd

Below is the BibTex for citing this snapshot of the repository.

```
@misc{hu2026trilevel,
  author = {Z. Hu and Z. Liu and D. Huang and S. Wang and P. Mo}, 
  publisher = {INFORMS Journal on Computing},
  title = {{A Trilevel Programming Model and Nested Generalized Benders Decomposition for the Bus Line Contracting Problem}},
  year = {2026}, 
  doi = {10.1287/ijoc.2025.1527.cd},
  url = {https://github.com/INFORMSJoC/2025.1527},
  note = {Available for download at https://github.com/INFORMSJoC/2025.1527},
}  
```

## Repository Structure

```text
data/                         input data
results/                      experiment outputs
scripts/                      experiment entry points and export scripts
src/                          core source code
README.md
AUTHORS
LICENSE
```

Main code modules:

- `src/algos/`: nested GBD, HPR variants, transit assignment, acceleration logic
- `src/busopt/`: model configuration and unified runners
- `src/entity/`: network and solution data structures
- `src/io_utils/`: data loading

Main experiment scripts:

- `scripts/run_main_experiments.py`
- `scripts/mode_comparison/`
- `scripts/sensitivity/`
- `scripts/exports/`

## Reproducing the Paper Experiments

Run all commands from the repository root.

### 1. Main experiments

Generate solution results:

```bash
python scripts/run_main_experiments.py
```

Outputs:

- `results/main_experiments/with_acceleration/`
- `results/main_experiments/without_acceleration/`

Export Table 1:

```bash
python scripts/exports/export_table1_csv.py
```

Output:

- `results/tables/table1_main_experiments.csv`

Export convergence data:

```bash
python scripts/exports/export_convergence.py
```

Output:

- `results/main_experiments/convergence/`

### 2. Regime comparison and ablation experiments

Run regime comparison:

```bash
python scripts/mode_comparison/run_regimes.py
```

Run full cooperative:

```bash
python scripts/mode_comparison/run_fc.py
```

Run semi-cooperative:

```bash
python scripts/mode_comparison/run_sc.py
```

Run ablation experiments:

```bash
python scripts/mode_comparison/run_ablation.py
```

All outputs are written to:

- `results/mode_comparison/`

Export Table 2:

```bash
python scripts/exports/export_table2_csv.py
```

Output:

- `results/tables/table2_mode_comparison.csv`

### 3. Sensitivity analysis

Subsidy sensitivity:

```bash
python scripts/sensitivity/run_subsidy_sensitivity.py
```

Outputs:

- `results/subsidy_sensitivity/*.json`
- `results/subsidy_sensitivity/subsidy.csv`

Fare sensitivity:

```bash
python scripts/sensitivity/run_price_sensitivity.py
```

Outputs:

- `results/price_sensitivity/*.json`
- `results/price_sensitivity/price.csv`

Operating cost sensitivity:

```bash
python scripts/sensitivity/run_cost_sensitivity.py
```

Outputs:

- `results/cost_sensitivity/*.json`
- `results/cost_sensitivity/cost.csv`

Minimum frequency sensitivity:

```bash
python scripts/sensitivity/run_min_freq_sensitivity.py
```

Outputs:

- `results/min_freq_sensitivity/*.json`
- `results/min_freq_sensitivity/min_freq.csv`

To export sensitivity CSVs only, rerun the same script with `--export-only`, or use:

```bash
python scripts/exports/export_sensitivity_csv.py --kind subsidy --input-dir results/subsidy_sensitivity
python scripts/exports/export_sensitivity_csv.py --kind price --input-dir results/price_sensitivity
python scripts/exports/export_sensitivity_csv.py --kind cost --input-dir results/cost_sensitivity
python scripts/exports/export_sensitivity_csv.py --kind min_freq --input-dir results/min_freq_sensitivity
```

## Requirements

- Python 3.10+
- Gurobi with a valid license
