The proposed approach relies on an extension of the S-graph framework to address all parameters of the problem at hand without the need to make any further assumptions atop those stated in Sect. 2. The core of the extension is a model transformation, i.e., providing a mapping between the input data and the S-graph model described in Sects. 2 and 3, respectively. This mapping is described in detail in Sect. 4.1 and summarized formally in Appendix 2. To address the cost-based objective and the travel distance limits, new bounding and feasibility functions had to be defined, which are described in Sects. 4.2 and 4.3. To solve the problem, there is no need to modify the standard S-graph algorithm for UIS-LW storage policy with changeover times. However, for easy understanding, the pseudo code for this algorithm is included in Appendix 3, as this specific version in its entirety has not been presented in the literature before.
Model transformation
The problem at hand is modeled as a precedential batch scheduling problem. Throughout the whole problem UIS storage policy is considered as the order locations can be left without any specialists. To model the various timing constraints of the problem, UIS-LW-arcs are needed. However, the terms ZW-arc and UW-arc are used when referring to (t, t) or \((t,\infty )\) weighted UIS-LW-arcs.
The set of resources R will be the set of cars, i.e., \(R=\mathcal{C}\). As in various applications of the method, 3 special time reference nodes are introduced to the graph: \(\{Z, S, E\}\in N\). These nodes will represent midnight and the start and the end of the shift. To fix the timing between these nodes, a ZW-arc is put between them: \((Z,S, t^{shiftstart},t^{shiftstart}),(Z,E, t^{shiftend},t^{shiftend}) \in A_1\) These three nodes (shown in Fig. 5) provide the frame for the other nodes and do not need to be scheduled or assigned to any resource similarly to the product-nodes of the framework.
Orders
Modeling the orders is rather straightforward. Each task of an order is represented by a node in the graph. Between those that are dependent on each other a recipe-arc is inserted with the weight of the processing time of the preceding task. Formally:
$$\begin{aligned}&(O,I)\in N \qquad \forall O\in \mathcal{O}, I\in \mathcal{I}_{T_O}\\&((O,I_1),(O,I_2),t^{perform}(I_1),\infty )\in A_1 \qquad \forall O\in \mathcal{O}, (I_1,I_2)\in D_{T_O} \end{aligned}$$
For the sake of transparency and keeping S-graph modeling conventions, an additional product-node is generated for each order, i.e., \(N^P = \mathcal{O}\). As usual, a processing time weighted recipe-arc is inserted between all final tasks and the product node:
$$\begin{aligned} ((O,I),O,t^{perform}(I),\infty )\in A_1 \qquad \forall O\in \mathcal{O}, I\in \mathcal{I}^{last}_{T_O} \end{aligned}$$
where \(\mathcal{I}^{last}_{T}\) is the set of tasks in template T that do not have a successor:
$$\begin{aligned} \mathcal{I}^{last}_T=\{I\in \mathcal{I}_T \mid \not \exists I'\in \mathcal{I}_T, (I,I')\in D_T\} \end{aligned}$$
The earliest starting time of an order can easily be expressed by an UW-arc between the special node \(Z\) and the first task or tasks of an order:
$$\begin{aligned} (Z,(O,I),t^{startafter}(O),\infty )\in A_1 \qquad \forall O\in \mathcal{O},I\in \mathcal{I}^{first}_{T_O} \end{aligned}$$
where \(\mathcal{I}^{first}_T\) is the set of tasks in template T that do not have a predecessor,Footnote 1 i.e.:
$$\begin{aligned} \mathcal{I}^{first}_T=\{I\in \mathcal{I}_T \mid \not \exists I'\in \mathcal{I}_T, (I',I)\in D_T\} \end{aligned}$$
Moreover, no tasks of any order can be performed before the start or after the end of a shift. Thus, for each order, two additional 0 weighted UW-arcs are inserted between \(S\) and the starting tasks of an order; and the product-node of an order and \(E\):
$$\begin{aligned}&(S,(O,I),0,\infty )\in A_1 \qquad \forall O\in \mathcal{O},I\in \mathcal{I}^{first}_{T_O}\\&(O,E,0,\infty )\in A_1 \qquad \forall O\in \mathcal{O}\end{aligned}$$
The part of the recipe-graph belonging to the orders is illustrated in Fig. 6.
Travel times
The time needed for a car to travel between tasks must be included in the model, as well. Since this time depends on the locations of the tasks, it can be mapped to changeover times of batch scheduling problems that depend on the equipments and the two tasks. As a result, if a car will be assigned to a node \((O_2,I_2)\) after \((O_1,I_1)\), the UIS schedule-arc that the algorithm will insert into the graph will be this:
$$\begin{aligned} ((O_1,I_1),(O_2,I_2),t^{perform}(I_1)+t^{travel}(L_{O_1},L_{O_2}),\infty ) \end{aligned}$$
Depot
Each car has to start from the depot and return there by the end of the shift. To model this, the recipe-graph is extended by two task-nodes for each car, representing the loading and unloading of the cars at the depot. The operating times for these tasks are 0, the location for both of them is the depot, and the only suitable equipment is the related car. Formally:
$$\begin{aligned} L_C,U_C\in N^T \qquad \forall C\in \mathcal{C}\end{aligned}$$
While locations belong to orders, the loading and unloading tasks must have the depot as their location. For the sake of generality, the notation L(n) is introduced:
$$\begin{aligned} L(n) = \left\{ \begin{array}{ll} L^D &{} \hbox {if } n=L_C \hbox { or } n=U_C\\ L_O &{} \hbox {if } n=(O,I)\\ \end{array} \right. \quad \forall n \in N^T \end{aligned}$$
Similarly, \(t^{perform}(L_C)=t^{perform}(U_C)=0\) and \(L_C, U_C \in N_C\) but \(L_C,U_C\not \in N_{C'}\) if \(C'\ne C\).
To ensure that \(L_C\) is the first task assigned to C and \(U_C\) is the last one, some additional changes are needed. This rule could easily be enforced by slightly changing the core S-graph algorithms to adhere to it. However, that is not necessary as this constraint can be expressed by some additional recipe-arcs, as well.
First, a 0 weighted ZW-arc needs to be inserted between \(S\) and all of the \(L_C\) nodes:
$$\begin{aligned} (S,L_C,0,0)\in A_1 \qquad \forall C\in \mathcal{C}\end{aligned}$$
These arcs ensure that \(L_C\) must be the first to be assigned to C, otherwise, if another node (O, I) is assigned to C first, the scheduling algorithm immediately inserts a weighted arc from (O, I) to \(L_C\). Together with the arc inserted between \(S\) and (O, I), these arcs would form an infeasible schedule, and the subproblem would be pruned immediately.
Similarly, a 0 weighted ZW-arc is inserted between \(U_C\) and \(E\):
$$\begin{aligned} (U_C,E,0,0)\in A_1 \qquad \forall C\in \mathcal{C}\end{aligned}$$
These additional nodes and arcs are illustrated in Fig. 7.
Bounding function
The general B&B algorithms of the S-graph framework were originally developed for makespan minimization. However, for any other objective, if a proper bounding function is provided, the scheduling algorithms will provide an optimal solution.
For the investigated problem class, the objective is to minimize the total cost, which consists of the following elements:
-
Processing costs of tasks
-
Fix costs for cars if they are used
-
Travel costs of cars
-
Penalties for lateness for scheduled orders
-
Penalties for deadline violations
In Sect. 4.2.1, a basic lower bound function is presented which incorporates the costs associated with the decisions already made in a partial schedule. This simple bound can be tightened if a lower bound is given for the costs corresponding to decisions that are not yet made. Section 4.2.2 provides several examples for such procedures. In Sect. 4.2.3 the different options for the bounding function are summarized.
Basic bounding function
The basic bounding procedure summarizes all costs based on decisions already made in previous branching steps. The function starts with initializing the bound variable to zero. Each following block increases its value by the lower bound of a cost-component so that it will contain the lower bound on the overall cost in the end.
First, the sum of the costs of processing the tasks is added, which will be constant for all schedules. This value does not depend on any decision because all orders have to be performed.
Then the fix costs of those cars are added that already have at least one task assigned to them. These cars will be used in each solution reachable from the current subproblem so their fix costs will increase the total cost.
A lower bound for the travel costs of cars can be easily established by summing the costs for travels that have already been assigned to a car.
The longest path from \(Z\) provides a lower bound on the starting time of each node. Thus, a lower bound on the penalties for starting orders too late can be given by summing the costs caused by the lateness that the partial schedule already ensures.
Similarly, a lower bound on the lateness for deadlines of the orders can be established and used to further increase the bound with the corresponding costs.
After these steps, the returned bound variable contains the sum of the lower bounds for all of the cost-components, thus, a lower bound on the total cost itself.
Tightening the bound
The bound described in Sect. 4.2.1 only considers direct implications of decisions that have already been made in the partial schedule. This bound can be further tightened by including some additional costs that arise from decisions not yet made, but are certain to be included later in the B&B tree.
Each of the following procedures provide a lower bound on such costs and can be called to further increase the value of the bound variable from Sect. 4.2.1.
Fix costs of cars One way to achieve a tighter bound is to include the fix costs of cars that have not yet been assigned to any task but their usage is inevitable. This is the case, for example, if there is at least one unscheduled task that can only be performed by a single, yet unused car.
Cost of remaining trips The bound can be further tightened by computing a lower bound for the cost of the remaining trips that the cars have to make. Two such different lower bounds are given here.
The first method relies on the minimal costs of entering and leaving a location. These values (\(c^{enter}(l)\), \(c^{leave}(l)\)) calculated at the start of the solution will remain constant:
For every location with unscheduled tasks, the cost of leaving this location can be added. If a car has a task with this location assigned to it most recently, it may be able to perform the remaining tasks there. Otherwise, a car will have to travel there so the cost of entering can be added. The sums of entering and leaving costs are kept separately, as every trip both leaves a location and enters another. Only one of the sums can be included in the bound, preferably the higher.
\(M^L \subseteq M\) is the set of assignments that were last assigned to the cars. It contains up to one task-resource pair for each car.
We can also add the costs of returning to the depot or leaving the last location for each car. Note, that triangle inequality is assumed to hold for \(d^{travel}\).
The second method considers the remaining trips for each car in more detail. The locations that the car must visit are determined by the tasks that can only be performed by the car in question. The lowest possible cost of visiting these locations is the solution of a traveling salesman problem. However, solving an NP-hard problem at each bounding step would be inefficient. The minimum spanning tree of the location-distance graph gives a computationally easy lower bound on the future trips. If distances are asymmetric, the smaller distance can be used for each location pair. Finally, for the locations whose every task can be performed by multiple cars (\(\mathcal{L}^x\)), the first method can be used to get a lower bound for further costs.
Variants for the bounding function
Theoretically, there are 12 different options how the above procedures can be combined to have a proper bounding function:
-
BasicBound is either used or not
-
AdditionalFixCost is either used or not
-
For future travel costs, either AdditionalVisitCosts or CarBasedCosts is used, or neither of them.
Not using the BasicBound is an unreasonable decision as it is easy to evaluate and contributes a lot to the bound. From the 6 remaining options the following 3 are selected:
Bound-0 The simplest option is to use only the BasicBound function. This is the fastest approach but it also provides the poorest bound. This option is mostly used as a baseline reference.
Bound-1 Another option is to use the sum of the return values of BasicBound, AdditionalFixCosts and AdditionalVisitCosts. This option requires slightly more computation but provides a tighter bound.
Bound-2 The third option is to use the sum of the return values of BasicBound, AdditionalFixCosts and CarBasedCosts. The last procedure requires to solve a minimal spanning tree problem, thus it is expected to be the slowest, but it can also provide even tighter bounds.
Feasibility function
The B&B algorithms of the S-graph framework perform a feasibility check at each partial schedule. The basic feasibility function of the framework searches for a directed cycle within the graph, which indicates infeasible schedules.
This function is adequate for most of the problems solved by the S-graph framework so far. However, for the problem at hand, there is a limit on the maximal distance a car can travel a day, \(d^{max}(C)\).
The distance that a car must cover in the current partial problem can be calculated very similarly to its corresponding cost contribution and if it exceeds the given limit for any car, the function must return false:
This feasibility function considers only the trips already assigned to a car. The second bound tightening method calculates a lower bound on the future trips of each car. It is also used to detect a future infeasibility when the lower bound exceeds \(d^{max}(r)\).
Branching strategies
Two main S-graph branching strategies have been published to make the assignment and sequencing decisions expressed by schedule-arcs. The original algorithm (Sanmartí et al. 2002) selects an equipment unit in each branching step, and different tasks are added to the end of its production sequence in each children node. More recently, a different algorithm has been proposed (Adonyi et al. 2007), where an unassigned, unscheduled task is selected, and in each child node, the task is added to a different position in the production sequence of any suitable units. To highlight this difference in the branching step, the two algorithms had been labeled as equipment-based and task-based, respectively. Both branching procedures can have many variants based on the selection method of the pivoting unit or task and the order in which the children are generated.
The proposed algorithm of Appendix 3 applies the equipment-based strategy for several reasons:
-
Unless there is a very defining bottleneck, it outperforms the task-based strategy in most of the general cases (Adonyi 2008).
-
More acceleration techniques have been published to further enhance its performance (Holczinger et al. 2002; Adonyi et al. 2008).
-
Some components of the bounding functions detailed in Sect. 4.2 rely on this strategy.
For the computational tests, unit selection was based on alphabetical order and the B&B tree was explored in a depth-first fashion.