This COVID-19 Healthcare Facility Capacity Optimization problem shows you how to determine the optimal location and capacity of healthcare facilities in order to:

- Satisfy demand from COVID-19 patients for treatment,
- Minimize the cost of opening temporary facilities for healthcare providers, and
- Predict the allocation of COVID-19 patients from a specific county to a specific healthcare facility.

This modeling example is at the beginner level, where we assume that you know Python and that you have some knowledge of how to build mathematical optimization models.

**Download the Repository**

You can download the repository containing this and other examples by clicking here.

**Gurobi License**

In order to run this Jupyter Notebook properly, you must have a Gurobi license. If you do not have one, you can request an evaluation license as a *commercial user*, or download a free license as an *academic user*.

Hospitals in various counties throughout the US are reaching full capacity due to a surge in COVID-19 patients. Many hospitals are considering creating temporary facilities to increase their capacity to handle COVID-19 patients.

In this example, we focus on nine counties in the US. Each county has existing facilities to treat COVID-19 patients, and also has the option of building temporary facilities to increase the overall capacity to handle COVID-19 patients.

The following table defines the coordinates of the centroid and the forecasted demand (i.e. the projected number of COVID-19 patients) of each county. To estimate this demand, we consider the population of nine fictional counties in California, the current number of COVID-19 cases per day in California, the average percentage of COVID-19 cases who require hospitalization, and the average number of days that a COVID-19 patient stays in the hospital.

Centroid | Coordinates | Demand |
---|---|---|

county 1 | (1, 1.5) | 351 |

county 2 | (3, 1) | 230 |

county 3 | (5.5, 1.5) | 529 |

county 4 | (1, 4.5 ) | 339 |

county 5 | (3, 3.5) | 360 |

county 6 | (5.5, 4.5) | 527 |

county 7 | (1, 8) | 469 |

county 8 | (3, 6) | 234 |

county 9 | (4.5, 8) | 500 |

The following table defines the coordinates and capacity of existing facilities. The capacity of existing facilities is calculated as 80% of the forecasted demand of the county in which the existing facilities are located. The exception to this is county 9, where we assume that we have an excess of existing capacity.

Existing | Coordinates | Capacity |
---|---|---|

facility 1 | (1, 2) | 281 |

facility 2 | (2.5, 1) | 187 |

facility 3 | (5, 1) | 200 |

facility 4 | (6.5, 3.5) | 223 |

facility 5 | (1, 5) | 281 |

facility 6 | (3, 4) | 281 |

facility 7 | (5, 4) | 222 |

facility 8 | (6.5, 5.5) | 200 |

facility 9 | (1, 8.5) | 250 |

facility 10 | (1.5, 9.5) | 125 |

facility 11 | (8.5, 6) | 187 |

facility 12 | (5, 8) | 300 |

facility 13 | (3, 9) | 300 |

facility 14 | (6, 9) | 243 |

The following table defines the coordinates and capacity of new temporary facilities. The cost of building a temporary facility with a capacity of treating one hundred COVID-19 patients is $\$500,000$.

Temporary | Coordinates | Capacity |
---|---|---|

facility 15 | (1.5, 1) | 100 |

facility 16 | (3.5, 1.5) | 100 |

facility 17 | (5.5, 2.5) | 100 |

facility 18 | (1.5, 3.5) | 100 |

facility 19 | (3.5, 2.5) | 100 |

facility 20 | (4.5, 4.5) | 100 |

facility 21 | (1.5, 6.5) | 100 |

facility 22 | (3.5, 6.5) | 100 |

facility 23 | (5.5, 6.5) | 100 |

The coordinates of the three tables are in tens of miles. We assume that each increase of 10 miles in the distance to a COVID-19 facility results in a $\$5$ increase in driving costs for each COVID-19 patient.

In this example, the goal is to identify which temporary facilities to build in order to be able to accommodate demand for treatment by COVID-19 patients while minimizing the total cost of COVID-19 patients driving to an existing or temporary COVID-19 facility and the total cost of building temporary facilities.

This example shows how a Facility Location mixed-integer programming (MIP) model can help healthcare providers make decisions about:

