Balancing Nurses and Beds Across Patient Populations
Palliative care programs operate under a hard truth: nursing staff and bed capacity are always scarcer than the need for them. A hospital or hospice network typically serves several distinct patient populations — terminally ill patients requiring intensive symptom control, patients with complex multi-symptom needs, those needing psychosocial and family support, short-term respite cases, and patients preparing to transition home. Each of these groups benefits differently from an additional nurse or an additional bed, and none of them benefit linearly — care quality shows diminishing returns as resources pile up in one place while other units go understaffed.
This is a textbook constrained optimization problem, and today we’ll build a full mathematical model and solve it in Python.
Formulating the Problem
We define $i = 1, \dots, 5$ patient care categories (wards). For each ward, the decision variables are the number of nurses $n_i$ and the number of beds $b_i$ assigned to it.
The clinical benefit derived from a ward’s staffing is modeled with a Cobb-Douglas-style diminishing-returns function:
$$
B_i(n_i, b_i) = w_i \cdot n_i^{\alpha_i} \cdot b_i^{\beta_i}
$$
where $w_i$ is a clinical priority weight reflecting acuity and patient volume, and $\alpha_i, \beta_i \in (0,1)$ capture the diminishing marginal value of adding more staff or beds to an already well-resourced ward.
The full optimization problem is:
$$
\max_{n_i, b_i} \sum_{i=1}^{5} w_i , n_i^{\alpha_i} , b_i^{\beta_i}
$$
subject to:
$$
\sum_{i=1}^{5} n_i = N_{\text{total}}, \qquad \sum_{i=1}^{5} b_i = B_{\text{total}}
$$
$$
r_{\min} , b_i \le n_i \le r_{\max} , b_i \quad \text{for all } i
$$
The ratio constraint is essential in clinical practice: no ward should be understaffed relative to its bed count (a patient safety floor), nor should nurses be piled onto a ward far beyond what its beds can use (an efficiency ceiling).
This is a nonlinear, constrained, continuous optimization problem — a natural fit for Sequential Least Squares Programming (SLSQP).
The Code
1 | import numpy as np |
======================================================================
PALLIATIVE CARE RESOURCE ALLOCATION - OPTIMIZATION RESULT
======================================================================
Ward Nurses (opt) Beds (opt) Nurses (equal split) Beds (equal split) Benefit (opt) Benefit (equal)
Terminal/High-Acuity 56.0 36.0 12.0 8.0 68.854 14.998
Complex Symptom Mgmt 1.0 1.0 12.0 8.0 1.300 12.737
Psychosocial & Family 1.0 1.0 12.0 8.0 1.000 9.601
Respite/Short-Term 1.0 1.0 12.0 8.0 0.900 8.818
Home-Transition Prep 1.0 1.0 12.0 8.0 0.800 7.527
----------------------------------------------------------------------
Total benefit (optimized) : 72.8543
Total benefit (equal split) : 53.6817
Improvement over baseline : +35.72%
Optimizer status : Optimization terminated successfully
======================================================================
Walking Through the Code
Setup and parameters. Five wards are defined with priority weights w, and exponents alpha/beta that control how quickly each ward’s benefit saturates as nurses or beds are added. The Terminal/High-Acuity ward has the highest weight (1.5) and leans more heavily on nursing intensity (alpha=0.55) than bed count, reflecting that hands-on symptom management matters more there than physical space. The Home-Transition Prep ward leans the opposite way (beta=0.60), since space for family visits and discharge logistics matters more than nurse-hours per patient.
The solve_allocation function is the heart of the model. It builds an initial guess (an equal split of nurses and beds across wards), then defines:
neg_total_benefit: the objective, negated becausescipy.optimize.minimizeminimizes by default — we want to maximize total benefit.eq_nurses/eq_beds: equality constraints forcing the full nurse and bed budgets to be used exactly.ratio_ineq: a single vectorized inequality constraint returning 10 values at once (5 lower-bound checks and 5 upper-bound checks), which SLSQP evaluates all together. This enforces the safety floor and efficiency ceiling per ward.
Wrapping this in a reusable function means we can call solve_allocation(N, B) with any budget pair — which is exactly what the sensitivity analysis later does, without duplicating logic.
Solving the base case (60 nurses, 40 beds) and comparing it against a naive equal-split baseline lets us quantify how much benefit is left on the table by not optimizing — this is often the single most persuasive number for hospital administrators.
The ratio bounds (RATIO_MIN = 0.30, RATIO_MAX = 3.00) were deliberately chosen wide enough that every budget scenario tested later remains feasible, while still enforcing a meaningful safety/efficiency band. Tight ratio bounds combined with extreme budget imbalances can make the constrained problem infeasible — worth checking before scaling this model to your own ward configuration.
Reading the Results
Figure 1 and Figure 2 (bar charts) show, ward by ward, how nurses and beds shift from the naive equal-split baseline to the mathematically optimal allocation. Expect to see the high-priority, nurse-sensitive wards (like Terminal/High-Acuity) pull in more nurses relative to their bed count, while wards with high beta values pull in relatively more beds. This is the clearest, most administrator-friendly output of the whole analysis — it directly shows “move X nurses from Ward A to Ward B.”


Figure 3 (3D surface) visualizes the benefit landscape for a single ward as a function of its nurse and bed counts. The surface’s curvature is the diminishing-returns effect made visible — it rises steeply at low staffing levels and flattens out as resources pile up, which is exactly why blindly pouring more staff into an already well-resourced ward is inefficient. The marked point shows where the optimizer landed for that ward given the overall budget constraints.

Figure 4 (sensitivity curves) answers the question every resource planner actually cares about: “if we hired 10 more nurses, how much would care quality actually improve?” Both curves show concave, decelerating growth — consistent with the Cobb-Douglas structure — meaning that at some point, adding more of one resource type yields shrinking returns unless the other resource (beds, or vice versa) is scaled up in tandem. The vertical dashed line marks the current budget, letting you see at a glance whether you’re operating in the steep part of the curve (where more investment pays off quickly) or the flat part (where it doesn’t).

Why This Matters Beyond the Numbers
The elegance of this formulation is that it doesn’t just produce “an answer” — it produces a tunable model. Swap in your own ward definitions, adjust the priority weights to reflect your institution’s clinical values, tighten or loosen the safety ratios to match regulatory minimums, and rerun. The sensitivity curves in particular are valuable for budget negotiations: they turn “we need more staff” into “here is precisely how much benefit the next 10 nurses would produce, and here is the point of diminishing returns.”
One limitation worth noting: this model treats benefit as static and deterministic. A natural extension is to make w_i time-varying (patient census fluctuates by season) or to add stochastic elements (unpredictable admission surges), which would turn this into a stochastic or dynamic programming problem — a good topic for a follow-up post.






























