Column generation approach to tour / shift creation
The purpose of this Repo is for me to experiment with column generation using an easy example.
Consider the problem of creating work shifts for some company.
The company has a set of tasks
- Local constraints: for each
$i \in {1, \dots, n-1}$ , the transition from$t_i$ to$t_{i+1}$ must be possible (enough time between the tasks, transition between end location of$t_i$ and the start location of$t_{i+1}$ possible etc.) - Global constrains: the whole sequence must conform to labor rules such as maximal work time, break rules, etc. Since the number of shifts corresponds to the number of employees that are required to perform all the tasks, a sensible goal is to find a minimum number of shifts that covers all tasks.
Imagine for a moment that we can generate all possible legal shifts
- The total duration of
$p$ (i.e. end time of the last task minus the start time of the first task) is at most$D_\max$ - Continuous work time without a break does not exceed
$D_\text{break}$ - The start location of the first task and the end location of the last task are the same (think of train drivers)
- All transitions between adjacent tasks are possible (space and time)
We could then formulate the following MILP problem:
Every shift p has an associated choice-variable
The advantage of this approach is that the checking of tour-validity and the optimal selection of a set of tours are decoupled.
The disadvantage is that the size of set
The idea of column generation is to work with a limited subset of all shifts
Consider the general linear program
Where
Given some basic solution
The coefficient of the non-basic variable
In column generation, we use the expression for the reduced cost, to check if there are additional candidate variables (shifts, in our case), that are currently outside of the pool of variables
The expression we need to minimize is a bit unwieldy. LP duality theory provides us with a nice way to avoid having to compute matrix inverses. The following LP is called the dual of the above generic LP (we call it the primal):
Duality theory provides many interesting results about the relationship between an LP and its dual. Here we need the following two facts:
- Complementary slackness / KKT conditions: If
$x$ is the optimal solution of the primal and$y$ ,$w$ is the optimal solution of the dual, then holds$x^T \cdot w = 0$ - Given an optimal solution to the primal, we can easily get an optimal solution to the dual. In particular, standard solvers allow accessing the dual solution after having computed the optimal primal solution.
Using the definition of the dual above and the first fact, we can simplify the expression for
Let
Thus we get the simpler expression for the reduced cost of non-basic variable
To apply the above approach for shift planning we need to find a way to efficiently minimize
-
$y$ is the vector of the optimal dual variables in step$i$ . We get this vector from the solver and don't need to worry about it. -
$A_j$ is the$j$ -th column of the constraint matrix$A$ of the generic LP. Every constraint in the concrete LP we want to solve (the RMP from above) looks as follows:$\sum_{p \in P \land t \in p} x_p = 1$ . We have such a constraint for every task$t$ . Mentally transposing this we understand that$A$ has a column for every shift$p \in \tilde{P}$ . Since we are interested in candidate shifts that are not yet part of$\tilde{P}$ , we need to imagine what the column of$A$ for such a shift would be.$A_j$ has binary entries, one entry for every task$t$ where an entry is$1$ if task$t$ is covered by shift$j$ . -
$c_j$ is the coefficient of shift$j$ in the objective. This is one for every shift, so$c_j = 1$
Thus the reduced cost of some shift-candidate