- How to best utilize their capacity,
- Whether to build temporary facilities for COVID-19 patients, and
- How COVID-19 patients from a county should be allocated to various healthcare facilities in order to ensure that the facilities have the capacity to provide treatment for the patients.

This Jupyter Notebook is based on the paper written by Katherine Klise and Michael Bynum [1].

$e \in E$: Index and set of existing healthcare facility locations.

$t \in T$: Index and set of temporary healthcare facility locations.

$f \in F = E \cup T$: Index and set of all healthcare facility locations.

$c \in C$: Index and set of counties.

$Dist_{c,f} \in \mathbb{R}^+$: Distance between county $c$ and facility location $f$.

$Dem_{c} \in \mathbb{R}^+$: Expected number of people in county $c$ who will need a COVID-19 facility.

$Cap_{f} \in \mathbb{R}^+$: Number of people that can be served by a facility at location $f$.

$\text{dCost} = 5$: Cost of driving 10 miles.

$\text{tFCost} = 500,000$: Cost of building a temporary COVID-19 facility with a capacity of treating 100 COVID-19 patients.

$bigM$: Penalty of adding extra capacity at temporary facilities in order to satisfy treatment of COVID-19 patients demand.

$y_{t} \in \{0, 1 \}$: This variable is equal to 1 if we build a temporary facility at location $t$; and 0 otherwise.

$ x_{c,f} \in \mathbb{R}^+$: Number of people from county $c$ served by a facility at location $f$.

$z_{t} \in \mathbb{R}^+$: Extra capacity added at temporary facility location $t$.

**Cost**. We want to minimize the total cost of patients driving from a county to a healthcare facility and the total cost of building temporary COVID-19 treatment capacity. The last term with the big penalty coefficient ($bigM$), enables extra capacity to be added at a temporary facility to ensure that total demand is satisfied.

**Demand**. Satisfy county demand of service from a COVID-19 facility.

**Existing facilities**. Capacity of an existing location of a facility cannot be exceeded.

**Temporary facilities**. Capacity of a temporary location of a facility cannot be exceeded. Please observe that extra capacity can be added.

In [1]:

```
from itertools import product
from math import sqrt
import gurobipy as gp
from gurobipy import GRB
# tested with Gurobi v9.1.0 and Python 3.7.0
```

`compute_distance`

computes distance between a county centroid and the location of a facility`solve_covid19_facility`

builds, solves, and prints results of the COVID-19 healthcare facility capacity optimization model

In [2]:

```
def compute_distance(loc1, loc2):
# This function determines the Euclidean distance between a facility and a county centroid.
dx = loc1[0] - loc2[0]
dy = loc1[1] - loc2[1]
return sqrt(dx*dx + dy*dy)
```

In [3]:

