A flexible web application designed to streamline and automate nurse scheduling, suitable for a wide range of diverse and complex real-world requirements.
- Stable version (frontend-only) hosted on Netlify.
- Development version hosted on Netlify.
- Documentation hosted on Netlify.
- Source code hosted on GitHub.
The nurse scheduling (or employee scheduling) problem is a well-known problem in the field of operations research (OR) and can be (approximately) solved efficiently by constrained optimization.
However, constraints can differ greatly between hospitals and wards, and there is currently no unified framework for modeling these diverse requirements. Most existing literature focuses on modeling an over-simplified constraint set, which is not applicable to real-world situations. Therefore, in practice, the problem is still often solved by hand with the help of Excel, which is often extremely time-consuming. The entire process requires several hours or even more than ten hours, depending on the problem complexity (e.g., co-scheduling of multiple understaffed wards).
This project (Nurse Scheduling System, or 護理排班系統 in Mandarin) aims to develop a flexible web app to automate the nurse scheduling task, and to provide a unified framework for modeling all types of real-world scenarios without sacrificing flexibility.
This project is in active development. Breaking changes may occur without notice. Please proceed with caution. Although the current version has been verified by domain experts and used successfully (with minimal post-adjustment) in several complex multi-ward scenarios involving up to ~100 nurses, it currently has a steep learning curve and lacks proper documentation.
- bun.
- uv
- Docker (optional, for Docker-based development environment and GPU solver).
- NVIDIA Container Toolkit (optional, for GPU solver).
These are not hard requirements. If you know what you are doing, you can also use other tools to manage dependencies, such as nvm/npm for Next.js, and virtualenv or conda for Python.
git clone https://github.com/j3soon/nurse-scheduling.git
cd nurse-schedulingFor Linux only: to quickly set up all local environments (core, web-frontend, and docs) in one go, run:
./scripts/setup_env.shFor Docker-based development environment:
# build image
docker build -f Dockerfile -t j3soon/nurse-scheduling:dev .
# or optionally with cuOpt
docker build -f Dockerfile.cuopt -t j3soon/nurse-scheduling:dev-cuopt .CPU solver:
# persist Codex auth/config across containers
mkdir -p ~/docker/.codex
# mount project files and Codex config
docker run --rm -it --network=host \
-v $(pwd):/app \
-v ~/docker/.codex:/root/.codex \
j3soon/nurse-scheduling:devGPU solver:
# persist Codex auth/config across containers
mkdir -p ~/docker/.codex
# mount project files and Codex config
docker run --rm -it --gpus all --network=host \
-v $(pwd):/app \
-v ~/docker/.codex:/root/.codex \
j3soon/nurse-scheduling:dev-cuoptcd web-frontend
bun install
bun run devFor building static site, run:
cd web-frontend
bun run buildFor linting, run:
cd web-frontend
bun run lint -- --fix
buncan be replaced directly withnpm.
We currently support three solvers: OR-Tools/CP-SAT, PuLP/CBC, and PuLP/cuOpt.
ortools/cp-satis the default solver and the most battle-tested one.pulp/cbcis only tested on basic test cases and now well-tested on real scenarios.pulp/cuoptis the GPU-accelerated solver, which is also only tested on basic test cases. Due to its GPU requirement, it is not currently included in CI testing.
cd core
# create virtual environment
uv venv --python 3.12
# activate virtual environment
source .venv/bin/activate
# install dependencies
uv pip install -r requirements.txt
# run CLI with default solver (ortools/cp-sat)
python -m nurse_scheduling.cli <input_file_path> [output_csv_path]
# for example:
python -m nurse_scheduling.cli tests/testcases/basics/01_1nurse_1shift_1day.yaml
# run CLI with PuLP/CBC solver
python -m nurse_scheduling.cli <input_file_path> [output_csv_path] --solver pulp/cbc
# explicit OR-Tools/CP-SAT selector
python -m nurse_scheduling.cli <input_file_path> [output_csv_path] --solver ortools/cp-sat
# run CLI with prettify and verbose
python -m nurse_scheduling.cli <input_file_path> [output_xlsx_path] --verbose --prettifyRun tests:
cd core
# run low-level solver encoding tests
pytest --log-cli-level=INFO tests/test_solver_ortools_cp_sat.py
pytest --log-cli-level=INFO tests/test_solver_pulp_cbc.py
pytest --log-cli-level=INFO tests/test_solver_pulp_cuopt.py
# run schedule regression tests (OR-Tools / PuLP)
pytest --log-cli-level=INFO tests/test_schedule_ortools_cp_sat.py
pytest --log-cli-level=INFO tests/test_schedule_pulp_cbc.py
pytest --log-cli-level=INFO tests/test_schedule_pulp_cuopt.py
# run the full core test suite
pytest --log-cli-level=INFO
# run basic Python lint checks for core
ruff check nurse_scheduling testsFor more debugging output when a test fails:
cd core
pytest --log-cli-level=DEBUG tests/test_solver_ortools_cp_sat.py
pytest --log-cli-level=DEBUG tests/test_solver_pulp_cbc.py
pytest --log-cli-level=DEBUG tests/test_schedule_ortools_cp_sat.py
pytest --log-cli-level=DEBUG tests/test_schedule_pulp_cbc.pyNote that setting WRITE_TO_CSV=True in core/tests/schedule_test_helper.py is often useful for creating new test cases.
Note: The tests and code coverage are only for the core module. The web frontend is not covered by tests.
cd core/nurse_scheduling
# development mode
fastapi dev serve.py
cd ..
# run curl (needs to be run after the server is running)
./tests/test_serve_curl.sh
# run serve tests (don't need to be run after the server is running)
python tests/test_serve.py
# or
pytest tests/test_serve.py --log-cli-level=INFO(TODO: Production mode instructions are not yet completed.)
cd docs
# create virtual environment
uv venv --python 3.12
# activate virtual environment
source .venv/bin/activate
# install dependencies
uv pip install -r requirements.txt
# preview documentation
mkdocs serveFor building static site, run:
cd docs
mkdocs buildThis project would not have been possible without the contributions of @ijsun and Jennifer Tzeng.
You can find the full list of code contributors here.
This project is licensed under the AGPL-3.0 License.