Cumulative Scheduling with Task Intervals Yves Caseau Bouygues - Direction Scientifique 1 avenue Eugène Freyssinet 78061 St Quentin en Yvelines cedex
[email protected]
François Laburthe Ecole Normale Supérieure L.I.E.N.S. - D.M.I. 45, rue d’Ulm, 75005 PARIS
[email protected]
Abstract This paper presents a set of propagation rules to solve cumulative constraints. As in our previous paper on jobshop scheduling [8], our goal is to propose to the CLP community techniques that allow a constraint satisfaction program to obtain performances which are competitive with ad-hoc approaches. The rules that we propose are a mix of an extension of the concept of task intervals to the cumulative case and the use of a traditional resource histogram. We also explain how to use a branching scheme inherited from operations research to address complex multi-resources problems (similar to the use of edge-finding for jobshop scheduling). We show that the complex propagation patterns associated with our rules make a strong arguments for using logic programming. We also identify a phenomenon of phase transition in our examples that illustrates why cumulative scheduling is hard.
1. Introduction Many real-world scheduling problems are really cumulative scheduling problems, where each resource may be shared between a bounded number of tasks, as explained in [1]. We have been investigating crew scheduling problems for the construction industry that fall quite neatly under this category. Such a cumulative problem can be seen as the extension of a classical n × m jobshop scheduling problem, where each task can consume a variable number of units of each machine. Instead of fixing the duration of the task, only the product span × consumption in fixed. The maximal number of units available at any time for each machine is fixed. In our problem, there is an additional complexity since the consumption is not constant in time (as for CHIP [1]) but can vary between two pre-set boundaries. There is very little work available on cumulative scheduling compared, for instance, to jobshop scheduling. The simpler case of resource-constrained project scheduling, where the consumption of each task is fixed, has been investigated by a few specialists from operations research (e.g. [22] [3] [4] [11] [17]). However, the variable consumption aspect produces a much more complex search space. Moreover, there are no credible benchmarks for these problems. We first decided to use a one-machine cumulative benchmark from [1] (originally a ship loading example from [20]). Comparing our algorithms with CHIP results is interesting since much work went into the resolution of cumulative constraints, although not much is published. We obtained results that are comparable to those published in [1], with a disheartening advantage to simpler propagation strategies. In order to check the robustness of our work, we started to evaluate the neighborhood of the problem by adding and removing a few constraints. We observed a phase transition phenomenon and a few very difficult instances of our problem. We also found out that the additional propagation necessary to solve these “ special instances ” was also mandatory for obtaining robustness with multi-resource problems. The result of our work is a resolution algorithm based on complex constraint propagation rules. This algorithm performs reasonably well on the few published benchmarks that we found and is robust, that means it is able to solve the difficult variants that we came across during our evaluation. For most benchmarks, better performances can be obtained by reducing the amount of propagation but this is at the expense of robustness. In this paper, we give a self-contained description of the propagation rules, that are based on the concepts of task intervals and resource histograms. In the same way that task intervals allowed us in [8] to produce the proof of optimality for the “ bridge ” benchmark
through simple propagation, the rules presented here allow us to produce the proof of optimality of the “ ship loading ” example through simple propagation. This paper is organized as follows. Section 2 presents cumulative scheduling through a simple experiment. We describe a simple algorithm and apply it to a classical benchmark. We identify some difficulties that will motivate our investigation for a more complex (and robust) algorithm. Section 3 presents the propagation rules and the branching scheme for our algorithm. Our goal is to provide designers of CLP systems with a plausible strategy to introduce cumulative constraints into their systems. As for the jobshop problem, we found it necessary to use a special-purpose branching scheme from operations research that is described in Section 3.3. Section 4 gives some results and discusses related techniques for cumulative scheduling. We show that our complex approach is still plausible for simpler problems, such as the resource-constrained scheduling problems. We also discuss the introduction of two techniques used in th case of jobshop scheduling: energetic reasoning (which was introduced by Lopez [15] and also used by Lock [14]) as well as the shaving technique, with which Martin & Shmoys [16] recently obtained promising results for jobshop scheduling.
2. Cumulative Scheduling 2.1. Informal Description A cumulative scheduling problem is defined by a set of tasks and a set of resources that we call machines here by analogy with jobshop scheduling. Each task needs a given machine for a certain amount of time, and needs other tasks to be completed before it can start (this is the precedence relation among tasks). In a cumulative problem, a machine can process many tasks in parallel, which is modeled by the availability of k “units” of the machine. The amount of processing, which can be seen as the product of the consumption (the number of units assigned to the task) by the span (duration), if the consumption is constant, is given for each task. If the consumption may vary (which was the case in our construction problem), the amount of processing is defined as a discrete integral. Due to the lack of space, we only deal in this paper with constant (but not fixed) consumption. We decided to experiment with the problem described in the CHIP paper [1]. This problem is made of 34 tasks with a complex precedence graph (Figure 1) that shows at once many interesting properties. First, this precedence graph covers all the tasks; second, the nodes T08/T09, T18, T23/T24 divide the problem into independent sub-problems. Each task is only given an amount of processing (which we call the size) and its consumption can be any divider of its size (e.g., a task with size 12 can be used as 1 x 12, 2 x 6, 3 x 4, ... etc.). In Figure 1, each box is a task and its size is indicated in italic (Precedence links are left-toright). The absence of other constraints on consumption yields a lot of flexibility which is another feature of this problem. The total amount of units N can be chosen arbitrarily but we have mostly focused on the case with 8 units. T04 24 T01 12
T02 16
T07 12 T03 12
T05 25
T06
T08
10
12
T09 12
T14
T12
T16
T17
15
10
9
12
T20 4
T10
T11
T13
T15
16
12
4
6
T18 14
T19 4
T23 28
T21 4
T22
T31 6 T24 40
T25 16
8
T26 3
T27 3
T28 12
T29 8
T30 9
T32 3
T33 6
T34 6
Figure 1: A one-machine reference problem from [1]
2.2. A Simple Approach to Cumulative Scheduling Solving a cumulative problem with a constraint-based approach requires to find a scheme for branching and a set of propagation rules for the constraints in order to prune the search space as much as possible. Finding an adequate branching scheme is not easy since the usual ordering scheme that is used for jobshop does not work here and branching based on task’s starting time is not appropriate since it does not scale up properly (i.e., it is
sensitive to the precision of time measurement). Most branching schemes use the fact that each task can be imposed to start either at the end of another task or at its earliest allowed time. After experimenting with a few schemes, we settled for a left-to-right scheme : we compute an increasing sequence of “events” that are either the end of previously scheduled task or externally imposed starting time. For each event, we examine the set of tasks that can be started at this very moment and we try all combinations of tasks/consumption that fit within the available number of units. Tasks that do not start are moved to the time of the next event. Our test program was obtained using this branching scheme and a simple propagation rule. After computing each new event, we sort the tasks according to their latest possible completion time and we verify that the amount of processing needed between the current event and any point in the future is compatible with the machine capacity. On the original problem, this algorithm works quite well, as shown by the results in the first table of Figure 2 (part of the improvement is due to a better machine since a Pentium90 is 3-4 times faster than a SPARC1). It must be noticed that although the algorithm does not use the existence of the separation nodes explicitly, they are “caught” by intelligent backtracking. However, performances could be improved by solving the sub-problems independently. We then decided to study the robustness of the algorithm with respect to precedence constraints. It is clear that if we add new precedence constraints, the problem becomes even easier. To see what happen in the other direction, we built the following sequence of problems: p1 is the original problem, p0 is obtained by adding one precedence link between T28 and T32, p2 is the problem obtained from p1 by removing all dashed links in Figure 1 (the graph becomes a tree), p3 is the problem obtained by further removing the solid links (T31-T34 become floating tasks), p4 is obtained from p3 by making T17 a floating task, p5 is the problem obtained by removing from p4 all precedence link towards T18-T20, and p6 is the problem obtained by adding a link between T14 and T10 to p3. The second table gives for each of these problems the time for obtaining the optimal solution (given its size) and the time for the optimality proof. These few results illustrate a more general finding: when the precedence graph is rich (as in p0 or p1), the problem is easy because the ordering aspect strongly limits the search space. On the other hand, when there are few precedence constraints, the problem is easy because of the flexibility of the tasks. This means that a solution of size 50 (x 8) is built easily, which is clearly optimal since the sum of the sizes is strictly larger than 49 x 8. The situation becomes much more difficult in between. This phase transition phenomenon is very similar to what was observed with the TSPTW -Traveling Salesman Problem with Time Windows- in [7]: when the time windows are tight, the scheduling problem dominates and a branching strategy drawn from jobshop scheduling works very well; when there are few time windows, the TSP dominates and a TSP strategy is indicated. The difficult cases occur at the transition between the two phases. N 3 7 8 11
solution 168 67 55 47
precedence graph (N = 8) optimal sol. time optimality
Opt. proof 0.3s 0.2s 0.15s 0.04s
Total time 0.9s 0.6s 0.2s 0.3s
[1] 2.7s 2.0s 1.0s 1.5s
p0
p1
p2
p3
p4
p5
p6
57 0.1s 0.03s
55 0.03s 0.15s
51 0.1s 0.06s
50 30s 0s
50 8s 0s
50 0.14s 0s
50 300s 0s
Figure 2: Results for various N and various precedence graphs
2.3. Formal description of the problem The problem is defined by a set of resources R, a set of tasks T and a set of precedence constraints C. For a resource r ∈ R, available(r) denotes the number of identical units of
type r that are available. For a task t ∈T , res(t), minuse(t) and maxuse(t) respectively denote the resource, the minimal (and maximal) number of units on res(t) necessary to perform t and size(t) denotes the total processing quantity (time x units) of t. Constraints c ∈C are made of pairs of tasks ( c = (t1 , t2 ) will be written t1 inconsistency
Figure 3: consistency on task intervals has more pruning power than on sole tasks
Upon each change to a time window, the set extension of some task intervals may change. These modified intervals can be recomputed with very few computations with an incremental maintenance algorithm (exactly the same as for the jobshop case, detailed in [8]). The values taken by the window bounds and the level consumption can only be integers, therefore all rectangular shapes are not allowed. For example, a task of size 10 can be processed using 2 units during 5 hours or using 5 units during 2 hours, but with 3 or 4 units. To take this fact into account, we introduce the notation a / b and maintain for each task t its minimal time span span(t). For n,p integers, let n / p := min {k ≥ n / p, n ≡ O[ k ]}. The values of minuse(t) and maxuse(t) are given as data, however, they can be dynamically sharpened. Indeed, the surface constraint use(t) × ( t − t ) = size(t) is used to derive the following propagation rule:
minuse(t ) × ( t − t ) < size(t ) ⇒ minuse(t ): = size(t ) / (t − t )
(area)
For t ∈T , let span(t ): = size(t ) / maxuse(t ) This redundant relation is maintained (the heavy use of span make it worthwhile) with the following rule:
span(t ) × maxuse(t ) < size(t ) ⇒ span(t ): = size(t ) / maxuse(t )
(s p a n )
Therefore, another integrity constraint can be stated
t − t > span(t ) ⇒ contradiction
(task integrity) There are four other propagation rules: precedence, throw, reject and exclusion The first rule propagates precedences, exactly as for the jobshop. t1 slack
=> t ≥
I - slack / minuse(t) = 7
Figure 4: the throw rule: if t started before I, it would overlap with the window of I for atleast 3 units, which is more than the available slack. Therefore t can be pushed ron the ight of I
It is interesting to see that the earliest starting time for t (which is being pushed) is obtained with the lowest possible consumption, whereas the earliest completion time would be obtained with the largest consumption. As a consequence, we can "push" further tasks that are linked to t through a precedence constraint by using this earliest completion time. let slack: = ( I − I ) × available( r ) − size( I ), size(t ) − max( 0, I − t ) × maxuse(t ) > slack minuse(t ) × ( I − I ) > slack t < I − slack / minuse(t ) t: = I − slack / minuse(t ) ⇒ (t < < t2 ) ⇒ t2 ≥ I − slack / maxuse(t ) + span(t )
(throw)
The third rule, reject, is similar to a subcase of the edge-finding rule for the jobshop. It detects situations in which a task t will necessarily be performed after all tasks t’ of an interval I, either because the time windows of t’ and t impose it, or because of a precedence relation between t’ and t (taking the transitive closure of this relation). use
[
t
t
t
t1 t2 t3 t4
2 4 2 2
8 9 9 5
2 2 2 4
t
5
10
2
]
size(t)
t
3 t1
2
I = [t1, t3]
1
t4 1
2
3
t2 t3 4
5
6
7
8
9 10
time
• t is after t1, t2, t3 because of precedences • t is after t4 because of time windows
precedences: t1 t2 − span(t2 ))
(exclusion)
⇒ t2 available( r ) ⇒ contradiction (histogram integrity) Second, it is also used for propagation on the time windows. When the availability of a resource r for a task t at a given time instant x (available(r) - level(r,x) + requires(t,x)) is strictly less than the minimal consumption of t, minuse(t), then t cannot be in process at time
instant x, and its window may be updated subsequently. The next figure shows such an example where t6 can be updated to 6. level(r) 5 4 3 2 1
t2 t3 t4
t
[t, t]
t1 t2 t3
[0, 3] [0, 5] [3, 6]
t4 t5 t6
[4, 7] [4, 6] [0,10]
size(t)= use(t) x span(t) 9=3x3 6=2x3 6=3x2 or 2 x 3 6=3x2 2=1x2 6=2x3 or 3 x 2
t1 t5 1 2 3 4 5 6
There are two peaks in the histogram during which t6 cannot be processed: during [2,3[ and during [5,6[.
a solution t2
t6 cannot fit before the peak [2,3[ t6 cannot fit before between peaks [2,3[ and [5,6[ => t6 is after peak [5,6[
t3
t4 t6
t1 t5
Figure 7: propagation with the resource histogram
The algorithm for checking if the window [a,b] of a task t using resource r can be reduced is as follows. First, it looks for peaks of consumption in the interval [a,b]. There is a peak at time x for task t if minuse(t) > available(res(t)) - ( level(res(t)) - requires(t,x)) When the peaks are taken out of [a,b], one is left with a union of widows [ai , bi ]: t can be increased to the smallest ai such t that fits in [ai, bi]. and t can be decreased to the largest bi such that t fits in [ai, bi]. In order to know if a t may fit between ai and bi one should check: ∃c ∈[ minuse(t ), maxuse(t )], ∃x1 , x2 ∈[ ai , bi ], ( x2 − x1 ) × c = size(t ) fits(t, ai , bi ) ⇔ ∀x ∈[ x1 , x2 − 1], level( res(t )) − requires(t, x ) + c ≤ available( res(t )) Computing this exact value requires several passes over the time window [a i, bi] (because of the different possible consumption levels) and slows down too much the algorithm. We therefore replaced it with an approximation in just one pass. In the previous example, check(t6,0,10) calls fits(t6,0,2), fits(t6,3,5) and fits(t6,6,10). Of these three calls to fits, the last one is the only one to return true, therefore t6 can be increased to 6. This checking procedure prunes very efficiently but is rather long to execute. Therefore, we found it worthwhile to call check(t) only when the value of minuse(t) has been increased (because of a change in the time window). 3.3. Branching Scheme Formally, the search algorithm can be described as follows: Let P be the set of tasks that have been placed (at the beginning, P = ∅), let event: = min(t, t ∈T − P) (at the beginning, event = 0), and let S: = { t ∈T t = event } . For each task t in the stack S, if { c1 , ... , ck } is the set of possible consumption levels, the k+1 following possibilities will be tried:
∨i {t ∈ P ∧ use(t ) = ci ∧ start (t ) = event } ∨ (t ∉ P ∧ start (t ) > event )
These possibilities are tried in decreasing order of ci . For the last possibility, the value of t is increased to min t' ∈T ( t' + span(t' ) t' + span(t' ) ≥ event ) So, each node of the tree is labeled by a task t of the stack S, and has k+1 branches (k depends on t). At depth |S|+1, a new stack is built and the same scheme is recursively applied. The set { c1 , ... , ck } is not the set of divisors of s i z e ( t ) in the interval [minuse(t),maxuse(t)]. Indeed, consumption levels ci such that ci + (level(r,event) requires(t,event)) > available(r) can be discarded right away. Moreover, if t had been delayed at the previous event e and if ci is small enough such that t can be “shifted” to the
left, then any solution with t placed at event for consumption ci could have been obtained with t placed at e with consumption ci. Therefore, for tasks that have already been delayed, c i such that ci + level(r,event-1) ≤ available(r) can also be discarded. This restriction (generating only semi-active schedules) is called a dominance rule: the branching scheme is limited to the generation of a dominant set of solutions (for each solution S, there exists another solution S’ in the dominant set of makespan smaller or equal than makespan(S); therefore feasibility or optimization problems have the same answers whether solved over the whole set of solutions or over the dominant set). The next figure shows an example of the consumption level considered in a stack. P={t1, t2, t3}
t
t
t4 t5
3 3
duration(t) = use(t) x span(t)
t
event = 3 S = {t4, t5}
t4
use 6
6 6
3=1x3 or 3x1 6=3x2 or 2x3 t4
t5
5 4
t2
start≥4
use=3
t3
3 2
t5
t1
1
time 1
2
use=1 discard if t4 was delayed
3
4
5
6
use=3
start≥4 use=2 discard if t5 was delayed
Figure 8: The branching scheme
Concerning the order in which the tasks of S are examined, we tried many heuristics and came to the following conclusion: tasks t with smallest t should be placed first (they cannot be too much delayed) as well as those with largest maxuse(t) (placing them will have much impact on the histogram, and, hopefully, on the other time windows). The choice of the respective consumption levels ci (t ) for the tasks t ∈S amounts to a knapsack problem. So, we modified the heuristic and computed for each ci , the best knapsack value ki in which it could be completed and ranked the ci in decreasing order of ( ki , ci ), instead of just ci . To our surprise, this smart heuristic yielded larger search trees than the basic order by decreasing values of ci , so it was discarded. As mentioned before, the drawback of this branching scheme is that it does not allow to focus on bottlenecks first: For example, if the hard part of the schedule is located on the right (late in the plan), the difficult subproblem will occur deep in the search tree and is likely to be reconsidered many times. In order to avoid this, we added historical backtracking to the search scheme (“no-good” backtracking). When the search algorithm backtracks to a node where a stack S is build, if no task is in progress at this event, (i.e., level(r,event) = 0), then the algorithm has just proved that it is not possible to schedule the set of tasks T-P after event. In order to keep this information, an array no-good(r) of lists of sets of tasks is associated to each resource r,(the default value is the empty list). We add the set T-P to the list no-good(r)[event]. In the rest of the search, when the algorithm comes to build a stack, it checks whether the present situation is subsumed by another one already explored. subsumed = true ⇔ ∃i ≤ event, ∃S ∈no − good ( r )[i ], T − P ⊆ S When the situation is subsumed, the algorithm directly backtracks without re-exploring the situation. We tried different implementations for this: in practice, it is not necessary to test several values of i, testing only the greatest i such that no-good(r)[i] is not empty is sufficient. Moreover, it is worthwhile to memorize the whole list no-good(r)[event] (Memorizing only the last set diminishes a little the memory requirements at the price of an noticeable loss in pruning power, as noticed in [12]).
4. Results and Related Work 4.1. The Ship-loading and Crew Scheduling Problems On the original ship loading problem, our (complex) algorithm does not perform better than the naive version that we introduced in Section 2, although the number of backtracks is smaller. It is interesting to notice that we are able to obtain the optimality proof with no backtracks (with N = 8). Similar results are obtained for different values of N (smaller number of backtracks but slightly longer execution time). These results are still somehow better than those of [1], although we cannot compare the number of backtracks. The interesting point is the improved behavior of the complex algorithm to the phase transition problem. Although there is still a peak for the difficult problems (such as p3 and p6), the number of backtracks is far more reasonable, which is a good indication of a more robust algorithm. In the next figure, we compare our initial ad-hoc algorithm (with some minor improvements) and the constraint propagation algorithm. (we give the number of backtracks in the search -bk. or kbk. for 1000bk.- and the running times on a PC pentium 90). Since the proofs of optimality are always obtained in less than 10 backtracks, we only mention that of the original problem. problem
p1 optimal. sol.
p1 opt. proof
p2 optimal sol.
p3 optimal sol.
p4 optimal sol.
p6 optimal sol.
simple alg.
0.03 s 65 bk
0.06 s 188 bk
0.06 s 183 bk
15s 44 kbk
47s 131 kbk
162 s 489 kbk
16 bk
0.2 s 0 bk
0.15 s 35 bk
0.14 s 2572bk
8s 1639bk
5 s 13 s 3922 bk
complex alg.
Figure 9: Complex Propagation Strategy on Ship Loading
Since we did not find benchmarks that were similar to our “real” crew scheduling problems, we have picked three of the most interesting as new benchmarks and we provide a short description in the appendix. These problems are representative of true multi-resource problems, which is not true of the Patterson benchmarks that we shall see in the next section. Most problems that we tried could be solved easily, even without using all the propagation rules. However, each technique presented in this paper was found necessary to solve one of these problems (including the previous variations from the ship loading). To illustrate this point, we give the results of two variants of our approach. The first one takes “advantage” of the fact that one of the resource is disjunctive and uses our jobshop scheduling approch first to schedule this resource before the others. The second one does not use the (throw) and (reject) rules. problem
PB1 PB1 opt. sol. (33) opt. proof
PB2 PB2 opt. sol (26) opt. proof
PB3 PB3 opt. sol (30) opt. proof
complex alg.
0.14s 14 bk
0.10s 0 bk
0,15s 53 bk
17s 10,2 kbk
4s 1556 bk
0,2s 91 bk
separate branching
3000s 3000 kbk
0.15s 0 bk
10 s 4400 bk
280s 120 kbk
180s 125 kbk
160s 108 kbk
without (throw &reject)
0.12s 17 bk
0.10s 0 bk
0.5s 344 bk
160s 82 kbk
56s 34 kbk
12s 8 kbk
Figure 10: New multi-resource benchmarks
Althouh this is out of scope of this paper, we need to mention that our original problems included one additional feature of “variable consumption rate”. This means that for some of the tasks, the consumption does not need to be constant and may vary according to time between the boundaries minuse(t) and maxuse(t). This is similar to a pseudo-preemptive situation [6]. It turns out that our branching scheme can be adapted to this new feature and that the resulting problems are easier to solve. That is to say, the problems obtained when
we impose that the consumption is constant are more difficult than the original ones. The additional flexibility provided by the semi-premptive nature of some tasks makes it easier to find a solution if one exists. 4.2. Resource-constrained project scheduling The formulation of cumulative scheduling that has captured the most attention in the past is known as the Resource Constraint Project Scheduling Problem (RCPSP) in which tasks have a fixed shape (the span(t) and use(t) are given as data) and each task is composed of a set of synchronized subtasks, one per resource. Hence, the problem amounts to a multidimensional single resource problem rather than to a general multi-resource problem. For this particular problem, linear programming approaches can solve only toy problems and branch and bound is the paradigm of choice. Patterson [19] proposed a set of 110 benchmarks (3 resources, 7 to 50 tasks) to compare different procedures among which that of Stinson [22] was the clear winner. In his thesis, Demeulmeester [11] proposed a new algorithm (based on what was proposed in [10]),which solved all 110 problems in an average time of 0,2s. per problem (on a slow PC), compared to 2.5s. for Stinson’s procedure. The algorithm of [11] incrementally constructs the schedule, from left to right. However, branching is based on resource conflicts: All tasks are scheduled as early as possible. The schedule is examined from left to right and when a resource conflict occurs (ie. when there is not enough resource available to perform all tasks as early as possible), a subset of all tasks that are currently in use is delayed. All sets are recursively tried. The algorithm also incorporates historical backtracking and dominance rules. The special form of the RCPSP (a multi-resource problem where all tasks require of each resource) allows to use very powerful dominance rules, which are useless in general multi-resource problems (one such dominance rule states that when a task uses so much of the resource that no other can be scheduled in parallel with it, it may be scheduled right away. This applies only when there exists a resource required by all tasks otherwise some tasks can always be scheduled in parallel. Hence, this rule is of little use for general multi-resource scheduling). This algorithm was recently sharpened [12], incorporating ideas from [17] and a factor 3 in time was gained on the Patterson benchmarks. We tested our algorithm on this benchmark. The purpose was not to do better than [12] but to test the robustness of the algorithm on a well known set of problems. We solved all 110 instances, with an average number of 1000 backtracks (34 problems were solved in less than 10 backtracks) and in an average time of 3,5 s. (on a PC Pentium 90). Our solution is slower than the one of Demeulemeester, however it is a more general purpose algorithm. Indeed, the technology involved imposes a heavy overhead (on the largest problem, finding a solution without backtracking already takes 2 seconds). However, our general algorithm can solve all these benchmarks in very few backtracks, without taking advantage of the special structure of the RCPSP. 4.3. Energetic Reasoning Energetic Reasoning is a generic technique that was proposed by Lopez [14] for jobshop scheduling. Its principle is to consider the contribution of each task to each time window of a given family. The contribution of a task t to an interval [a b] is the minimal quantity of the ressource (consumption x duration) that will needed by t between a and b. For instance, if b=a+1, the contribution of t is requires(t,a). By definition, we obtain a redundant constraint for each interval, that states that the sum of the contributions must be smaller than (b - a) x available(r). This is a powerful technique since when it is applied to intervals of the form [a,a+1] it produces the results of Section 3.2 and when it is applied to intervals of the form [t, t ], it generalizes the integrity constraint for task intervals. As a matter of fact, energetic reasoning is more precise since it takes into account the necessary contribution of tasks that do not belong to the task interval but still must have a non-empty intersection. On the other hand, applyling energetic reasoning to all time intervals is extremely expensive. A reasonable compromise is to apply it for all "task intervals", that is, for all time windows of the form [t, t ]. First, it is faily simple to maintain the energy (the sum of all
contributions) associated to each interval. We use the O(n 2 ) incremental algorithm for maintaining the task intervals presented in [8]; however, although most of the updating fits nicely into this algorithm, there remains one propagation pattern that requires a O(n 3 ) subloop. Second, the energy may be used to refine the propagation rules. As a matter of fact, the (throw) rule can use a better value for the slack (the "unused" part of the interval) by taking the energy into account. When we try to place the task t before the task interval I, the slack is computed as the difference between the capacity of I and the energy, the only trick is to subtract the contribution of t itself to the energy. We report our experiments with energetic reasoning in the table 12. First, it is interesting to note that if we simply implement the integrity constraint but do not mofify the propagation rule, the results are very disapointing (almost no reduction in the number of backtracks with a significant cost). When the rule (throw) is updated, the gain in the number of backtrack is more significant. Those results are consistent with those reported in [15] who also implemented energetic reasoning with task interval (not surprisingly, the additional benefits of energetic reasoning are more important in the cummulative case than for the jobshop, for which we have other powerful rules). However, the gain from energetic reasoning is far from sufficient to offset the extra cost for maintaining the energy. Although more experiments are needed, our preliminary conclusion is that energetic reasoning is too expensive for its pruning power. It looks as though it should be necessary to simplify the computation of energy so that it may be performed within an O(n 2) loop. 4.4. Shaving Since the rules presented in this paper were partially inspired from previous work on jobshop scheduling, it is interesting to consider if more techniques could be borrowed. The immediate candidate for this is shaving, a technique very natural to CLP practitionners (it is a form of path-consistency), that has proven recently to be a technique of choice for jobshop scheduling ([5][16]). Shaving consists of reducing domains by excluding values that are inconsistent with the rest of the problem (the whole set of constraints and data). Practically, if the domain associated with the starting time of a task t is the interval [a, b] = [t, t − span(t )], we evaluate if the lower bound a is consistent by trying to assert t: = a + span(t ). If we detect a contradiction by propagating this information, we know that it is actually impossible to start the task t at a. Thus, we can increase t to a + 1. This is repeated until no contradiction is detected. The actual implementation of shaving uses a dichotomic search to find by how much each bound of the interval [a,b] can be shaved, as is explained in [16]. Shaving is orthogonal to the propagation technique and can be used with any set of propagation rules. In their paper, Martin and Shmoys use it with one unique “exclusion” rule. We have used it with the rules presented in [8]. It must be noticed that shaving is very timeconsuming and does not accomodate well with propagation schemes that are too costly. For instance, we cannot use shaving jointly with the improvements that we propose in [9]. problem MT10. LA19. LA20. ORB1 ORB2 ABZ5
[2] 372 s 1460 s 1402 s 1482 s 2484 s 951 s
16 Kb 94 Kb 82 Kb 72 Kb 153 Kb 58 Kb
[7] 230 s 189 s 156 s 1000 s 108 s 255 s
1575 bk 300 bk 910 bk 7265 bk 456 bk 1350 bk
[8] + shaving 232 s 7 bk 208 s 9 bk 24 s 0 bk 1460 s 99 bk 128s 6 bk 336 s 26 bk
Figure 11: Optimality Proofs for 10 x 10 jobshop problems (SPARC-1)
Shaving can be used before starting the search as a pure domain reduction technique. Surpringly, although the domains are actually reduced substantially, the improvement for the search is marginal. On the other hand, it can be used successfully as a bounding technique as proposed by [5] and [16]. We have implemented this strategy by executing a “shaving loop” after each decision in our branch-and-bound algorithm. This loop consists of shaving all tasks until no more reduction can be performed. The principal effect of this loop is to detect inconsistencies very early on. The results are quite spectacular although
the cost of shaving is significant. We give the time for computing the proof of optimility (and the number of backtracks) for some classical 10 x 10 problems. More interesting results can be found in [16]. As we said previously, adding shaving to an existing propagation scheme is straightforward. However, the results in the cumulative case were disapointing. The soft structure of the problem produces less shaving than what was observed with the jobshop problem. Also, the use of shaving as a preliminary technique before search did not prove useful at all. We then tried to perform a “shaving loop” after each decision in the search tree, with or without reaching stability. As shown in Figure 12, the results are disapointing. The gain in search space varies from interesting to none, but the additional cost always offset the gains. Altough further analysis work is needed, it seems that the complexity of the propagation and the loose structure of the problem makes it a poor fit to the use of shaving. problem (opt. solution)
p1
p2
p3
p4
p6
with shaving.
0.7 s 18 bk
2.4 s 34 bk
21 s 383 bk
2.3 s 7 bk
59 s 2401 bk
with Energetic Reasoning
0,7 s. 12 bk.
1,6 s 26 bk.
2295b. 20s.
1179 10,2s.
3469 30s.
Figure 12: Other Possible Approaches
4.4. Relevance to (Constraint) Logic Programming In addition to the direct relevance for CLP designers that are facing cumulative scheduling problems, we believe that this work is interesting for the (C)LP community for two reasons. First, it shows the need for control in a CLP language. To implement our algorithm easily, it is desirable to be allowed to express new propagation rules and to have a complete control over the branching scheme (the labeling of variables). This is very similar to what was found with our experiment with jobshop scheduling and, therefore, is not worthy of further developments. It is interesting to notice that this is a trend with newer languages such as Oz [21], that allows the user to express more easily his branching strategy than with earlier systems. Second, we believe that this algorithm makes our case for using logic rules in a search algorithm more convincing than the examples of our previous papers. It might have been argued that the rules that we gave for our jobshop algorithm could be encoded reasonably easily with a procedural language. A careful inspection of the rules (throw) and (reject) show that there are many ways for them to be triggered and that the task of coding all these propagation patterns explicitly is a very tedious one. Also, it follows from our previous experiments that it is highly desirable to keep control upon which rules (and how) are propagated. From our experience, this is a case where there is a very definitive advantage for the use of logic programming techniques that free the programmer from a lot of difficult work. To evaluate the previous statement, we wrote an procedural version of the propagation for our shaving experiments. A key success factor for shaving is the ability to propagate very efficiently. The procedural algorithms are tedious to write but they offer opportunities for further optimization, such as folding or combining some of the subloops. The bottom line is that we spent a large amount of time to develop a program that is far more complex (and much longer) for virtually no improvement of performance (the gain in speed was offset by some of the simplification that were necessary to derive efficient propagation schemes).
5. Conclusion In this paper, we presented the cumulative scheduling problem and gave experimental evidence for the need to develop more robust approaches. We proposed an algorithm based on complex propagation rules for the cumulative constraint and a specialized branching scheme. We believe that our contribution is as follows: •
• •
It is a detailed and self-contained description of a constraint propagation algorithm that solves efficiently common benchmarks. As a consequence, it should be of value to CLP practitioners and designers. We were able to demonstrate the robustness of our algorithm using richer problems. These problems justify our extensive propagation of the cumulative constraint. We made an experimental contribution to the understanding of hard CSP's. We identified a phase transition phenomenon that strongly advocates for a richer set of benchmarks.
Acknowledgments This work was heavily inspired by the pioneering work of the CHIP team. We were introduced to the “art of shaving” by Paul Martin. We are also grateful to Jacques Carlier and Eric Pinson for numerous suggestions, and to Claude Le Pape for insightful comments.
References [1]
A. Aggoun, N. Beldiceanu. Extending CHIP in order to Solve Complex Scheduling and Placement Problems. Mathematical and Computer Modelling, vol. 17 (7), p. 5773, 1993.
[2]
D. Applegate, B. Cook. A Computational study of the Job-Shop Problem ORSA Jouranl on Computing, 3, p. 149-156, 1991.
[3] R. Alvarez-Valdes, J.M. Tamarit, Heuristic Algorithms for Resource-Constrained Project Scheduling: a Review and an Empirical Analysis in R. Slowinski, J. Weglarz (eds): Advances in Project Scheduling, Elsevier, Amsterdam, 1989, p. 113-134. [4] J. Carlier, B. Latapie. Une Méthode Arborescente pour résoudre les problèmes cumulatifs, Operations Research 25(3), 1991, p. 311-340. [5] J. Carlier, E. Pinson. Adjustments of Heads and Tails for the Job-Shop Problem, European Journal of Operations Research 78, p. 146-161, 1994. [6] J. Carlier, E. Pinson. Jackson’s Pseudo Preemptive Schedule for the Pm/r,q/Cmax scheduling Problem, Technical Report, HEUDIASIC, Compiègne, France, 1996. [7] Y. Caseau. Constraint Satisfaction with an Object-Oriented Knowledge Representation Language. Applied Intelligence, Vol. 4, no. 2, May 1994. [8] Y. Caseau, F. Laburthe. Improved CLP Scheduling with Tasks Intervals. Proc. of the 11th International Conference on Logic Programming, The MIT Press, June 1994. [9] Y. Caseau, F. Laburthe. Improving Branch and Bound for Jobshop Scheduling with Constraint Propagation. Proc. of CCS’95 (Combinatorics and Computer Science), Brest, July 1995, to appear in LNCS, Springer Verlag. [10] N. Christofides, R. Almarez-Valdes, J.M. Tamarit. Project Scheduling with Resource Constraints: a Branch and Bound Approach, European Journal of Operations Research, 29(3), p. 262-273, 1987. [11] E. Demeulemeester. Optimal Algorithms for Various Classes of Multiple Resource Constrained Project Scheduling Problems, unpublished PhD. dissertation, Katholieke Universiteit Leuven, Belgium, 1992
[12] E. Demeulemeester, W. Herroelen. New Benchmark Results for the Resource Constrained Project Scheduling Problem, Research Report 9521, Department of Applied Economics, K.U. Leuven, Belgium, 1995. [13] C. Le Pape. Implementation of Resource Constraints in ILOG SCHEDULE: A Library for the Development of Constraint-Based Scheduling Systems, Intelligent Systems Engineering, 1994, 3 (2), p. 55-66. [14] H. Lock. Optimizing the cumulative constraint by global capacity constraints, in Planen und Konfiguren, J. Sauer ed., Infix Verlag, 1996 [15] Lopez Approche énergétique pour l’ordonnancement de tâches sous contraintes de temps et de ressources, PhD Thesis, Université Paul Sabatier, (in french) 1991 [16] P. Martin, D. Shmoys. A New Approach to Computing Optimal Schedules for the Job Shop Scheduling Problem, in M. Queyranne (ed): Proceedings of IPCO’5, Vancouver, 1996, to appear in LNCS. [17] A. Mingozzi, V. Maniezzo, S. Ricciardelli, L. Bianco. An Exact Algorithm for Project Scehduling with Resource Constraints Based on a New Mathematical Formulation, Technical Report 32, University of Bologna, 1994. [18] W. Nuijten. Time and Resource Constrainted Scheduling, a constraint satisfaction approach, PhD. Dissertation, University of Eindhoven, 1994, [19] J.H. Patterson. A Comparison of Exact Procedures for solving the Multiple Constrained Resource Project Scheduling Problem, Management Science 30(7), 1984, p. 854-867. [20] Roseaux. Exercices et Problèmes résolus de recherche opérationelle. Vol 3., Masson, Paris, 1985. [21] J.P. Stinson. A Branch and Bound Algorithm for a General Class of Multiple Resource-Constrained Scheduling Problems, unpublished Ph.D. Dissertation, North Carolina State University, Raleigh [22] G. Smolka. The Oz Programming Model, Research Report RR-95-10, DFKI, Saarbrücken, July 1995.
7. Appendix Here is a short description of the three problems presented in this paper. Each small box represents a task (the product span x consumption is in italic, the minimal and maximal consumption are within brackets). Each directed link represent a precedence constraint; each bidirectional link represent a synchronization constraint (start at the same time). Each task is assigned to one resource (where #available is the number of available units for this resource). Here is our first problem (PB1). The others are available by the web from our pages http://www.ens.fr/users/dmi/laburthe, http://www.ens.fr/users/dmi/caseau
Resource 1 #available: 5
Resource 2 #available: 1
Resource 3 #available: 3
G1A 4 [2-2]
T1 2 [1-1]
B2+ 4 [1-4]
G227 [3-5]
T2 2 [1-1]
B23 [1-3]
G2A 6 [3-3]
T3 3 [1-1]
B2A 6 [3-3]
G318 [2-4]
T4 3 [1-1]
B3+ 12 [3-3]
G3+ 7 [1-1]
T5 2 [1-1]
B5+ 12 [2-3]
G618 [2-3]
T6 2 [1-1]
B612 [2-3]
G6A 4 [2-2]
T7 3 [1-1]
B8A 2 [1-1]
G7+ 8 [1-1]
T8 2 [1-1]
B914 [2-3]
G818 [2-4]
T9 2 [1-1]
B9A 6 [3-3]
G910 [5-5]
T0 4 [1-1]
B0A 4 [1-1]
G0+ 4 [1-2]
TX 2 [1-1]
BX13 [1-3]
GX20 [2-5]
TY 6 [1-1]
BY+ 5 [1-3]
GY+ 15 [5-5]