```
def solve_covid19_facility(c_coordinates, demand):
#####################################################
# Data
#####################################################
# Indices for the counties
counties = [*range(1,10)]
# Indices for the facilities
facilities = [*range(1,24)]
# Create a dictionary to capture the coordinates of an existing facility and capacity of treating COVID-19 patients
existing, e_coordinates, e_capacity = gp.multidict({
1: [(1, 2), 281],
2: [(2.5, 1), 187],
3: [(5, 1), 200],
4: [(6.5, 3.5), 223],
5: [(1, 5), 281],
6: [(3, 4), 281],
7: [(5, 4), 222],
8: [(6.5, 5.5), 200],
9: [(1, 8.5), 250],
10: [(1.5, 9.5), 125],
11: [(8.5, 6), 187],
12: [(5, 8), 300],
13: [(3, 9), 300],
14: [(6, 9), 243]
})
# Create a dictionary to capture the coordinates of a temporary facility and capacity of treating COVID-19 patients
temporary, t_coordinates, t_capacity = gp.multidict({
15: [(1.5, 1), 100],
16: [(3.5, 1.5), 100],
17: [(5.5, 2.5), 100],
18: [(1.5, 3.5), 100],
19: [(3.5, 2.5), 100],
20: [(4.5, 4.5), 100],
21: [(1.5, 6.5), 100],
22: [(3.5, 6.5), 100],
23: [(5.5, 6.5), 100]
})
# Cost of driving 10 miles
dcost = 5
# Cost of building a temporary facility with capacity of 100 COVID-19
tfcost = 500000
# Compute key parameters of MIP model formulation
f_coordinates = {}
for e in existing:
f_coordinates[e] = e_coordinates[e]
for t in temporary:
f_coordinates[t] = t_coordinates[t]
# Cartesian product of counties and facilities
cf = []
for c in counties:
for f in facilities:
tp = c,f
cf.append(tp)
# Compute distances between counties centroids and facility locations
distance = {(c,f): compute_distance(c_coordinates[c], f_coordinates[f]) for c, f in cf}
#####################################################
# MIP Model Formulation
#####################################################
m = gp.Model('covid19_temporary_facility_location')
# Build temporary facility
y = m.addVars(temporary, vtype=GRB.BINARY, name='temporary')
# Assign COVID-19 patients of county to facility
x = m.addVars(cf, vtype=GRB.CONTINUOUS, name='Assign')
# Add capacity to temporary facilities
z = m.addVars(temporary, vtype=GRB.CONTINUOUS, name='addCap' )
# Objective function: Minimize total distance to drive to a COVID-19 facility
# Big penalty for adding capacity at a temporary facility
bigM = 1e9
m.setObjective(gp.quicksum(dcost*distance[c,f]*x[c,f] for c,f in cf)
+ tfcost*y.sum()
+ bigM*z.sum(), GRB.MINIMIZE)
# Counties demand constraints
demandConstrs = m.addConstrs((gp.quicksum(x[c,f] for f in facilities) == demand[c] for c in counties),
name='demandConstrs')
# Existing facilities capacity constraints
existingCapConstrs = m.addConstrs((gp.quicksum(x[c,e] for c in counties) <= e_capacity[e] for e in existing ),
name='existingCapConstrs')
# temporary facilities capacity constraints
temporaryCapConstrs = m.addConstrs((gp.quicksum(x[c,t] for c in counties) -z[t]
<= t_capacity[t]*y[t] for t in temporary ),
name='temporaryCapConstrs')
# Run optimization engine
m.optimize()
#####################################################
# Output Reports
#####################################################
# Total cost of building temporary facility locations
temporary_facility_cost = 0
print(f"\n\n_____________Optimal costs______________________")
for t in temporary:
if (y[t].x > 0.5):
temporary_facility_cost += tfcost*round(y[t].x)
patient_allocation_cost = 0
for c,f in cf:
if x[c,f].x > 1e-6:
patient_allocation_cost += dcost*round(distance[c,f]*x[c,f].x)
print(f"The total cost of building COVID-19 temporary healhtcare facilities is ${temporary_facility_cost:,}")
print(f"The total cost of allocating COVID-19 patients to healtcare facilities is ${patient_allocation_cost:,}")
# Build temporary facility at location
print(f"\n_____________Plan for temporary facilities______________________")
for t in temporary:
if (y[t].x > 0.5):
print(f"Build a temporary facility at location {t}")
# Extra capacity at temporary facilities
print(f"\n_____________Plan to increase Capacity at temporary Facilities______________________")
for t in temporary:
if (z[t].x > 1e-6):
print(f"Increase temporary facility capacity at location {t} by {round(z[t].x)} beds")
# Demand satisfied at each facility
f_demand = {}
print(f"\n_____________Allocation of county patients to COVID-19 healthcare facility______________________")
for f in facilities:
temp = 0
for c in counties:
allocation = round(x[c,f].x)
if allocation > 0:
print(f"{allocation} COVID-19 patients from county {c} are treated at facility {f} ")
temp += allocation
f_demand[f] = temp
print(f"{temp} is the total number of COVID-19 patients that are treated at facility {f}. ")
print(f"\n________________________________________________________________________________")
# Test total demand = total demand satisfied by facilities
total_demand = 0
for c in counties:
total_demand += demand[c]
demand_satisfied = 0
for f in facilities:
demand_satisfied += f_demand[f]
print(f"\n_____________Test demand = supply______________________")
print(f"Total demand is: {total_demand:,} patients")
print(f"Total demand satisfied is: {demand_satisfied:,} beds")
```

