This library implements a two-phase, rolling-horizon mixed-integer linear programming solver for the Integrated Healthcare Timetabling Competition - IHTC 2024.
The technicals of the model, the solver and a presentation of the challenge is provided in the following article, that we kindly ask to cite if you use part of this code.
@article{sabauda25HTC,
title={Healthcare Predictive Timetabling: A model predictive decomposition for integrated healthcare timetabling},
author={Gioia, Daniele Giovanni and Mazza, Lorenzo and Macis, Manuel and Fadda, Edoardo and Brandimarte, Paolo},
journal={TBA},
year={2025},
howpublished = {\url{to be assigned}},
}The IHTC-2024 has provided two sets of instances. A public one that was used for qualification purposes and a second one for the finals. Such instances are available in the datasets folder. Furthermore, an additional dataset large__instances contains very large example that have been kindly provided to us by the IHTC-2024 team to stress our solver.
Instances are read by the classes inside the problem__instance folder. In particular, InstanceGlobal.py is a JSON parser that follows the competition guidlines for the input format.
The results folder contains the solutions generated by the solver and is used by the testers to compute the cost function and possible infeasibilities.
To validate instances, a C++ compiler is necessary. To compile the instance validator:
g++ -o IHTP_Validator.exe IHTP_Validator.ccthen you can run it using:
./IHTP_Validator.exe INSTANCE.json SOLUTION.jsonTo run competition instances singularly:
./tester/IHTP_Validator.exe ./datasets/ihtc2024_competition_instances/i01.json ./results/solution_i01.jsonThe test.sh file allows for a single run of all the instances. It automatically compile the validator and runs all the tests. Note that is made for Mac OS and unix systems.
Such a test is currently given for the final instances (that we call 'm'), but comments are left to easly adapt and run it with the public instances (that we call 'i').
NOTE: it may be the case that you need to give the shell file permissions. I.e.,
chmod +x test.sh
./test.shWhile running the solver, the class Solution can evaluate the solution directly in Python, but first, you must have the package pybind11. To check for it:
python3 -m pip show pybind11
to install so:
python3 -m pip install pybind11To get the solution validator, go to the folder solution and run:
-
For Ubuntu:
c++ -O3 -Wall -shared -std=c++17 -fPIC `python3 -m pybind11 --includes` Validator.cpp -o Validator`python3-config --extension-suffix`
this will create a
.sofile that can be used by python. -
For Mac arm64:
c++ -O3 -Wall -shared -std=c++17 -undefined dynamic_lookup `python3 -m pybind11 --includes` Validator.cpp -o Validator`python3-config --extension-suffix`
At this point, the method eval of the solution class should hopefully work.
In general, the Solution.py file with the correspondent class, inside the solution folder, manages the connection between the two phases of the solver and also works as formatter to provide the solution in a JSON that meets the requirements of IHTC-2024.
The actual solvers are in the folder solver. The solver for SCP and PAS with a predictive decomposition is HPT__SCCPAS.py. The file is hopefully adequately commented, but for the mathematical foundation of it, it is necessary to check the article given at the beginning of this README. the NRA.py file contains the NRA solver and the same applies to it. In the file two__stage__seq__solver.py, there is the class that connects the two solvers by managing time constraints and populating the gurobi models. The classes have hierarchical abstracts and are intedended for more general solvers than what is actually presented. In fact, they supported also other draft sovlers that we then did not use for the challenge.
To run all the framework, a main.py is given as example. FIxing the available time, it first check the Gurobi version (as for version newer than 9, it seems that the model building time completely jeopardize a rolling strategy), and then allows for running datasets in batches. A verbose option provide more accurate informations and recursively set the verbose in Gurobi.