Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Lecture 9: Set Covering and Shift Scheduling

Open In Colab

This notebook covers the set cover and covering problems, and their main practical use, shift scheduling: choosing the cheapest set of shifts (or facilities) that between them cover every point that needs covering (an hour, a location, ...). Unlike the transportation problem, integrality is essential here. Both problems are introduced in the same steps as the transportation problem: practical motivation, generic model, the model for an example, its solution in pulp, and extensions.

Learning outcomes

On completion of this notebook, you will be able to:

  • formulate set cover and covering problems as ILO models;

  • explain why the integrality constraints cannot be dropped in a set cover problem;

  • formulate shift-scheduling problems as covering problems and solve them with pulp.

The Set Cover Problem

Practical Motivation

An ambulance service wants to open as few ambulance bases as possible, while every address in its region can still be reached from some base within the target response time (in the Netherlands, 15 minutes). For every candidate location we know which addresses it can reach in time; the question is which candidates to open. Fire stations, police posts and parcel lockers lead to the same question. A less obvious application comes from IBM, which used it for efficient virus scanning: instead of scanning for every known virus signature, scan for a small collection of code fragments that between them occur in all known viruses.

Modeling

Problem Definition and Example

We have a universe U={1,…,m}U = \{1, \dots, m\} of elements that must be covered, and nn sets S1,…,SnS_1, \dots, S_n with Si⊆US_i \subseteq U. The problem is to find the smallest collection of these sets whose union is all of UU. In the ambulance application, UU is the set of addresses and SiS_i the set of addresses that candidate base ii reaches in time.

As an example, a region has six incident locations, U={1,…,6}U = \{1, \dots, 6\}, and six candidate bases B1, ..., B6, which reach the following locations in time:

baseB1B2B3B4B5B6
locations reached1, 2, 32, 3, 44, 55, 61, 63, 4, 5

Decision Variables

For every set we decide whether to take it or not, which is a yes/no decision. We model it with a binary decision variable per set:

xi={1if set Si is taken,0otherwise,i=1,…,n.x_i = \begin{cases} 1 & \text{if set } S_i \text{ is taken,} \\ 0 & \text{otherwise,} \end{cases} \quad i = 1, \dots, n.

Which set contains which element is data, not a decision. For the constraints it is handy to turn this data around: for every element uu, let

Iu={ i∈{1,…,n}∣u∈Si }I_u = \{\, i \in \{1, \dots, n\} \mid u \in S_i \,\}

be the index set of the sets that contain uu. In the example, location 1 is reached by B1 and B5, so I1={1,5}I_1 = \{1, 5\}. An index set derived from the data like this is a common way to sum over only the terms that matter.

Objective

We minimize the number of sets taken, ∑i=1nxi\sum_{i=1}^{n} x_i.

Constraints

Every element uu must be in at least one of the sets taken. The number of sets taken that contain uu is ∑i∈Iuxi\sum_{i \in I_u} x_i, since only the sets in IuI_u contain uu. So, for every u∈Uu \in U,

∑i∈Iuxi≥1.\sum_{i \in I_u} x_i \ge 1.

We use “≥1\ge 1” and not “=1= 1”: an element may well be covered twice (two bases that both reach an address). Requiring exactly one would be a different, much more restrictive problem that often has no feasible solution at all. Finally, xi∈{0,1}x_i \in \{0, 1\}.

Complete ILO Model

min⁡∑i=1nxis.t.∑i∈Iuxi≥1,u∈Uxi∈{0,1},i=1,…,n.\begin{aligned} \min \quad & \sum_{i=1}^{n} x_i \\ \text{s.t.} \quad & \sum_{i \in I_u} x_i \ge 1, \quad u \in U \\ & x_i \in \{0, 1\}, \quad i = 1, \dots, n. \end{aligned}

Modeling the Example

With x1,…,x6x_1, \dots, x_6 for bases B1, ..., B6, each location gives one constraint, with the bases that reach it:

min⁡x1+x2+x3+x4+x5+x6s.t.x1+x5≥1(cover location 1)x1+x2≥1(cover location 2)x1+x2+x6≥1(cover location 3)x2+x3+x6≥1(cover location 4)x3+x4+x6≥1(cover location 5)x4+x5≥1(cover location 6)xi∈{0,1},i=1,…,6.\begin{aligned} \min \quad & x_1 + x_2 + x_3 + x_4 + x_5 + x_6 \\ \text{s.t.} \quad & x_1 + x_5 \ge 1 & \text{(cover location 1)} \\ & x_1 + x_2 \ge 1 & \text{(cover location 2)} \\ & x_1 + x_2 + x_6 \ge 1 & \text{(cover location 3)} \\ & x_2 + x_3 + x_6 \ge 1 & \text{(cover location 4)} \\ & x_3 + x_4 + x_6 \ge 1 & \text{(cover location 5)} \\ & x_4 + x_5 \ge 1 & \text{(cover location 6)} \\ & x_i \in \{0, 1\}, \quad i = 1, \dots, 6. \end{aligned}

Solving the Example in pulp

The binary variables (cat="Binary") are similarly setup as in the knapsack problem. New is the derived index set: the data is stored as the sets themselves (a Python set per base), and the sum ∑i∈Iuxi\sum_{i \in I_u} x_i becomes a sum over only those bases whose set contains uu, written with an if inside the generator. We do not necessarily have to build IuI_u separately.

status: Optimal
bases: ['B2', 'B4', 'B5']

Three bases suffice. Two cannot: location 6 is only reached by B4 and B5. With B4, a second base would have to reach locations 1 to 4, and with B5 it would have to reach locations 2 to 5, and no base does either.

Extensions

Are the Integrality Constraints Needed?

In the transportation problem, we could drop integrality and still get whole numbers. Here we cannot. Take the small instance U={1,2,3}U = \{1, 2, 3\} with S1={1,2}S_1 = \{1, 2\}, S2={1,3}S_2 = \{1, 3\}, S3={2,3}S_3 = \{2, 3\}. No single set covers UU, so the integer optimum is 2 (any two sets). But the LO relaxation, with 0≤xi≤10 \le x_i \le 1 instead of xi∈{0,1}x_i \in \{0, 1\}, can set every xi=12x_i = \tfrac12: each element is then covered by 12+12=1\tfrac12 + \tfrac12 = 1, at total “cost” 1.5. Adding the three constraints gives 2(x1+x2+x3)≥32(x_1 + x_2 + x_3) \ge 3, so the relaxation can never beat 1.5, and rounding the 0.5’s up gives all three sets, which is worse than the true optimum of 2.

The Covering Problem

The covering problem generalizes set cover in three ways: each element uu must be covered bub_u times instead of once, a set may be chosen more than once (xi∈{0,1,2,… }x_i \in \{0, 1, 2, \dots\}), and each set ii has a cost cic_i:

min⁡∑i=1ncixis.t.∑i∈Iuxi≥bu,u∈Uxi∈{0,1,2,… },i=1,…,n.\begin{aligned} \min \quad & \sum_{i=1}^{n} c_i x_i \\ \text{s.t.} \quad & \sum_{i \in I_u} x_i \ge b_u, \quad u \in U \\ & x_i \in \{0, 1, 2, \dots\}, \quad i = 1, \dots, n. \end{aligned}

With bu=1b_u = 1 and xix_i binary, it is a set cover problem in which bases have different costs. Its main application, shift scheduling, is the next problem.

Shift Scheduling

Practical Motivation

A shop, a call center or a hospital ward needs a certain number of staff at work in every hour of the day, and that number varies over the day. Staff are hired for shifts of fixed types (a morning shift, a full-day shift, ...), each with its own cost. How many workers should be scheduled on each shift type, so that every hour has enough staff at the lowest total cost? The required staffing per hour typically comes from a demand forecast (predictive analytics). Dantzig studied this problem in 1954 for the staffing of toll booths.

Modeling

Problem Definition and Example

Shift scheduling is a covering problem. Split the day into time intervals U={1,…,m}U = \{1, \dots, m\}, and let bub_u be the required staffing in interval uu. Each of the nn shift types ii works a set Si⊆US_i \subseteq U of intervals and costs cic_i per worker. As before, Iu={ i∈{1,…,n}∣u∈Si }I_u = \{\, i \in \{1, \dots, n\} \mid u \in S_i \,\} is the index set of the shift types that work in interval uu. The problem is to find the cheapest number of workers per shift type such that every interval has at least its required staffing.

As an example, a small shop is open from 8:00 to 12:00 (four one-hour intervals) and has four shift types:

shift typemorningmiddaylatefull
works8-109-1110-128-12
intervals SiS_i1, 22, 33, 41, 2, 3, 4
cost cic_i (€)30303050

The required staffing is b=(3,6,7,4)b = (3, 6, 7, 4) for the intervals 8-9, 9-10, 10-11 and 11-12.

Decision Variables

Several workers can work the same shift type, so taking a set is no longer a yes/no decision but a number:

xi=number of workers scheduled on shift type i,i=1,…,n,x_i = \text{number of workers scheduled on shift type } i, \quad i = 1, \dots, n,

with xi∈{0,1,2,… }x_i \in \{0, 1, 2, \dots\}, since we cannot schedule half a worker.

Objective

We minimize the total staff cost, ∑i=1ncixi\sum_{i=1}^{n} c_i x_i.

Constraints

The number of workers present in interval uu is the sum of the workers on all shift types in IuI_u, which must be at least the requirement:

∑i∈Iuxi≥bu,u∈U.\sum_{i \in I_u} x_i \ge b_u, \quad u \in U.

Overstaffing is allowed (“≥\ge”): with fixed shift lengths it is often unavoidable, since a worker needed in one interval may also be present in a quieter one.

Complete ILO Model

min⁡∑i=1ncixis.t.∑i∈Iuxi≥bu,u∈Uxi∈{0,1,2,… },i=1,…,n.\begin{aligned} \min \quad & \sum_{i=1}^{n} c_i x_i \\ \text{s.t.} \quad & \sum_{i \in I_u} x_i \ge b_u, \quad u \in U \\ & x_i \in \{0, 1, 2, \dots\}, \quad i = 1, \dots, n. \end{aligned}

This is exactly the covering problem from the previous section.

Modeling the Example

With x1,x2,x3,x4x_1, x_2, x_3, x_4 the number of morning, midday, late and full shifts:

min⁡30x1+30x2+30x3+50x4s.t.x1+x4≥3(8-9)x1+x2+x4≥6(9-10)x2+x3+x4≥7(10-11)x3+x4≥4(11-12)xi∈{0,1,2,… },i=1,…,4.\begin{aligned} \min \quad & 30x_1 + 30x_2 + 30x_3 + 50x_4 \\ \text{s.t.} \quad & x_1 + x_4 \ge 3 & \text{(8-9)} \\ & x_1 + x_2 + x_4 \ge 6 & \text{(9-10)} \\ & x_2 + x_3 + x_4 \ge 7 & \text{(10-11)} \\ & x_3 + x_4 \ge 4 & \text{(11-12)} \\ & x_i \in \{0, 1, 2, \dots\}, \quad i = 1, \dots, 4. \end{aligned}

Solving the Example in pulp

The code has the same shape as the set cover code. The only change in the variables is cat="Integer" with lowBound=0, which gives xi∈{0,1,2,… }x_i \in \{0, 1, 2, \dots\}, and the constraints now have the right-hand side need instead of 1.

status: Optimal
roster: {'morning': 0.0, 'midday': 3.0, 'late': 1.0, 'full': 3.0}
total cost: 270.0

The optimal roster has 3 midday, 1 late and 3 full shifts, at a cost of €270. Every requirement is met exactly, so here there is no overstaffing.

Extensions

More Realistic Shifts

Real instances have many more intervals (for example, half hours over a whole day) and many more shift types, with different lengths, start times and breaks.

Not Meeting Every Requirement

Requiring bub_u staff in every interval can be expensive when a single peak interval forces extra shifts. An alternative is to allow under- and overstaffing and penalize both in the objective. This needs the modeling trick for absolute values from Robust Regression.

Interactions Between Intervals

Here the required staffing per interval is given. In a call center, understaffing in one interval leaves a queue of waiting callers for the next one, so the requirements depend on the schedule itself. Then only simulation can evaluate a schedule; see Local Search.

References

  • Koole, G. (2019). An Introduction to Business Analytics. §6.5 “Example ILO Problems” (covering). Spreadsheet material replaced with pulp.