In this scenario, we consider the data described for the instance of the COVID-19 Healthcare Facility Capacity Optimization problem. The forecasted demand is as defined in the first table of the problem description.

In [4]:

```
# Create a dictionary to capture the coordinates of a county and the demand of COVID-19 treatment
counties, coordinates, forecast = gp.multidict({
1: [(1, 1.5), 351],
2: [(3, 1), 230],
3: [(5.5, 1.5), 529],
4: [(1, 4.5 ), 339],
5: [(3, 3.5), 360],
6: [(5.5, 4.5), 527],
7: [(1, 8), 469],
8: [(3, 6), 234],
9: [(4.5, 8), 500]
})
# find the optimal solution of the base scenario
solve_covid19_facility(coordinates, forecast)
```

The optimal total cost of building COVID-19 temporary healthcare facilities is $\$1,500,000$, and three COVID-19 temporary healthcare facilities are built. The total cost of allocating COVID-19 patients to healthcare facilities is $\$21,645$, and no extra capacity needs to be added to accommodate the demand for treatment from COVID-19 patients.

The MIP model also determines the expected number of COVID-19 patients of a county allocated to a healthcare facility. For example, 6 COVID-19 patients from county 3, 50 COVID-19 patients from county 5, and 166 COVID-19 patients from county 6 are expected to be treated at facility 7. The total number of COVID-19 patients expected to be treated at facility 7 is 222.

Assume that the Centers for Disease Control and Prevention (CDC) announced that the number of hospitalizations will increase by 20%. This percentage includes 5% of buffer capacity to account for the variability of the expected demand.

In [5]:

```
# Increase in demand by 20%.
for c in counties:
forecast[c] = round(1.2*forecast[c])
# find the optimal for scenario 1
solve_covid19_facility(coordinates, forecast)
```

The optimal total cost of building temporary COVID-19 healthcare facilities is $\$4,500,000$, and nine temporary COVID-19 healthcare facilities are built. The total cost of allocating COVID-19 patients to healthcare facilities is $\$25,520$, and 40 and 27 beds need to be added at temporary healthcare facilities 15 and 17, respectively.

Please note that in this scenario, the system is overloaded and all COVID-19 healthcare facilities are operating at full capacity. In addition, extra capacity needs to be added at some temporary healthcare facilities.

In this example, we addressed the COVID-19 Healthcare Facility Capacity Optimization problem. We determined the optimal location and capacity of healthcare facilities in order to:

- Satisfy demand from COVID-19 patients for treatment,
- Minimize the cost of opening temporary facilities for healthcare providers, and
- Predict the allocation of COVID-19 patients from a specific county to a specific healthcare facility.

We explored two scenarios. In the base scenario, we have enough capacity and need to build three temporary healthcare facilities. Whereas in the alternative scenario (1) with an increase of 20% in the number of COVID-19 patients requiring hospitalization, we need to build nine temporary healthcare facilities and add extra capacity at two of them.

Our COVID-19 Healthcare Facility Location Optimization model can be used by public health officials and healthcare providers to help make strategic decisions about when and where to increase healthcare facility capacity during the COVID-19 pandemic. Also, this strategic model can feed information to a COVID-19 load-balancing dispatching model that is capable of assigning (in real time) COVID-19 patients who require hospitalization to the "right" healthcare facilities.

In addition, our model can feed into a tactical model that determines how capacity should be increased to accommodate any increase in demand. For example, the number medical personnel to be hired, trained, and re-skilled, the rotation of medical personnel, and the amount of equipment (e.g. ventilators, drugs, beds, etc.) needed.

[1] Katherine Klise and Michael Bynum. *Facility Location Optimization Model for COVID-19 Resources*. April 2020. Joint DOE Laboratory Pandemic Modeling and Analysis Capability. SAND2020-4693R.

Copyright © 2020 Gurobi Optimization, LLC