Faculteit IngenieurswetenschappenVakgroep Technische Bedrijfsvoering
Ontwikkeling van een time-window heuristiekvoor multimachine omsteltijdreductie
door:Joris April
Promotor: Prof. dr. ir. D. Van GoubergenCo-promotor: Prof. dr. ir. E.-H. Aghezzaf
Scriptie voorgedragen tot het behalen van de academische graad vanburgerlijk werktuigkundig-elektrotechnisch ingenieur
Optie:BedrijfskundeAcademiejaar 2006–2007
Faculteit IngenieurswetenschappenVakgroep Technische Bedrijfsvoering
Ontwikkeling van een time-window heuristiekvoor multimachine omsteltijdreductie
door:Joris April
Promotor: Prof. dr. ir. D. Van GoubergenCo-promotor: Prof. dr. ir. E.-H. Aghezzaf
Scriptie voorgedragen tot het behalen van de academische graad vanburgerlijk werktuigkundig-elektrotechnisch ingenieur
Optie:BedrijfskundeAcademiejaar 2006–2007
De auteur en promotor geven de toelating deze scriptie voor consultatie beschikbaar
te stellen en delen ervan te kopieren voor persoonlijk gebruik. Elk ander gebruik valt
onder de beperkingen van het auteursrecht, in het bijzonder met betrekking tot de
verplichting uitdrukkelijk de bron te vermelden bij het aanhalen van resultaten uit
deze scriptie.
The author and promoter give the permission to use this thesis for consultation and
to copy parts of it for personal use. Every other use is subject to the copyright laws,
more specifically the source must be extensively specified when using results from this
thesis.
Gent, Juni 2007
De promotor De auteur
Prof. dr. ir. D. Vangoubergen Joris April
VOORWOORD ii
Voorwoord
Graag wil ik mijn promotor, prof. dr. ir. D. Van Goubergen, en mijn co-promotor
prof. dr. ir. E.-H. Aghezzaf danken voor hun hulp en feedback bij mijn onderzoek en
bij het schrijven van de tekst.
Een scriptie is een zeer belastend werk. Graag wil ik de mensen uit mijn directe
omgeving bedanken voor het al dan niet vrijwillige meedragen van deze last. In het
bijzonder wil ik Eveline bedanken voor de morele steun en permanente nood-bijstand,
mijn ouders en familie voor de morele steun en meegaandheid, Stefaan voor het helpen
nalezen en de morele steun.
Joris April, juni 2007
Ontwikkeling van een time-window heuristiek
voor multimachine omsteltijdreductie
door
Joris April
Scriptie ingediend tot het behalen van de academische graad van
burgerlijk werktuigkundig-elektrotechnisch ingenieur:
Optie: Bedrijfskunde
Academiejaar 2005–2006
Promotor: Prof. dr. ir. D. Van Goubergen
Co-promotor: Prof. dr. ir. E.-H. Aghezzaf
Faculteit Ingenieurswetenschappen
Universiteit Gent
Vakgroep Technische Bedrijsvoering
Samenvatting
In dit werk wordt een heuristiek voorgesteld die de makespan (f1) van omsteltijdre-ducties op multi-machine productielijnen minimaliseert, en bij uitbreiding wordt ookhet minimaliseren van twee bijkomende doelfunctiewaarden (work-balance f2 en slackf3) bekeken. De doelfunctiewaarden en de probleemstelling zijn gebaseerd op het werkvan Van Goubergen (2001) en dit werk is een natuurlijke extensie. In hoofdstuk 1en 2 wordt de problematiek ingeleid. In hoofdstuk 3 wordt het probleem opgevat alseen ’RCPSP/max’-probleem, en worden RCPSP/max-heuristieken uit de literatuurbesproken. In hoofdstuk 4 wordt een voorstel tot heuristiek gedaan op basis van hetwerk van Smith (2004). Een implementatie van de heuristiek is bijgeleverd op CD-rom,de gebruiksaanwijzing en enkele programmeertechnische details worden besproken inhoofdstuk 5. De prestatie van de heuristische implementatie wordt beoordeeld aan dehand van de in Van Goubergen (2001) gepubliceerde testcases, resultaten zijn opgeno-men in hoofdstuk 6.
Trefwoorden
SMED, multi-machine omsteltijdreductie, change-over, set-up reduction, RCPSP/max,
scheduling heuristic, resource-constraints, maximum timelags, generalized precedence
constraints
A time-window heuristic for multimachine set-upreduction
Joris April
Supervisor(s): Prof. dr. ir. D. Van Goubergen, Prof. dr. ir. E.-H. Aghezzaf
Abstract— In this paper, a heuristic procedure for multi-machine setupreduction is proposed, as a natural extension to the works of Van Gouber-gen[1]. The problem is modeled as a resource-constrained project schedul-ing problem with generalized precedence constraints (RCPSP/max) and aheuristic is proposed, based on a RCPSP/max-heuristic by T. Smith [2]
Keywords— SMED, multi-machine setup, changeover, set-up reduction,RCPSP/max, scheduling heuristic, resource-constrained project schedul-ing, maximum timelags, generalized precedence constraints
I. INTRODUCTION
THE SMED-methodology, as proposed by Shingo in 1985,is well known among industrial engineers. However, [1]
was the first to provide a comprehensive framework whichadapts the SMED-principles to setups with multiple persons andmachines involved. In this iterative framework, a LP-model isimplemented to optimize the schedules of setup-activities to beperformed. For large problem instances, it was found that thecalculation times of this optimal branch-and-bound procedurewere too large for practical use. The purpose of this study isto find a scheduling heuristic that replaces the first step of themodel, i.e. the minimization of the downtime of the machine-line. As an extension, an effort is done to adapt the heuristicfor the optimization of secondary objectives, namely achievinga maximally balanced workload among setup performers andshifting ’idle times’ of the workers to the end of the setup. Theobjectives are hereby optimized in a pre-emptive fashion.
Since the problem constraints involved strongly relate to thewell-studied RCPSP, and more specifically the RCPSP/max, aheuristic for this last problem was adapted and implemented tosuit the problem at hand.
II. THE RCPSP/MAX
A. Definition RCPSP/max
A RCPSP/max consists of a set of tasks (J ) and a set of re-newable resources (K). Time is discrete. Each resource k hasa capacity of Rk units per timeslot, a task j takes Tj timeslotsto be executed and uses rj , k units of resource k in each times-lot of execution. A starting timeslot sTj needs to be assignedto each j ∈ J , so that the makespan (timeslot in which thelast activity finishes) is minimized. Both minimal and maximaltimelag-constraints are allowed between tasks:1. sTn − sTm ≥ lagmin
m,n
2. sTn − sTm ≤ lagmaxm,n
Of course, the resource capacity may never be exceeded.
B. Adaptation to RCPSP/max
The following constraints are to be taken into account for thesetup reduction problem:
• Labor: in each timeslot, Lmax workers are available (∈ K)• Precedence: j2 cannot start before j1 is finished: lagmin
j1,j2=
Tj1
• Consecutive: j2 starts right after j1: lagminj1,j2
= Tj1 andlagmax
j1,j2= Tj1
• Concurrence: sTj1 = sTj2 : lagminj1,j2
= 0 and lagmaxj1,j2
= 0• Disjunction: j1 and j2 cannot overlap. This is implementedby a fictitious resource k with capacity 1, of which each mem-ber of the disjunctive set requires one unit in each execution-timeslot.
III. HEURISTIC PRINCIPLES
A. Time-Windows
Suppose we consider a horizon of Tmax timeslots. Beforeschedule construction, a hard-window is determined for eachj ∈ J . A hard-window [hLj , hUj ] contains all possible startingtimes that are time-feasible (i.e. are consistent with the time-lagconstraints), with hLj ≥ Reltj (the earliest time at which j canstart due to the setup characteristics) and hUj ≤ Tmax−Tj +1.The hard windows are not changed during schedule construc-tion. Also, a soft-window is maintained for each task; [sLj , sUj ]contains, at each stage of schedule construction, all possiblestarting times for j that are consistent with all timelags, thismeans, all times at which j could be started without violatingany time-constraints with respect to the already scheduled tasks.It’s clear that [sLj , sUj ] ⊂ [hLj , hUj ]. The windows are kept sothat the greedy SGS-constructor could select candidate startingtimeslots easily at each stage.
B. Greedy schedule constructor
Each schedule is built from scratch by assigning the tasks insequence, this is a so-called serial schedule generation scheme(SGS). Activities are assigned in the order of descending prior-ity values in each iteration. The priorities are transferred andmodified from one iteration to another, this means the heuristicuses local search on the priority-order space (with learning ef-fect; priorities are passed on and modified) and it has the flavourof a ’multi-pass heuristic’. For each task j that has to be sched-uled, the SGS searches the soft-window for the earliest resource-feasible time. If none is found within the soft-window, then atthe end of the SGS procedure, the priorityj will be increased sothat in the next schedule construction, it will have moved to thetop of the queue, along with other tasks that were not succesfullyscheduled. They will have more chances of being scheduled fea-sibly when they are considered earlier (this is the principle ofSqueaky Wheel Optimization−SWO). The priorities of feasiblyscheduled tasks are also incremented, with a small value and a
small probability. This injects a randomness into the priority-listrepresentation, which will allow for alternative feasible sched-ules to be generated.
C. Basic Swo algorithm
The number n of schedule-construction attempts to be under-taken is chosen by the user. Before the start of these iterations,the value for Tmax is determined for which every task windowcontains at least one timeslot. This is a sort of lower bound,but only considering the time-constraints. After that, in eachiteration the greedy SGS procedure is run. If ten consecutiveiterations have failed in generating a feasible schedule, Tmax
is incremented and the hard-windows are re-calculated with re-spect to this new horizon. Note that this horizon elongationdoes not imply longer downtimes, it only implies more additionsand comparations in the computational procedure (checking re-source feasiblity). After the n SGS iterations, the implementedJava-program writes all starttimes and makespan-values to asheet ’Results’ within the file that provided the input. Only theschedules with the lowest downtime-values are kept and writtento the inputfile.
D. Swo with bulldozing
Smith [2] also proposes the following useful addition to hisheuristic. Instead of searching for the earliest feasible time-slott within the soft-window, all times within [sLj , hUj ] are consid-ered. If a time t within ]sUj , hUj ] is chosen, this means that twas initially time-feasible but that it has become time-infeasibledue to tasks that were scheduled earlier. j is scheduled at t andall tasks that are incompatibly scheduled with respect to thisplanning are sequentially descheduled, then rescheduled in thesame manner as j itself. This way each rescheduled task can in-voke a new set of tasks to be de- and rescheduled later. If at anypoint in this process, a task i has no resource-feasible candidatestarting-time within [sLi, hUi], the bulldozing mechanism hasfailed and all bulldozing must be undone. The original task jwhich invoked the initial bulldoze is moved to the top of the pri-ority queue after the current iteration and the global schedule ofthe current iteration will be unfeasible. As with the basic algo-rithm, after ten infeasible iterations, the horizon is incrementedand the different schedules with minimal downtime are writtento the Excel-file.
E. Swo with bulldozing and refilling
A second modifcation was made, as suggested in [2], butsince the implementation had some flaws and failed to deliverresults as good as bulldozing, while taking 10 times longer tocomputate, this is omitted here.
F. Secondary Objectives
While testing on the 7 test-instances provided in [1], it be-came clear that the procedures are capable of generating manydifferent schedules with the same optimal downtime. Methodswere added to also calculate the ’balance’(second objective) andthe ’slack’-objective (third objective) after generation of a feasi-ble schedule. Only the best schedules with respect to the pre-emptive optimalisation of the makespan, the balance and the
slack-function (in that order of importance) are stored and writ-ten to the Excel-sheet.
IV. CONCLUSION AND RESULTS
In all seven test-instances of [1], the optimal makespan wasreached after very few iterations. The main purpose of thestudy, namely finding a heuristic for optimizing the down-time/makespan of the setup, is thus fulfilled. The bulldozingalgorithm was found to be more efficient in finding many alter-native schedules, though it requires approximately 1,5 times thecalculation time of the basic algorithm. In three out of seveninstances, a makespan shorter than the one in [1](assumed to beoptimal) is found. The reason for this is not immediately ap-parent, this should be subject to further investigation. The foundsolutions were extensively checked with the constraints and datagiven in [1], and no inconsistencies were found.
With regards to the secondary objectives, no guarantuees canbe made. While for some instances the optimal for the secondobjective is reached, and for two test-instances even the optimalfor the third, no strong coherence can be seen between the per-formance on different test-instances. Of course, bulldozing doeshave the advantage over the basic algorithm due to its ability togenerate more feasible schedules, given a number of iterations.
In order to judge the performance more concisely, more test-cases should be optimally solved to be used as reference for theproposed heuristic. Of course, this requires solving the abovementioned downtime-issue in [1] first. Also, the window-basedstrategy could be tested with other metaheuristic strategies. [2]points out that Tabu Search would be a good match for thismethodology.
REFERENCES
[1] Dirk Van Goubergen, A methodology for set-up reduction of multi-stagemanufacturing lines, Ph.D. thesis, Ugent University, 2001.
[2] Tristan Smith, Window-based Project Scheduling Algorithms, Ph.D. thesis,University of Oregan, 2004.
INHOUDSOPGAVE vi
Inhoudsopgave
Voorwoord ii
Overzicht iii
Extended abstract iv
Inhoudsopgave vi
1 Inleiding 1
1.1 Set-ups en de huidige bedrijfscultuur . . . . . . . . . . . . . . . . . . . 1
1.2 Voordelen van korte set-ups . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2.1 Hogere flexibiliteit . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2.2 Grotere capaciteitsreserve . . . . . . . . . . . . . . . . . . . . . 3
1.2.3 Lagere productiekost . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Set-ups verbeteren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3.1 SMED-methodologie volgens Shingo . . . . . . . . . . . . . . . . 4
1.3.2 Algemene methode voor (N,M)-omstellingen . . . . . . . . . . . 6
2 Optimaliseren van de multischema’s via het kwantitatief model 9
2.1 Structurering van de gegevens . . . . . . . . . . . . . . . . . . . . . . . 9
2.2 Beslissings- en hulpvariabelen . . . . . . . . . . . . . . . . . . . . . . . 10
2.3 Randvoorwaarden/beperkingen . . . . . . . . . . . . . . . . . . . . . . 11
2.4 Optimalisatie-objectieven . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.5 Opbouw van de iteratieve algoritmes A1 en A2 . . . . . . . . . . . . . . 15
2.5.1 Opbouw van de iteraties: cutting-plane . . . . . . . . . . . . . . 16
2.5.2 Algoritme A1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5.3 Algoritme A2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.6 Toepassing van kwantitatief model op testcases . . . . . . . . . . . . . 23
2.6.1 CASE 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.6.2 CASE 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.6.3 CASE 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3 RCPSP-heuristieken in de literatuur 29
3.1 Het RCPSP-probleem . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.2 Classificatie van heuristieken uit de literatuur . . . . . . . . . . . . . . 30
INHOUDSOPGAVE vii
3.2.1 Serieel en parallel SGS . . . . . . . . . . . . . . . . . . . . . . . 31
3.2.2 X-pass heuristieken . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.2.3 Metaheuristieken . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.2.4 Andere heuristieken . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.3 Andere literatuuroverzichten RCPSP . . . . . . . . . . . . . . . . . . . 39
3.4 Het RCPSP/max-probleem . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.5 Literatuur RCPSP/max en keuze van een heuristiek . . . . . . . . . . . 42
4 Werking van het window-based algoritme 45
4.1 Aanpassing omstelprobleem aan RCPSP/max . . . . . . . . . . . . . . 45
4.1.1 Tijdsbeperkingen: time-lags . . . . . . . . . . . . . . . . . . . . 45
4.1.2 Resource-beperkingen . . . . . . . . . . . . . . . . . . . . . . . . 46
4.2 Basisprincipes van de heuristiek . . . . . . . . . . . . . . . . . . . . . . 47
4.2.1 Constraint-graph en herleiden van lagmax . . . . . . . . . . . . . 47
4.2.2 Het bijhouden van time-windows . . . . . . . . . . . . . . . . . 48
4.2.3 Het kernalgoritme: Squeaky Wheel Optimization . . . . . . . . 57
4.2.4 Aanvulling 1: Bulldozing . . . . . . . . . . . . . . . . . . . . . . 64
4.2.5 Aanvulling 2: Refilling . . . . . . . . . . . . . . . . . . . . . . . 69
4.2.6 Aanpassingen voor secundaire objectieven . . . . . . . . . . . . 74
5 Gebruik en details Java-implementatie 77
5.1 Gebruiksaanwijzing Java-implementatie . . . . . . . . . . . . . . . . . . 77
5.1.1 Installatie van de JRE . . . . . . . . . . . . . . . . . . . . . . . 77
5.1.2 Invullen van de MS Excel template . . . . . . . . . . . . . . . . 78
5.1.3 Uitvoeren van het Swo-algoritme . . . . . . . . . . . . . . . . . 80
5.2 Structurering van de JAVA-implementatie . . . . . . . . . . . . . . . . 81
6 Resultaten: toepassing op testcases 82
6.1 Case 1-1: Voor toepassing van SMED . . . . . . . . . . . . . . . . . . . 83
6.1.1 Selectie op basis van f1 . . . . . . . . . . . . . . . . . . . . . . . 83
6.1.2 Selectie op basis van f1 − f2 . . . . . . . . . . . . . . . . . . . . 84
6.1.3 Selectie op basis van f1 − f2 − f3 . . . . . . . . . . . . . . . . . 84
6.2 Case 1-2: Na toepassing van SMED . . . . . . . . . . . . . . . . . . . . 85
6.2.1 Selectie op basis van f1 . . . . . . . . . . . . . . . . . . . . . . . 85
6.2.2 Selectie op basis van f1 − f2 . . . . . . . . . . . . . . . . . . . . 85
6.2.3 Selectie op basis van f1 − f2 − f3 . . . . . . . . . . . . . . . . . 86
6.3 Case 1-3: Na SMED, nieuwe Relt(m) . . . . . . . . . . . . . . . . . . . 86
6.3.1 Selectie op basis van f1 . . . . . . . . . . . . . . . . . . . . . . . 86
6.3.2 Selectie op basis van f1 − f2 . . . . . . . . . . . . . . . . . . . . 86
6.3.3 Selectie op basis van f1 − f2 − f3 . . . . . . . . . . . . . . . . . 87
6.4 Case 1-4: Na SMED, nieuwe Relt(m), Lmax = 4 . . . . . . . . . . . . . 88
6.5 Case 2-1: Na SMED-stap 1 . . . . . . . . . . . . . . . . . . . . . . . . . 90
6.6 Case 2-2: Na SMED-stappen 2-3 . . . . . . . . . . . . . . . . . . . . . 91
6.7 Case 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
INHOUDSOPGAVE viii
7 Besluiten 94
7.1 Verwezenlijkingen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
7.1.1 Vervangen model ’1D’ in kwantitatief model door Van Goubergen
(algoritme A1) . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
7.1.2 Verschillende versies van het Swo-algoritme . . . . . . . . . . . 95
7.1.3 Bruikbare Java-implementatie . . . . . . . . . . . . . . . . . . . 95
7.1.4 Uitbreiden tot verdere stappen van algoritme A1 . . . . . . . . 95
7.2 Verdere mogelijkheden tot onderzoek . . . . . . . . . . . . . . . . . . . 96
A Gegevens van de testcases 98
A.1 Case 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
A.1.1 Voor toepassing van SMED . . . . . . . . . . . . . . . . . . . . 98
A.1.2 Na toepassing van SMED . . . . . . . . . . . . . . . . . . . . . 100
A.1.3 Situatie met gewijzigde ReleaseTimes . . . . . . . . . . . . . . . 101
A.1.4 Situatie met gewijzigde ReleaseTimes en een extra persoon . . . 102
A.2 Case 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
A.2.1 Na SMED-stap 1 . . . . . . . . . . . . . . . . . . . . . . . . . . 103
A.2.2 Na SMED-stappen 2-3 . . . . . . . . . . . . . . . . . . . . . . . 105
A.3 Case 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
A.3.1 Na SMED-stap 1 . . . . . . . . . . . . . . . . . . . . . . . . . . 106
B JAVA-implementatie sourcecode 111
B.1 Overzicht van de klassen . . . . . . . . . . . . . . . . . . . . . . . . . . 111
B.2 Klasse ’Task’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
B.3 Klasse ’Lag’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
B.4 Klasse ’Constraints’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
B.5 De ’abstracte’ klasse ’Resource’ . . . . . . . . . . . . . . . . . . . . . . 127
B.6 De klasse ’FictResource’ (modelleren van disjuncties) . . . . . . . . . . 127
B.7 De klasse ’MachineResource’ (modelleren van machine-disjuncties) . . . 128
B.8 De klasse ’LaborResource’ (modelleren van Lmax) . . . . . . . . . . . . 129
B.9 De klasse ’LaborResource’ (modelleren van Lmax) . . . . . . . . . . . . 129
B.10 Klasse ’UsageProfile’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
B.11 Klasse ’IOExcel’ (input-output-stockeren van de oplossingen . . . . . . 131
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) . . . . . . . 137
Bibliografie 154
Lijst van figuren 159
Lijst van tabellen 161
INLEIDING 1
Hoofdstuk 1
Inleiding
1.1 Set-ups en de huidige bedrijfscultuur
In een wereld waar de globalisering steeds doorgedrevener wordt, ligt de lat voor pro-
ductiebedrijven steeds hoger. Concurrenten bevinden zich niet meer op lokaal niveau,
maar over de gehele wereld. Afnemers van de producten krijgen via globale en laag-
drempelige communicatiemiddelen (zoals het internet), een steeds bredere kijk, steeds
bredere keuzemogelijkheden. Van Goubergen (2001) spreekt in dat verband van het
’buyer’s market’-tijdperk.
In deze tijd geldt dus meer dan ooit dat de klant koning is. Hij wordt steeds mondi-
ger en veeleisender. De fabrikant moet zo goed mogelijk inspelen op de klantenvraag,
vandaar de evolutie naar steeds meer productvarianten en steeds kleinere volumes per
variant. Als hierbij nog in rekening genomen wordt dat technologie steeds geavanceer-
der wordt en dus productiecapaciteiten per machine in de lift zitten, is snel duidelijk
dat het toewijzen van machines aan een enkele productvariant zelden nog economisch
verantwoordbaar is.
De machines worden dus gedeelde productiemiddelen (Eng: shared resources), elk
slechts voor een fractie van hun tijd toegewezen aan bepaalde productvarianten. Bij
elke omwisseling tussen producttype A en producttype B zal er dus een ’changeover’
of een ’set-up’ plaatsvinden. Van Goubergen definieert dit begrip als volgt (vrije ver-
taling):
Definitie 1.1 (Set-up = Changeover) Een set-up of een changeover bestaat uit al-
le activiteiten die uitgevoerd moeten worden om van een product A naar een product B
over te schakelen. De set-up tijd (omsteltijd) is de tijd die verloopt tussen het vertrek
1.2 Voordelen van korte set-ups 2
van het laatste product A uit de machine en het vertrek van het eerste goede (confor-
me) product B uit de machine, met dit product B geproduceerd aan een tempo volgens
de normstelling (normatief tempo). In overeenstemming met Van Goubergen (2001)
classificeren we set-ups volgens een koppel (X,Y), metX : aantal om te stellen machines op de lijn (zonder ongecontroleerde tussenbuffer)
Y : aantal personen die deelnemen aan de set-up
Aangezien machines overeenstemmen met hoge investeringsniveaus, is de downtime
van de machine op zich al een kost. Maar hoe hoger deze downtime, hoe hoger ook
de economische minimum productiebatches. Dit leidt tot lagere flexibiliteit en kosten
door overproductie.
Vroeger zagen firma’s set-uptijden hoofdzakelijk als een noodzakelijk kwaad, een on-
veranderlijke stoorfactor die bij de productieplanning in rekening te brengen was. Met
de opkomst van ’Lean-Manufacturing’,’World Class Manufacturing’ en ’Just-in-Time’
wordt nu zeer sterk de focus gelegd op waste reduction en flexibiliteit, d.w.z. kleine
lotsizes die de klantenvraag nauwgezet volgen. Reductie van de set-up downtime is een
middel bij uitstek om flexibiliteit op te voeren: de minimum lotsize wordt kleiner, dus
frequentere set-ups zijn mogelijk.
1.2 Voordelen van korte set-ups
De nood aan korte omsteltijden wordt uitgebreid besproken in Van Goubergen (2001,
Hoofdstuk 2). Ter informatie wordt hier kort een overzicht gegeven van de belangrijkste
voordelen. De lezer wordt doorverwezen naar het volledige werk voor meer info. Heel
dit inleidingshoofdstuk is trouwens gebaseerd op het werk Van Goubergen (2001), om
een algemene omkadering te kunnen geven van het centrale probleem van dit werk.
1.2.1 Hogere flexibiliteit
Zoals reeds gezegd, zijn klanten steeds veeleisender wat betreft kostprijs, kwaliteit,
leverbetrouwbaarheid, producteigenschappen en customization. Om hieraan te kunnen
voldoen is flexibiliteit essentieel. In de literatuur zijn vele pogingen ondernomen om
het intuitieve begrip ’flexibiliteit’ in een sluitende definitie te gieten. Zonder hier verder
op in te gaan kan gesteld worden dat volgende aspecten steeds aanwezig zijn:
• Product: mogelijkheid tot uitbreiden van het geproduceerde gamma aan pro-
ducten.
1.3 Set-ups verbeteren 3
• Mix: mogelijkheid tot heralloceren van productiemiddelen naar een andere mix
van geproduceerde goederen.
• Volume: mogelijkheid tot opdrijven van productiecapaciteit.
• Levering: mogelijkheid tot snel inspelen op klantenvraag en fluctuaties.
Het is reeds aangehaald dat een gereduceerde downtime kleinere economische produc-
tiebatches mogelijk maakt, en dus is het eenvoudiger om in te spelen op fluctuaties
in de vraag. Set-up reduction verhoogt dus zowel de mix-flexibiliteit als de volume-
flexibiliteit en is een belangrijke vereiste voor verhoogde flexibiliteit.
1.2.2 Grotere capaciteitsreserve
Bij een productielijn heeft men vaak te maken met een ’bottleneck’-resource (cf. de
’Theory of constraints’ van Goldratt & Cox (1984)). Dit is een productiemiddel waar-
van de capaciteit eigenlijk de globale capaciteit beperkt, omdat daar de grootste werk-
inhoud (in tijdseenheden) moet uitgevoerd worden. Elke verloren seconde op de bott-
leneck is een globaal verlies dat niet meer kan ingehaald worden. Set-up reduction kan
de belasting op de bottleneck verkleinen (meer tijd komt vrij voor het eigenlijke pro-
duceren). Er komt dan een reserve aan capaciteit zonder dat hier een grote investering
aan gekoppeld is.
1.2.3 Lagere productiekost
Op de geglobaliseerde markten is de prijs doorgaans niet stuurbaar door producenten,
maar eerder opgelegd door de markt en de vraag-aanbodverhouding. Winstmaxima-
lisatie is dan ook enkel mogelijk door minimaliseren van de kostenstructuur van een
product. Hiervoor is set-up reduction een onmisbare tool. Van Goubergen (2001) toont
de reductie van de productiekosten aan via een OEE-berekening (’Overall Equipment
Efficiency’, cfr. Van Goubergen (2000)).
1.3 Set-ups verbeteren
Een andere voorgestelde (en complementaire) indeling is die op basis van het tijdstip
waarop activiteiten kunnen uitgevoerd worden, zoals reeds voorgesteld in de oorspron-
kelijke SMED-methode (Shingo, 1985):
1.3 Set-ups verbeteren 4
1.3.1 SMED-methodologie volgens Shingo
De SMED-methode werd voor het eerst voorgesteld door Shingo (1985), en is gebaseerd
op diens werk op grote metaalpersen in de autonijverheid (vandaar de benaming S ingle
M inute Exchange of D ie). De methode is in zijn zuivere vorm enkel geschikt voor
(1,1)-setups. Het basisconcept is de indeling van activiteiten in on-line en off-line:
1. Interne of on-line activiteiten: worden uitgevoerd tijdens downtime van de
machine, terwijl de productie stil ligt.
2. Externe of off-line activiteiten: kunnen worden uitgevoerd terwijl de machine
werkt, dus voor of na de eigenlijke downtime van de machine.
De online-activiteiten leiden tot de werkelijke downtime van de machinelijn en moeten
dus geminimaliseerd worden. Bijkomend kunnen de offline-activiteiten gereduceerd
worden omdat dit een besparing in arbeidskosten geeft, en om zeker te zijn dat tijdens
de werking van de lijn er nog genoeg tijd voorhanden is om de off-line activiteiten uit
te voeren (belangrijk bij verkleinende productiebatches).
De basis van de SMED-methodologie zoals voorgesteld door Shingo (1985) bestaat uit
vier fasen en drie overgangsstappen daartussen (zie figuur 1.1).
• Stap 1: In de initiele, gemengde fase worden meestal alle activiteiten, ook diegene
die voor off-line uitvoering in aanmerking komen, uitgevoerd tijdens de downtime
van de machinelijn. Er is geen duidelijke werkinstructie, en de instel-activiteiten
gebeuren op basis van ’trial-and-error’. De eerste stap bestaat uit het duidelijk
oplijsten en opsplitsen van alle activiteiten in on-line en off-line, waarna de off-
line activiteiten ook werkelijk als off-line uitgevoerd worden, d.w.z. buiten de
downtime. Volgens Shingo (1985) kan hier de downtime gereduceerd worden met
30 % a 50 %.
• Stap 2: Hier worden zoveel mogelijk on-line activiteiten getransfereerd naar off-
line door technische modificaties (zoals het invoeren van modulaire componenten,
aanschaf van reserve-onderdelen zodat schoonmaakwerk en onderhoud off-line
kunnen gebeuren,. . . ). Volgens Shingo (1985) kan hier de downtime-reductie tot
75 % gaan.
• Stap 3: Het minimaliseren en stroomlijnen van alle overblijvende activiteiten. Er
gebeurt geen uitwisseling meer tussen on- en off-line, maar vooral de werkmethode
en de sequentie van de activiteiten wordt verbeterd. Er worden elektrische/pneu-
matische gereedschappen ingevoerd, gestandaardiseerde componenten ingevoerd
voor uitwisselbaarheid, er worden sets samengesteld voor een snelle set-up en
1.3 Set-ups verbeteren 5
een duidelijke werkinstructie wordt opgesteld voor alle deelnemende personen.
Ook alle instelproblemen en de daaruit volgende bijregelactiviteiten worden hier
verbeterd, met als doel de instellingen juist te kunnen zetten bij de eerste po-
ging (zelfpositionerende systemen, discrete instelwaarden,. . . ). Hierdoor worden
’testruns’ geelimineerd. Na deze stap komen we in de ’verbeterde fase’ met re-
ducties tot meer dan 90 %.
Figuur 1.1: Overzicht van de SMED-methode
De modificaties die door het SMED-proces van Shingo ingevoerd worden, vragen door-
gaans lage investeringen en geven toch grote downtime-verkortingen. Mechanisatie
komt pas in de laatste fase, omdat dit eigenlijk het ’wegpolijsten’ is van schoonheids-
foutjes; belangrijker is om in de eerste stappen structureel na te denken over het set-up
proces. SMED-stap 1 wordt vaak onmiddellijk in de praktijk gebracht, daar deze vaak
snel resultaat geeft zonder al te veel hindernissen. SMED-stap 2 en 3 worden in de
praktijk vaak simultaan uitgevoerd.
Van Goubergen (2001) geeft een uitgebreid overzicht van in de literatuur voorgestelde
aanvullingen op de basismethodologie. Hieruit blijkt dat de meeste literatuur wel te
herleiden valt tot de theorie van Shingo (1985), zijnde met enkele conceptuele ver-
schillen, zonder de fundamentele aard van de methode te veranderen. We overlopen
deze verschillende invalshoeken hier niet verder, daar dit niet echt bij de algemene
probleemsituering van dit hoofdstuk valt. In de literatuur worden tevens verschillen-
de tools voorgesteld die het SMED-denkproces aanzienlijk kunnen vergemakkelijken.
Van Goubergen (2001) brengt de nuttigste daarvan samen. In de volgende paragraaf
schetsen we een globaal overzicht van de aanvullingen die worden voorgesteld om de
SMED-methodologie van een conceptuele methode tot een direct toepasbaar frame-
work te transformeren, dat ook van toepassing is op situaties met meerdere machines
1.3 Set-ups verbeteren 6
in lijn, en meerdere personen die de set-up uitoefenen. SMED focust op zich immers
enkel op een (1,1)-omstelsituatie.
1.3.2 Algemene methode voor (N,M)-omstellingen
Van Goubergen (2001) stelt een methode voor die de basisideeen van SMED omzet naar
een framework voor (N,M)-omstellingen. We veronderstellen dat de omstelsituatie
duidelijk gekend is en een target voor de reductie vooropgesteld is. Multischema’s
spelen een sleutelrol in de methode. Ook zullen ze later belangrijk zijn voor de visuele
weergave van de bekomen resultaten.
Een multimachine-schema toont de verdeling van de taken over de machines; elke kolom
stemt overeen met een machine. Een multi-personen schema visualiseert de verdeling
van de taken over de verschillende personen (een kolom per persoon).
Definitie 1.2 (Multischema (Eng: Multi-activity diagram)) Uit de Britse stan-
daard BS3138 (vrij vertaald):
Een schema waarop de activiteiten van meer dan 1 entiteit (werknemer, gereedschap
of materiaal) weergegeven worden ten opzichte van een gemeenschappelijke tijdsschaal,
om de onderlinge relaties weer te geven.
Als voorbeelden zijn de figuren 1.2 en 1.3 toegevoegd.
Figuur 1.2: Multi-machineschema naar Van Goubergen (2001)
1.3 Set-ups verbeteren 7
Figuur 1.3: Multi-persoonschema naar Van Goubergen (2001)
Het iteratieve framework voor omsteltijdreductie voor (N,M)-omstellingen wordt sche-
matisch weergegeven in de flowchart van figuur 1.4. In stappen 2, 7 en 11 worden hierbij
optimalisaties van de bekomen multischema’s uitgevoerd m.b.t. een aantal objectie-
ven, waarvan het minimaliseren van de makespan het belangrijkste is. Van Goubergen
(2001) stelt (naast een kwalitatieve methode), een LP-model voor om deze optimalisa-
tie door te voeren. Dit model wordt besproken in hoofdstuk 2. Bij toepassing van dit
model is gebleken dat bij grote omstelproblemen de rekentijd praktisch niet werkbaar
is; het doel van dit werk is dan ook het zoeken van een heuristiek die binnen aanvaard-
bare tijd inplanningen kan vinden met (bijna-)minimale downtime (en zo mogelijk ook
goede waarden voor de andere objectieven). Voor meer details, zie hoofdstuk 2.
De indeling van on- en off-line activiteiten is in het geval van meerdere machines niet
meer zo eenduidig als in de SMED-methodologie door Shingo (1985). De downtime
van de verschillende machines starten niet altijd op hetzelfde moment. Wanneer de
machines in een lijn zonder veiligheidsproblemen kunnen ’ontkoppeld’ worden, kunnen
de eerste machines sneller uitgeschakeld worden terwijl de laatste prodcten A verder
in de lijn afgewerkt worden. Analoog kunnen de machines aan het begin van de lijn
ook vroegen opgestart worden. In het multimachine-schema zien we dan een ’band’
van downtimes (cfr. figuur 1.5); wanneer activiteiten in deze zone uitgevoerd worden,
spreken we van online, anders moeten het off-line activiteiten zijn.
1.3 Set-ups verbeteren 8
Figuur 1.4: (N,M)-omstellingen: reductiemethode (Van Goubergen, 2001)
Figuur 1.5: Multi-machineschema bij ontkoppelde machines (naar Van Goubergen (2001))
OPTIMALISEREN VAN DE MULTISCHEMA’S VIA HET KWANTITATIEF MODEL 9
Hoofdstuk 2
Optimaliseren van de multischema’s
via het kwantitatief model
Zoals hoger reeds besproken stelt Van Goubergen (2001) twee aanpakken voor om op
verschillende momenten in zijn iteratieve set-upreductiemethode de multischema’s te
optimaliseren, nl. kwantitatief en kwalitatief. Aangezien het onderwerp van deze thesis
het vinden van een heuristiek voor de eerste stap in het kwantitatief model (optima-
liseren van makespan) betreft, is het kwalitatief model eigenlijk irrelevant voor deze
uiteenzetting. De lezer wordt voor deze aanpak dan ook doorverwezen naar Van Gou-
bergen (2001). Dit hoofdstuk bespreekt de kwantitatieve aanpak en de voorgestelde
geıntegreerde algoritmes ’A1’ en ’A2’, en de daaruit voortvloeiende resultaten en pro-
bleemstelling voor deze scriptie.
2.1 Structurering van de gegevens
We beginnen met een overzicht van alle gegevens en de manier waarop ze in Van Gou-
bergen (2001) gestructureerd worden als input voor het mathematisch optimalisatie-
model.
Machines m = 1, . . . ,M
Lmax = totaal aantal beschikbare werknemers voor de omstelling
t = tijdsslots lopende over nummers 1, . . . , Tmax
Activiteiten/taken (Tasks): j = 1, . . . , J
J(m) = {j | j wordt uitgevoerd op machine m}Jf (m) = {j ∈ J(m) | j kan de laatste activiteit zijn op machine m}, dus Jf (m) ⊂J(m)
[Tj] = aantal tijdsslots nodig voor uitvoering taak j
[Lj] = aantal werknemers nodig bij uitvoering van taak j
2.2 Beslissings- en hulpvariabelen 10
Precedence set PD = {(j1, j2) | taak j1 moet eindigen voordat taak j2 kan starten}Disjunctieve set DJ = {(j1, j2) | taak j1 and j2 nooit gelijktijdig in uitvoering}Concurrente set CC = {(j1, j2) | taak j1 and j2 moeten gelijktijdig starten}Consecutieve set CS = {(j1, j2) | taak j2 start onmiddelijk na de voltooiing van j1}
2.2 Beslissings- en hulpvariabelen
xjt =
1 : als taak j begint in tijdsslot nummer t
0 : anders
st = slack hulpvariabele – aantal wachtende werknemers in tijdsslot t
Savg = gemiddelde slack gedurende de downtime van de machine (hulpvariabele)
Zt = |st − Savg|= afwijking van gemiddelde slack in tijdsslot t
Z0 = downtime van de machine = ’makespan’
Z0L = ondergrens (lower bound) voor de downtime/makespan
qt =
1 : als t ≤ Z0
0 : anders∀t = 1, . . . , Tmax
wt = continue hulpvariabele gebruikt in objectief 2 ∀t = 1, . . . , Tmax
Opmerkingen
• Tmax is een bovengrens voor de ’makespan’. In de algoritmes van Van Goubergen
(2001) is het zeer belangrijk om deze waarde niet te hoog te kiezen, omdat de
commerciele software die het LP-model oplost, gebruik maakt van ’branch-and-
bound’ methodes. Hoe hoger de waarde, hoe uitgebreider de branch-and-bound
boom. Als strategie wordt voorgesteld bij een te kleine Tmax te beginnen en te
incrementeren tot een oplossing gevonden wordt. Een andere strategie, voor een
reeds in de praktijk uitgevoerde omstelling, is te vertrekken van de huidige om-
steltijd (makespan), dan moet er sowieso een realiseerbare makespan gevonden
worden die kleiner of gelijk is aan deze bovengrens. In elk geval is het bepa-
len van de Tmax zodat de rekentijd van het probleem beperkt blijft, een van de
sleutelproblemen in het kwantitatief model. Voor een probleem dat onoplosbaar
is, is er bovendien geen garantie dat dit ook kan aangetoond worden binnen een
aanvaardbare rekentijd. Aangezien we hier echter een fysisch proces modelleren,
wil dit zeggen dat de vertaling van het reele probleem naar het abstract model
verkeerd verlopen is; er moet steeds een haalbare oplossing zijn.
• Door het invoeren van discrete tijdsslots in plaats van een continue tijdsschaal
wordt de complexiteit van het probleem beheersbaar. Na observatie van de ge-
2.3 Randvoorwaarden/beperkingen 11
maakte video-opnames zijn de taaktijden gekend tot op een seconde nauwkeurig.
Behalve voor zeer korte set-ups zal het echter geen zin hebben tijddslots van
1 seconde in te voeren; dit zal immers de rekentijd onhaalbaar groot maken.
Van Goubergen (2001) stelt een afronding naar grotere tijdseenheden voor (vaak
een of enkele minuten). Dit wordt dan ook verder gehanteerd in dit werk, omdat
de tijdsgegevens van de testcases in minuten zijn opgegeven.
• De deelverzameling Jf (m) is ingevoerd om het aantal beperkingen (constraints)
van het LP-model te beperken en wordt geconstrueerd op basis van de PD- en
de CS-sets. Het gaat hier dus niet om basisgegevens, maar afgeleide data.
• In de iteratieve globale omstelreductieaanpak (sectie 1.3.2) komt het optimalise-
ren van de multischema’s voor in verschillende stappen. Het spreekt voor zich dat
de gegevens na het toepassen van SMED-stap 1,2 en 3, aangepast moeten worden
(geschrapte taken, gereduceerde taaktijden, meer of minder deelnemers,. . . ).
• Om de set PD op te stellen wordt een ’precedence graph’ opgesteld, zodanig dat
geen redundante koppels ingevoerd worden. Als bijvoorbeeld (1, 2) en (2, 3) reeds
voorkomen heeft het geen zin om nog het koppel (1, 3) in te voeren.
• Voorstellen voor de ondergrens Z0L:
– als per machine alle taken onderling disjunctief zijn:
Z0L = max{∑J∈J(m) Tj} ∀m = 1, . . . ,M
– als parallele taken mogelijk zijn (algemener geval):
Z0L =∑
j TjLj
Lmax
• Als een taak j begint in tijdsslot t is de starttijd (t− 1) (begin van het tijdsslot):
[STj] = [∑
t (t− 1)xjt]
2.3 Randvoorwaarden/beperkingen
• Een aparte constraint wordt ingevoerd zodat elke taak j ∈ J op 1 en juist 1
starttijd ingepland wordt (merk op dat het laatste haalbare tijdsslot voor de
inplanning (Tmax − Tj + 1) is (cf. de in de heuristiek geıntroduceerde hard-
windows, in latere hoofdstukken):
Tmax−Tj+1∑t=1
xjt = 1 ∀j = 1, . . . , J (2.1)
2.3 Randvoorwaarden/beperkingen 12
• Aantal werknemers (’labor constraints ’): elke taak heeft een aantal personen
nodig. Op elk moment mogen er niet meer activiteiten in uitvoering zijn dan de
beschikbare werknemers kunnen uitvoeren.
t∑k=1
∑j:k+Tj≥t+1
Ljxjk ≤ Lmax ∀t = 1, . . . , Tmax (2.2a)
We kunnen dit ook uitdrukken aan de hand van de slackvariabele st om gelijk-
heden te bekomen:∑j
t∑k=max{1,t−Tj+1}
xjkLj + st = Lmax ∀t = 1, . . . , Tmax (2.2b)
• Er zijn tijdsbeperkingen tussen activiteiten (meestal binaire constraints, d.w.z.
tussen twee activiteiten). De verschillende soorten binaire constraints die op een
omstelling van toepassing kunnen zijn:
– Gewone precedence constraints (volgorde-beperkingen). Voorbeeld: taak
j2 kan pas beginnen na het voltooien van taak j1. Dit komt overeen met
STj2 ≥ STj1 + Tj1 of:∑t
(t− 1)xj2t ≥∑t
(t− 1)xj1t + Tj1 ∀t = 1, . . . , Tmax;∀(j1, j2) ∈ PD(2.3)
– Twee-aan-twee disjunctierelatie: Taken j1 en j2 mogen op geen enkel tijdstip
overlappen, met andere woorden nooit tegelijkertijd in uitvoering zijn.
t∑k=max{1,t−Tj1
−1}
xj1k+t∑
k=max{1,t−Tj2−1}
xj2k ≤ 1 ∀t = 1, . . . , Tmax;∀(j1, j2) ∈ DJ
(2.4)
– Machine-disjunctie voor alle machines: geen van de takenkoppels (j1, j2)
waarvoor geldt j1, j2 ∈ J(m), mogen onderling overlappen. Op elk van de
machines met een disjunctie kan dus slechts 1 taak tegelijk in uitvoering
zijn. Indien alle j ∈ J(m) opgenomen zijn in de ’precedence graph’ wordt
deze constraint overbodig voor die m. Let op: de DJ-set bevat de koppels
die uit deze constraints volgen niet.∑j∈J(m)
t∑k=max(1,t−Tj+1)
xjk ≤ 1 ∀t = 1, . . . , Tmax;∀m = 1, . . . ,M (2.5)
– Concurrente activiteiten: (j1, j2) waarvoor moet gelden STj1 = STj2 , beide
taken starten dus (ongeveer) gelijktijdig.
xj1t = xj2t ∀t = 1, . . . , Tmax; ∀(j1, j2) ∈ CC (2.6)
2.4 Optimalisatie-objectieven 13
– Consecutieve activiteiten (j1, j2): een striktere vorm van de gewone prece-
dence constraints. De taken j1 en j2 moeten hierbij net na elkaar uitgevoerd
worden; als taak j1 bijvoorbeeld eindigt in tijddslot 3 moet taak j2 beginnen
in tijdsslot 4.∑t
(t− 1)xj2t =∑t
(t− 1)xj1t + Tj1 ∀t = 1, . . . , Tmax;∀(j1, j2) ∈ CS(2.7)
• Er is ook nog een unaire tijdsbeperking op elke activiteit (dit wil zeggen een
beperking op de activiteit op zich, niet in relatie tot de inplanning van een an-
dere activiteit). De tijd waarop een activiteit kan beginnen hangt immers af van
het begin van de ’online-band’ op de desbetreffende machine (cfr. figuur 1.5).
Een taak die op machine ’m’ wordt uitgevoerd kan nooit beginnen voor tijdsslot
’Relt(m)’. Dit geheel getal stelt de ’release time’ van de corresponderende machi-
ne voor. Indien de machines niet fysisch ontkoppelbaar zijn is voor elke machine
de release time natuurlijk gelijk aan 1 (het eerste tijdsslot is het begin van de
planningshorizon).
xjt = 0 ∀t < Relt(m); j ∈ J(m);m = 1, . . . ,M (2.8)
2.4 Optimalisatie-objectieven
Het optimaliseren van de multischema’s gebeurt volgens vier objectieven. De wiskun-
dige uitdrukkingen van de objectieven zijn gegeven zonder opbouw van de redenering,
hiervoor wordt verwezen naar Van Goubergen (2001). Aangezien de objectieven tegen-
strijdig kunnen zijn, moet een rangorde vastgelegd worden van belangrijkheid. De vier
objectieven volgens Van Goubergen (2001) in volgorde van belangrijkheid:
1. De totale downtime van de machinelijn minimaliseren.
Minimaliseer f1 = Z0 (2.9a)
Onder voorwaarden:
Z0 ≥∑t
(t+ Tj − 1)xjt ∀j ∈ Jf (m);m = 1, . . . ,M (2.9b)
2. Het werk moet evenredig verdeeld worden tussen alle werknemers die deelnemen
aan de opstelling (balanced workload).
Minimaliseer f2 =∑t
Zt −∑t
st + SavgTmax (2.10a)
2.4 Optimalisatie-objectieven 14
Onder voorwaarden:
Zt ≥ st − Savg ∀t = 1, . . . , Tmax (2.10b)
Zt ≥ Savg − st ∀t = 1, . . . , Tmax (2.10c)∑t
wt =∑t
st − Lmax(Tmax − Z0) (2.10d)
Z0 =∑t
qt (2.10e)
0 ≤ wt ≤ (Lmax− 1)qt ∀t = 1, . . . , Tmax (2.10f)
0 ≤ Savg − wt ≤ (Lmax − 1)(1− qt) ∀t = 1, . . . , Tmax (2.10g)
(Tmax+1−t)qt ≥ Z0 +1−t ≥ qt−(1−qt)(t−1−Z0L) ∀t = 1, . . . , Tmax (2.10h)
3. Wachttijden (slack) moeten zoveel mogelijk aan het einde van de omstelling inge-
pland worden. Op die manier kunnen mensen die vrijkomen off-line activiteiten
uitvoeren of op ander werk gezet worden.
Minimaliseer f3 =
Z0∑t=1
αtst (2.11a)
Onder voorwaarde (vastleggen van de coefficienten αt):
αt = 1 + (Z0 − t)(Lmax + 1) ∀t = 1, . . . , Tmax (2.11b)
4. Het minimaliseren van de loopafstanden(uitgedrukt in doelfunctiewaarde f4).
Loopafstanden zijn een pure vorm van waste volgens de Lean Manufacturing-
theorie. Door de activiteitentoewijzing aan de verschillende personen te verande-
ren, kan het bewegingspatroon van de omstelling veranderd worden (visualiseer-
baar op een routing-schema). Zeer belangrijk is om op te merken dat de toewijzing
van activiteiten aan personen in feite niets te maken heeft met de inplanning van
de activiteiten in de tijd. Een toewijzing aan personen gebeurt dus pas nadat
een feasible schedule is opgebouwd, waarbij natuurlijk wel de Lmax (werknemers-
resource) niet mag overschreden worden. De toewijzing gebeurt achteraf gewoon
zo dat de ’loopafstanden’ geminimaliseerd worden. Om deze loopafstanden uit te
drukken tussen verschillende machines gebruikt Van Goubergen (2001) verschil-
lende weegfuncties in het ’Movement Network Model’ dat gebruikt wordt om de
optimale toewijzing van activiteiten aan welbepaalde werknemers te bepalen. Hij
maakt onderscheid tussen:
2.5 Opbouw van de iteratieve algoritmes A1 en A2 15
• Lineaire verplaatsingskost (linear movement cost) waarbij kan verondersteld
worden dat alle machines zich op 1 lijn bevinden (1-dimensionaal), en dat
de ’loopafstand’ tussen twee taken evenredig is met de absolute waarde van
het verschil in rangnummer van hun corresponderende machines.
• Kwadratische verplaatsingskosten (quadratic movement cost) waarbij de de
’loopafstand’ (verplaatsingskost) tussen machine m1 en m2 gelijk is aan het
kwadraat van hun rangnummerverschil: (m1 −m2)2
• Afstands-verplaatsingskost (distance movement cost) waarbij de afstand tus-
sen de verschillende machines wordt opgemeten/geschat en als de transitie-
kost tussen taken geldt.
Het is duidelijk dat deze laatste benadering veel realistischer zal zijn voor een
situatie waarbij machines niet rechtlijnig zijn opgesteld maar verspreid over de
ruimte.
Na het definieren van de transities/verplaatsingskosten wordt het ’Movement
Network Model’ (dat gebruikt maakt van netwerkmodellen (activity nets) aan het
werk gezet en het levert, voor het ingegeven schedule, de toewijzing van taken
aan personen, die de minimale totale ’verplaatsingskost’ oplevert. Dit model
wordt verder niet besproken, aangezien het niet van direct belang is voor onze
heuristische procedure. We willen immers in eerste instantie een feasible schedule
bepalen met minimale f1 (en bijkomend f2 en f3). Vervolgens kunnen we uit de
eventueel bekomen alternatieven met behulp van het model van Van Goubergen
(2001) deze kiezen dat de gunstigste optimale f ∗4 leveren.
Het is duidelijk dat het minimaliseren van de downtime (objectief f1) het belangrijkste
is, gevolgd door f2 . De belangrijkheid van f3 en f4 is eerder opiniegebonden (het
verschil tussen de in volgende sectie besproken procedures A1 en A2).
2.5 Opbouw van de iteratieve algoritmes A1 en A2
Van Goubergen (2001) bouwt een uitgebreid model op dat gebruik maakt van lineaire
programmering en een cutting-plane-werkwijze. Hij stelt twee optimalisatie-algoritmes
voor. Algoritme A1 minimaliseert volledig preemptief de vier hoger geıntroduceerde
objectieven. Dit wil zeggen dat eerst de minimale downtime bepaald wordt, vervolgens
de best mogelijke werkverdeling bij deze downtime,. . . Er wordt met andere woorden
geen afweging gemaakt tussen de verschillende objectieven, elk wordt afzonderlijk be-
handeld. Bij algoritme ’A2’ wordt eerst een gewogen doelfunctie van de eerste twee
2.5 Opbouw van de iteratieve algoritmes A1 en A2 16
objectieven geoptimaliseerd, daarna wordt preemptief voortgegaan om de twee volgen-
de objectieven zo goed mogelijk te realiseren.
2.5.1 Opbouw van de iteraties: cutting-plane
Omdat een LP-probleem steeds verschillende optimale oplossingen kan hebben, is het
belangrijk om de verschillende optimale oplossingen te kunnen bereiken met de op-
lossingsmethode, daar er wat betreft de nog te optimaliseren objectieven in verdere
stappen, een goede keuze zou kunnen gemaakt worden. Na elke iteratie wordt dus een
extra cutting-plane beperking ingevoerd, die de oplossing van de laatste iteratie als het
ware van de oplossingsruimte ’wegsnijdt’.
Stel dat de gevonden oplossing in de k-de iteratie overeenstemt met start-tijdsslots
tk(k) voor elke taak j. Na de K-de iteratie kan dan volgende beperking aan het model
toegevoegd worden om de gevonden oplossingen van alle voorgaande iteraties uit te
sluiten:
J∑j=1
xj,tk(j) ≤ (J − 1) ∀k = 1, . . . , K (2.12)
De iteraties kunnen afgebroken worden van zodra de optimale downtime-waarde stijgt,
of na een gewenst aantal oplossingen met optimale downtime. Iteraties moeten sowieso
stoppen als het probleem ’infeasible’ wordt.
2.5.2 Algoritme A1
Dit algoritme is volledig sequentieel (preemptief) opgebouwd, dit wil zeggen het op-
timaliseert de f1,f2,f3 achter elkaar. Door een cutting-plane methode vinden we een
set optimale oplossingen voor deze drie objectieven. Voor elk van deze oplossingen
wordt met het ’movement network model’ de taaktoewijzing (aan personen) bepaald
die een minimale verplaatsingskost geeft. De oplossing waarvoor de beste waarde voor
f4 gevonden wordt, wordt voorgedragen als de beste oplossing. Hieronder wordt de
wiskundige uitdrukking en een flowchart van algoritme A1 gegeven.
Model 1D - optimaliseren van de downtime (f1)
We brengen vergelijkingen 2.9,2.1,2.2b,2.8,2.3,2.4,2.5,2.7,2.6,2.10b,2.10c,2.10d samen
als beperkingen bij het minimaliseren van f1:
Minimaliseer f1 = Z0 (2.13a)
2.5 Opbouw van de iteratieve algoritmes A1 en A2 17
Onder voorwaarden:
Z0 ≥∑t
(t+ Tj − 1)xjt ∀j ∈ Jf (m);m = 1, . . . ,M (2.13b)
Tmax−Tj+1∑t=1
xjt = 1 ∀j = 1, . . . , J (2.13c)
∑j
t∑k=max{1,t−Tj+1}
xjkLj + st = Lmax ∀t = 1, . . . , Tmax (2.13d)
xjt = 0 ∀t < Relt(m); j ∈ J(m);m = 1, . . . ,M (2.13e)
∑t
(t− 1)xj2t ≥∑t
(t− 1)xj1t + Tj1 ∀t = 1, . . . , Tmax;∀(j1, j2) ∈ PD (2.13f)
t∑k=max{1,t−Tj1
−1}
xj1k +t∑
k=max{1,t−Tj2−1}
xj2k ≤ 1 ∀t = 1, . . . , Tmax;∀(j1, j2) ∈ DJ
(2.13g)
∑j∈J(m)
t∑k=max(1,t−Tj+1)
xjk ≤ 1 ∀t = 1, . . . , Tmax; ∀m = 1, . . . ,M (2.13h)
xj1t = xj2t ∀t = 1, . . . , Tmax,∀(j1, j2) ∈ CC (2.13i)
∑t
(t− 1)xj2t =∑t
(t− 1)xj1t + Tj1 ∀t = 1, . . . , Tmax;∀(j1, j2) ∈ CS (2.13j)
xjt ∈ {0, 1} (2.13k)
Deze eerste optimalisatiestap levert de optimale downtime Z∗0 . Deze wordt als input
gebruikt voor de tweede stap. Laatstgenoemde zoekt de oplossing met de beste werk-
verdeling (balanced workload, f2 bij een downtime Z∗0 .
Model 1B - optimaliseren van de ’workload balance’ (f2)
Het voorgestelde model voor de berekening van f2 (vergelijkingen 2.10) bevat de hulp-
variabelen qt en wt. Deze zijn enkel nodig indien de ingegeven waarde van Tmax (totaal
aantal beschouwde tijdsslots en dus bovengrens van de te vinden makespan) te groot
is. Er is dan een groep ongebruikte tijdsslots, aan het einde van de horizon, die uit de
berekening van de workload balance moeten weggelaten worden omdat zij een foutief
2.5 Opbouw van de iteratieve algoritmes A1 en A2 18
resultaat zouden veroorzaken. De verdeling van de workload moet inderdaad enkel
geoptimaliseerd worden over de tijdsslots die effectief gebruikt worden.
Aangezien echter hier de Tmax gelijkgesteld wordt door de door model 1D berekende
optimale makespan Z∗0 , hebben de hulpvariabelen geen belang meer. We kunnen aldus
vergelijkingen 2.10d tot 2.10h weglaten en vervangen door 2.13d. Deze berekent op
zeer eenvoudige wijze de gemiddelde slack over alle tijdsslots (Savg), uitgaande van de
slack -variabelen st in elk afzonderlijk tijdsslot.
Minimaliseer f2 =∑t
Zt (2.14a)
Onder voorwaarden:
Zt ≥ st − Savg ∀t = 1, . . . , Z∗0 (2.14b)
Zt ≥ Savg − st ∀t = 1, . . . , Z∗0 (2.14c)
SavgZ∗0 =
Z∗0∑
t=1
st (2.14d)
xjt ∈ {0, 1} (2.14e)
Hier worden vergelijkingen 2.13c tot 2.13j aan toegevoegd, waarin Tmax door Z∗0 ge-
substitueerd wordt.
Vergelijking 2.13c zal (na substitutie Tmax = Z∗0) automatisch de downtime Z∗0 opdrin-
gen.
Model 1S - slack zoveel mogelijk naar het einde toe leggen (f3)
Volledig gebaseerd op vergelijkingen 2.11 en voorgaande modellen:
Minimaliseer f3 = 1 +
Z∗0∑
t=1
(Z∗0 − t)(Lmax + 1)st (2.15a)
Onder voorwaarden:Z∗
0∑t=1
Zt ≤ f ∗2 (2.15b)
+ vergelijkingen 2.14b tot 2.14d
+ vergelijkingen 2.13c tot 2.13j, waarin Tmax=Z∗0
2.5 Opbouw van de iteratieve algoritmes A1 en A2 19
xjt ∈ {0, 1} (2.15c)
Model 1CP - cutting-plane iteraties
Een constraint wordt toegevoegd om het oplossingsgebied te beperken tot oplossingen
met waarde f3 = f ∗3 , zodat vanaf nu enkel oplossingen mogelijk zijn die de optimale
waarden f ∗1 , f ∗2 en f ∗3 behouden. We zoeken dus simpelweg naar alternatieve optimale
oplossingen, daarom wordt een ’null ’-doelfunctie toegevoegd; er is geen bijkomende
specifieke doelfunctie. De cutting-plane beperkingen worden toegevoegd zodat de reeds
bekomen optimale oplossingen in vorige iteraties nu buiten het oplossingsgebied vallen.
Een nieuwe bekomen oplossing zal dus minstens in 1 starttijd verschillen van de reeds
bekomen optimale oplossingen.
Minimaliseer (’null ’ doelfunctie) (2.16a)
Onder voorwaarden:
f3 ≤ f ∗3 (2.16b)
+ vergelijking 2.15b
+ vergelijkingen 2.14b tot 2.14d
+ vergelijkingen 2.13c tot 2.13j, waarin Tmax=Z∗0
xjt ∈ {0, 1} (2.16c)
Initialisatie
Voor de eerste iteratie moeten alle datasets in de vroeger beschreven datastructuur ge-
goten worden. Speciale aandacht moet besteed worden aan het kiezen van de tijdsslots
(niet te kort) en het kiezen van de maximale horizon Tmax (niet te groot).
In onderstaande figuur wordt het stroomschema van het geıntegreerde algoritme weer-
gegeven (hoe alle modellen samengebracht worden). Deze figuur is naar vorm volledig
overgenomen uit Van Goubergen (2001), maar is vertaald.
2.5 Opbouw van de iteratieve algoritmes A1 en A2 20
Figuur 2.1: Flowchart van algoritme A1 (naar Van Goubergen (2001))
2.5.3 Algoritme A2
In dit algoritme wordt niet puur preemptief gewerkt. De doelfuncties f1 en f2 worden
lineair gecombineerd tot een eerste doelfunctie ’f1 + µf2’. In Van Goubergen (2001)
wordt aangetoond dat, bij een geschikte keuze van µ, dit overeenkomt met het bekomen
van een optimale oplossing voor de twee doelfuncties afzonderlijk. Hierna worden
cutting-plane beperkingen toegevoegd om alternatieve optimale oplossingen te bekomen
voor de gecombineerde doelfunctie. Over alle bekomen optimale oplossingen worden
vervolgens diegene bepaald die via het netwerkmodel voor verplaatsingen de kleinste
f ∗4 genereren. Uit de set met minimale f ∗4 wordt vervolgens diegene behouden die de
minimale waarde voor f3 levert. Ten opzichte van A1 wordt dus het onderlinge belang
van f3 en f4 omgewisseld.
Model 1DB - gecombineerde doelfunctie (downtime en balanced workload)
We optimaliseren de gecombineerde doelfunctie (vergelijkingen 2.9a en 2.10a), onder-
worpen aan alle relevante beperkingen: vergelijkingen 2.9b,2.1,2.2b,2.8,2.3,2.5,2.4,2.6,2.7,2.10b
t.e.m. 2.10h.
2.5 Opbouw van de iteratieve algoritmes A1 en A2 21
Minimaliseer Z = Z0 + µ(∑t
Zt −∑t
st + SavgTmax) (2.17a)
Hierin is 0 ≤ µ ≤ 1LmaxTmax
een experimenteel bepaalde parameter.
Onder voorwaarden:
Z0 ≥∑t
(t+ Tj − 1)xjt ∀j ∈ Jf (m);m = 1, . . . ,M (2.17b)
Tmax−Tj+1∑t=1
xjt = 1 ∀j = 1, . . . , J (2.17c)
∑j
t∑k=max{1,t−Tj+1}
xjkLj + st = Lmax ∀t = 1, . . . , Tmax (2.17d)
xjt = 0 ∀t < Relt(m), j ∈ J(m);m = 1, . . . ,M (2.17e)
∑t
(t− 1)xj2t ≥∑t
(t− 1)xj1t + Tj1 ∀t = 1, . . . , Tmax;∀(j1, j2) ∈ PD (2.17f)
t∑k=max{1,t−Tj1
−1}
xj1k +t∑
k=max{1,t−Tj2−1}
xj2k ≤ 1 ∀t = 1, . . . , Tmax;∀(j1, j2) ∈ DJ
(2.17g)
∑j∈J(m)
t∑k=max(1,t−Tj+1)
xjk ≤ 1 ∀t = 1, . . . , Tmax; ∀m = 1, . . . ,M (2.17h)
xj1t = xj2t ∀t = 1, . . . , Tmax;∀(j1, j2) ∈ CC (2.17i)
∑t
(t− 1)xj2t =∑t
(t− 1)xj1t + Tj1 ∀t = 1, . . . , Tmax;∀(j1, j2) ∈ CS (2.17j)
Zt ≥ st − Savg ∀t = 1, . . . , Tmax (2.17k)
Zt ≥ Savg − st ∀t = 1, . . . , Tmax (2.17l)
∑t
wt =∑t
st − Lmax(Tmax − Z0) (2.17m)
2.5 Opbouw van de iteratieve algoritmes A1 en A2 22
Z0 =∑t
qt (2.17n)
0 ≤ wt ≤ (Lmax − 1)qt ∀t = 1, . . . , Tmax (2.17o)
0 ≤ Savg − wt ≤ (Lmax − 1)(1− qt) ∀t = 1, . . . , Tmax (2.17p)
(Tmax + 1− t)qt ≥ Z0 + 1− t ≥ qt − (1− qt)(t− 1− Z0L) ∀t = 1, . . . , Tmax (2.17q)
xjt, qt ∈ {0, 1} (2.17r)
wt ∈ R (2.17s)
Model 1CP2 - cutting-plane (alternatieve optimale oplossingen zoeken voor 1DB)
Bijkomende beperkingen worden toegevoegd om optimale waarden Z∗0 en f ∗2 te be-
houden. Cutting-plane constraints worden ingevoerd om de reeds bekomen optimale
oplossingen voor model 1DB weg te snijden van de oplossingsruimte. Zoals bij algorit-
me A1 worden ook hier de hulpvariabelen qt en wt overbodig, omdat geen compensatie
meer nodig is voor de ongebruikte tijdsslots in de horizon Tmax. Tmax wordt hier
immers gesubstitueerd door de reeds bekomen optimale downtime/makespan Z∗0 . De
vergelijkingen 2.17m tot 2.17q kunnen aldus weggelaten worden.
Minimaliseer (’null ’ doelfunctie) (2.18a)
Onder voorwaarden:Z∗
0∑t=1
Zt ≤ f ∗2 (2.18b)
SavgZ∗0 =
Z∗0∑
t=1
st (2.18c)
J∑j=1
xj,tk(j) ≤ (J − 1) ∀k = 1, . . . , K (cutting-plane) (2.18d)
+ vergelijkingen 2.17c tot en met 2.17l waarin Tmax = Z∗0
xjt ∈ {0, 1} (2.18e)
2.6 Toepassing van kwantitatief model op testcases 23
Ook hierbij geldt de opmerking dat de optimale downtime f ∗1 automatisch wordt op-
gedrongen door in vergelijking 2.17c te substitueren (Tmax = Z∗0). De initialisatie
gebeurt analoog als in algoritme A1. De vertaalde flowchart voor algoritme A2 uit
Van Goubergen (2001) wordt gegeven in figuur 2.2.
Figuur 2.2: Flowchart van algoritme A2 (naar Van Goubergen (2001))
2.6 Toepassing van kwantitatief model op testcases
Door Van Goubergen (2001) worden de algoritmes A1 en A2 toegepast op drie test-
cases, in de verschillende relevante stappen van de algemene methode voor (N,M)-
omstellingen (initiele fase, na SMED-stap 1 en na SMED-stappen 2-3, cfr. sectie 1.3.2).
Het kwantitatief branch-and-bound model zoals besproken in dit hoofdstuk werd
geımplementeerd voor gebruik met CPLEX, een softwarepakket voor lineaire program-
mering. De *.mod-inputfile met alle probleemgegevens werd gegenereerd met behulp
van een MS-Excel template (Visual Basic-macro’s).
We geven hier kort een overzicht van de daarbij bekomen resultaten die Van Goubergen
(2001) aanhaalt, en vooral ook van de probleempunten bij het toepassen van het kwan-
titatief model. De resultaten kunnen vervolgens gebruikt worden als referentie van de
bekomen resultaten van de heuristische implementatie. De door Van Goubergen (2001)
2.6 Toepassing van kwantitatief model op testcases 24
aangehaalde probleempunten zullen tevens de motiveren vormen voor het zoeken naar
een heuristiek (het doel van deze scriptie).
De gegevens van de testcases in de verschillende fases zijn opgenomen in appendix
A. Hierbij dient vermeld te worden dat enkel de basisgegevens vermeld zijn, die ook
de enige input vormen voor de verder besproken heuristiek. Van Goubergen (2001)
gebruikt nog enkele andere hulp-datastructuren en verzamelingen, die echter allemaal
opgebouwd kunnen worden vertrekkende van deze basisgegevens (cf. de bespreking van
de data van het kwantitatief model, 2.1).
2.6.1 CASE 1
Deze case is eerder klein (14 activiteiten), met een beperkt aantal constraints.
Case 1-1: Voor SMED
In de initiele situatie (voor het toepassen van SMED) komt Van Goubergen (2001) tot
de resultaten van tabel 2.1 (toepassing van algoritme A1 en algoritme A2).
Tabel 2.1: Resultaten van Van Goubergen (2001) voor case 1-1
f1 f2 f3 f4 # optimale Run-tijd # cuttingdowntime balance slack movement oplossingen planes
A1 lin mov cost 11 3,27273 6 9 1 2 min 126A1 dist mov cost 11 3,27273 6 23 3 2 min 126A2 lin mov cost 11,0655 6 9 1 212 min 1290
(11 met opt. f4)A2 dist mov cost 11,0655 46 21 2 212 min 1290
(7 met opt. f4)
Hierin is in de oplossing door algoritme A2 de waarde 11, 0655 de uitkomst van de
gecombineerde doelfunctie f1 +µf2 met µ een experimenteel bepaalde parameter zoals
hoger in dit hoofdstuk besproken. Deze waarde stemt overeen met die van de optimale
oplossing die gevonden werd door algoritme A1 (nl. f1 = 11 en f2 = 3, 2727). A1 en
A2 twee vinden dezelfde optimale oplosssing bij lineaire afstandskosten, A2 echter na
een veel langere rekentijd.
Van Goubergen (2001) bespreekt ook nog een oplossing van dit basisprobleem met
andere ’verplaatsingskosten’, de in de tabel afgebeelde ’distance movement costs’, die
gebaseerd zijn op de werkelijke afstand tussen de machines. Dit is enkel van belang
voor de bepaling van f4 in het pre-emptieve algoritme A1; bij wijziging van de ’ver-
plaatsingskosten’ zal hoogstens een ander schedule geselecteerd worden met dezelfde
2.6 Toepassing van kwantitatief model op testcases 25
waarden f1, f2 en f3, dat echter een betere f ∗4 levert (cf. figuur 2.1).Voor A2 wijzigt
het veranderen van de kosten in het ’movement network model’de oplossing zowel wat
betreft f3 als f4. De reden waarom is dat A2 in feite doelfunctie f3 na f4 stelt qua
belangrijkheid (cf. figuur 2.2).
Aangezien wij de later besproken heuristiek enkel zullen gebruiken voor de volgorde
f1 − f2 − f3 (wegens zijn intrinsieke eigenschappen), doen de verschillende afstands-
kosten eigenlijk niet ter zake als vergelijkingspunt voor de heuristiek; na het bepalen
van een feasible en ’optimaal’ schedule met betrekking tot de eerste drie objectieven
kan de taaktoewijzing apart gebeuren met behulp van een model dat de loopafstand
minimaliseert.
Dit stemt qua methodologie in feite volledig overeen met A1. Voor deze en alle in de
volgende punten besproken resultaten, zijn dus de oplossingen door A1 als vergelij-
kingspunt de belangrijkste (en enkel de eerste drie doelfunctiewaarden, dus de gekozen
’verplaatsingskosten’ maken in casu weinig verschil). De resultaten van A2 worden
vermeld ter informatie en vergelijking.
Case 1-2: Na SMED
Na het toepassen van SMED op case 1 geeft Van Goubergen (2001) de resultaten uit
tabel 2.2. Merk op dat ten opzichte van case 1-1 de tijdsslots verkleind zijn van 30
minuten naar 1 minuut, vandaar de grotere waarden voor de optimalisatie-objectieven.
Merk ook op dat hier alle releasetimes van de activiteiten j ∈ J op 1 staan, met
andere woorden, alle activiteiten worden ogenblikkelijk vrijgegeven aan het begin van
de horizon.
Tabel 2.2: Resultaten van Van Goubergen (2001) voor case 1-2
f1 f2 f3 f4 # opt. Opl. # cutting planes
A1 lin mov cost 60 0 0 10 4 10
A1 quadr mov cost 60 0 0 26 3 10
A1 dist mov cost 60 0 0 16 1 10
A2 dist mov cost 60 0 16 1 10
(1 met opt. f4)
Case 1-3: Na SMED, met verschillende Relt(m)
Om een meer realistische situatie te modelleren, kunnen de activiteiten j ∈ J(m) een
releasetime verschillend van 1 (eerste tijdsslot) meekrijgen. De gegevens zijn wederom
2.6 Toepassing van kwantitatief model op testcases 26
te vinden in appendix A. Zie tabel 2.3 voor de door Van Goubergen (2001) bekomen
resultaten.
Opvallend hierbij is dat de f1 waarde groter is dan in de vorige situatie. Toch is de
downtime van de lijn echter korter: zoals besproken in hoofdstuk 1 moet de eigenlijke
downtime gemeten worden aan de laatste machine. Aangezien de releasetime van de
laatste machine 41 bedraagrt, is de feitelijke downtime dus 72 − 41 = 31, wat veel
minder is dan in de vorige situatie.
Tabel 2.3: Resultaten van Van Goubergen (2001) voor case 1-3
f1 f2 f3 f4 # opt. Opl. # cutting planes
A1 lin mov cost 72 36 7356 12 1 2
A2 quadr mov cost 72 36 7356 30 1 2
A1 dist mov cost 72 36 7356 20 1 2
A2 dist mov cost 72,72 7356 20 1 6
(3 met opt f4)
Case 1-4: Extra werkkracht
De releasetimes worden op hun gewijzigde waarden vastgehouden, echter bij deze laat-
ste te testen situatie wordt een extra werkkracht toegevoegd zodat nu Lmax = 4.
Van Goubergen (2001) bekomt de resultaten in tabel 2.4. Analoog geldt hier dat de
reele downtime van de lijn gelijk is aan 66− 41 = 25.
Tabel 2.4: Resultaten van Van Goubergen (2001) voor case 1-4
f1 f2 f3 f4 # opt. Opl. # cutting planes
A1 lin mov cost 66 38,3636 15409 6 2 2
A2 quadr mov cost 66 38,3636 15409 10 1 2
A1 dist mov cost 66 38,3636 15409 7 2 2
A2 dist mov cost 66,7673 16009 6 2 108
(12 met opt f4)
2.6 Toepassing van kwantitatief model op testcases 27
2.6.2 CASE 2
Case 2-1: Na SMED-stap 1
Na het toepassen van SMED stap 1 op deze testcase paste Van Goubergen (2001) het
kwantitatief model (A1) toe en kwam tot de waarden van tabel 2.5.
Tabel 2.5: Resultaten van Van Goubergen (2001) voor case 2-1
f1 f2 f3 f4 # opt. Opl. # cutting planes
A1 lin mov cost 50 24,36 1959 15 2 57
Case 2-2: Na SMED-stappen 2 en 3
Na het voltooien van de SMED-stappen volgen de resultaten uit tabel 2.6.
Tabel 2.6: Resultaten van Van Goubergen (2001) voor case 2-2
f1 f2 f3 f4 # opt. Opl. # cutting planes
A1 lin mov cost 40 19,95 1506 9 4 333
2.6.3 CASE 3
Deze case is een van de omvangrijkste die Van Goubergen uit de talrijke field-experience
haalde (gegevens wederom opgenomen in appendix A). Bijgevolg kan deze case later
als een echte graadmeter dienen voor de prestaties van onze heuristiek. Het is ook
deze case die de rechtstreekse aanleiding geeft tot de probleemstelling van dit werk.
De toepassing van het kwantitatief model leverde immers geen volledige oplossing voor
alle vier de stappen van het pre-emptief algoritme A1 (en aangezien A2 altijd meer
rekentijd opleverde is dit al zeker niet geschikt).
De run van A1 werd onderbroken na enkele dagen rekentijd (het is immers duidelijk dat
dit geen praktisch gebruik meer toelaat), en daaruit volgde enkel de optimale waarde
68 voor f1 (de downtime). De eerste stap van A1 was dus voltooid maar nam zeer veel
rekentijd in beslag. De hoofdbedoeling van dit werk is dan ook een heuristiek te vinden
die met een grote betrouwbaarheid een f1-waarde levert die optimaal is of in elk geval
dicht tegen het optimum ligt. De enige input naar de volgende stap van algoritme
A1 (dus naar model 1B) is immer de numerieke waarde Z∗0 = f ∗1 . Indien deze taak
volbracht is kan:
2.6 Toepassing van kwantitatief model op testcases 28
1. Getest worden of inderdaad de verhoopte rekentijdreductie kan bekomen worden
door de f1-bepaling van de heuristiek als vervanging van de eerste stap van A1
in te lassen.
2. Bekeken worden of de heuristiek zich leent tot het verder optimaliseren van de
volgende doelfuncties via aanpassingen.
Tabel 2.7: Resultaten van Van Goubergen (2001) voor case 3
f1 f2 f3 f4 # opt. Opl. # cutting planes
A1 lin mov cost 68 / / / / /
RCPSP-HEURISTIEKEN IN DE LITERATUUR 29
Hoofdstuk 3
RCPSP-heuristieken in de
literatuur
3.1 Het RCPSP-probleem
Het RCPSP, of ’Resource Constrained Project Scheduling Problem’, is een probleem
waarover enorm veel publicaties bestaan. Het probleem wordt door Kolisch en Hart-
mann in hun verschillende publicaties als volgt geformuleerd (vrij vertaald):
Definitie 3.1 (RCPSP) Een in te plannen project dat bestaat uit een set in te plan-
nen taken/activiteiten J = {0, . . . , J, J + 1}. Hierbij zijn taak ’0’ en ’J + 1’ respectie-
velijk de fictieve start- en eindactiviteiten.
De inplanning van de activiteiten gebeurt zo dat de ’makespan’(tijd waarna alle ac-
tiviteiten beeindigd zijn) geminimaliseerd wordt, en is aan twee soorten ’constraints’
(beperkingen) onderworpen:
1. ’Precedence constraints’: Voor elke taak j bevat de verzameling Pj de directe
voorgangers van j; taak j kan niet gestart worden zolang niet alle k ∈ Pj voltooid
zijn.
2. ’Resource constraints’: Het uitvoeren van de taken vereist ’resources’ (produc-
tiemiddelen) met beperkte capaciteit. De verzameling resources is gegeven door
K = {1, . . . , K}. Tijdens de uitvoering verbruikt taak j rj,k eenheden van resour-
ce k ∈ K, en dat gedurende elk tijdsslot van de uitvoerlengte Tj. Elke resource k
heeft een totale en constante capaciteit Rk in elk tijdsslot.
pj, rj,k en Rk worden deterministisch en constant verondersteld. Voor de fictieve begin-
en eindactiviteit geldt natuurlijk pj = 0 en rj,k = 0 (∀k ∈ K).
Het probleem zoals het hier geformuleerd is, wordt reeds sinds de jaren ’60 uitgebreid
behandeld in allerhande publicaties en is een uitbreiding van het klassieke job-shop
3.2 Classificatie van heuristieken uit de literatuur 30
schedulingprobleem. Een van de eerste ’integer linear programming’-beschrijvingen
is te vinden in Pritsker et al. (2000). Bij het bekijken van deze formulering valt di-
rect de gelijkvormigheid op met de kwantitatieve formulering van het omstelprobleem
uit Van Goubergen (2001). Het is echter ook duidelijk dat alle tijdsbeperkingen van
omstelproblemen niet zomaar te modelleren zijn binnen deze probleemformulering. In-
derdaad, naast precedence constraints moeten er ook disjuncties, gelijktijdige taken en
taken die elkaar onmiddelijk opvolgen ingevoerd worden. De aard van de beperkin-
gen in het omstelprobleem zullen dus het omstelprobleem complexer maken dan het
algemeen RCPSP.
We kunnen vaststellen dat het omstelprobleem NP-hard is qua complexiteit, aange-
zien Blazewicz et al. (1983) reeds besluiten dat het basis-RCPSP NP-hard is. Het is
dus duidelijk dat bij grote problemen, zoals CASE 3 uit Van Goubergen (2001), heuris-
tieken een noddzaak worden om het probleem op te lossen binnen praktisch werkbare
rekentijden.
Het is niet direct duidelijk hoe de extra constraints kunnen ingevoerd worden in de
algemene probleemstelling als in definitie 3.1. Het is mogelijk dat bepaalde heuristie-
ken aanpasbaar zijn. Dit is echter zeker niet triviaal, aangezien deze constraints de
complexiteit en de vorm van de oplossingsruimte behoorlijk wijzigen. Heuristieken zijn
vaak net zo ingespeeld op de generieke probleemformulering, dat ze de structuur van
de oplossingsruimte optimaal benutten.
3.2 Classificatie van heuristieken uit de literatuur
Zoals hoger reeds aangebracht, is de literatuur over het algemene RCPSP enorm uitge-
breid, zowel wat betreft optimale methodes als heuristieken. Aangezien het probleem
NP-hard is, zullen optimale procedures weinig praktisch zijn qua rekentijd, en worden
ze vooral gebruikt om optimale oplossingen te bepalen van testproblemen (benchmar-
king) (Kolisch & Hartmann, 1999).
Hier wordt kort een overzicht gegeven van de belangrijkste types heuristieken die in
de literatuur voorgesteld worden voor de oplossing van het RCPSP. Dit overzicht is
gebaseerd op de overzichten van Hartmann & Kolisch (2000), Kolisch & Hartmann
(2006), Kolisch & Hartmann (1999) wat betreft indeling. Er zijn nog talrijke andere
overzichten beschikbaar, waaronder Ozdamar & Ulusoy (1995), . . . De basisindeling die
Kolisch en Hartmann consequent gebruiken is echter interessant voor deze uiteenzet-
ting, omdat zij voor de classificatie uitgaan van de opbouw van de heuristiek. Op die
manier krijgt men een algemeen beeld van de verschillende heuristische invalshoeken
die mogelijk zijn bij scheduling-problemen.
3.2 Classificatie van heuristieken uit de literatuur 31
3.2.1 Serieel en parallel SGS
De zogenaamde ’schedule generation schemes ’(SGS) zijn een basisbouwsteen in zeer
vele heuristieken. Dit zijn eigenlijk procedures die een feasible schedule trachten op te
bouwen door het stapsgewijs uitbreiden van gedeeltelijke schedules. Een gedeeltelijk
schedule is hierbij een schedule waarbij slechts aan een deel van de J in te plannen acti-
viteiten een sTj (starttijd) toegewezen is. We kunnen onderscheid maken tussen seriele
SGS en parallelle SGS. Kolisch & Hartmann (1999) geeft een rigoureuze algoritmische
beschrijving van beide, terwijl Hartmann & Kolisch (2000) het eerder niet-technisch
beschrijft als volgt:
• Seriele SGS: Deze procedure bestaat uit J stappen (1 voor elke activiteit j). In
elke stap wordt een activiteit gekozen uit de deelverzameling van de vrijgegeven
activiteiten en ingepland op een minimale sTj, zodanig dat aan de resource- en
tijdsbeperkingen voldaan is. Een vrijgegeven activiteit is hierbij een activiteit
waarvan alle directe predecessors reeds een starttijd toegewezen hebben gekre-
gen (cf. de precedence graphs zoals besproken bij het kwantitaief model voor
omstelproblemen). Het resultaat is een active schedule, dit wil zeggen dat geen
enkele activiteit vroeger kan gestart worden zonder een andere te verschuiven
naar een later tijdstip (Sprecher et al., 1995). Volgens Kolisch (1996b) geldt voor
problemen met een regular perfomance measure (Sprecher et al., 1995), zoals het
minimaliseren van de makespan er een is, dat steeds een optimale oplossing in de
verzameling van de active schedules bevat zit.
Een variant op de seriele SGS is ’list scheduling’, waarbij de activiteiten eerst
in een geordende lijst gerangschikt worden, bijvoorbeeld λ = [j1, . . . , jJ ]. Hierbij
moet elke activiteit alle voorgangers in de ’precedence graph’ ook als voorgangers
hebben in de geordende lijst λ. Vervolgens worden de activiteiten een voor een
ingepland, de lijst aflopend van begin naar einde. Ook hier geldt dat er altijd
een lijst λ∗ bestaat die een optimaal schedule zal genereren m.b.t. een ’regular
performance measure’.
• Parallelle SGS: De parallelle procedure gaat uit van de tijd, eerder dan van de
lijst met activiteiten. Met elke iteratie g stemt een tijdsslot tg overeen en een set
’vrijgegeven activiteiten’. Hier is een activiteit j vrijgegeven als ze kan ingepland
worden met als start-tijdsslot sTj = tg zonder de resource- en de tijdsbeperkingen
te schenden. Een voor een worden vrijgegeven activiteiten uitgekozen en gesche-
duled op tg. Na elke toewijzing moet hierbij natuurlijk de verzameling vrijgegeven
activiteiten bijgewerkt worden. Wanneer geen vrijgegeven activiteiten overblijven
in iteratie g, wordt naar de volgende iteratie gestapt. tg+1 is hierbij groter dan tg,
3.2 Classificatie van heuristieken uit de literatuur 32
en stemt overeen met het eerstvolgende tijdsslot waarin een van de activiteiten
die in uitvoering zijn op tg voltooid is. tg+1 is dus het tijdsslot waarin, voor het
eerst na tg, weer een deel van de hernieuwbare resources worden vrijgegeven. De
set vrijgegeven activiteiten wordt opnieuw bepaald,. . .
De parallelle SGS genereert wat in Sprecher et al. (1995) non-delay schedules
genoemd worden. Dit zijn schedules waarbij geen enkele activiteit naar een vroe-
ger tijdsslot kan verschoven worden zonder een andere naar een later tijdstip
te verschuiven, en dit zelfs als activity preemption is toegelaten. Bij toegelaten
activity preemption kunnen activiteiten willekeurig onderbroken worden, om la-
ter hervat te worden. De verzameling van non-delay schedules is bijgevolg een
deelverzameling van de active schedules-verzameling. Een groot nadeel is dat
het vaak voorkomt dat er geen optimaal schedule m.b.t. een regular performance
measure in de deelverzameling van non-delay schedules bevat zit. Dit wil zeggen
dat de parallelle SGS-procedures soms optimale oplossingen a priori niet kunnen
bereiken.
3.2.2 X-pass heuristieken
Tot deze klasse behoort het grootste deel van de heuristieken in de literatuur (bijna
alle heuristieken van de minder recente literatuur). Deze heuristieken zijn gebaseerd
op prioriteitsregels (priority rules). Als X = 1 wordt slechts 1 schedule gegenereerd en
spreken we van een single pass method. Voor X > 1 worden er X schedules gegenereerd
(multi-pass method).
Bij elke schedule-opbouw start een X-pass methode van nul zonder enige overgedragen
informatie uit het verleden (reeds gegenereerde schedules). In elke deelstap van de
schedule-opbouw wordt de volgende in te plannen activiteit geselecteerd op basis van
een prioriteitsregel. Een dergelijke regel wijst aan elke activiteit j een scalaire waarde
v(j) toe. De eerstvolgende in te plannen activiteit kan dan zowel die met de laagste als
de hoogste v(j)-waarde zijn, al naargelang de geformuleerde beslissingsregels. Zeer be-
kende prioriteitsregels zijn LFT (Latest Finishing Time) en WCS (Worst Case Slack).
Uitgebreide overzichten van prioriteitsregels zijn o.a. te vinden in Kolisch & Hartmann
(1999) en Kolisch (1996a).
Single-pass methodes gebruiken eenmaal een van de SGS-procedures in combinatie
met een enkele prioriteitsregel om 1 schedule op te bouwen. Veel meer flexibiliteit
is haalbaar bij multi-pass methodes. Hartmann & Kolisch (2000) onderscheiden drie
combinatiemogelijkheden tussen SGS en prioriteitsregels voor multi-pass methodes:
3.2 Classificatie van heuristieken uit de literatuur 33
• Multi-prioriteitsregel methodes gebruiken de SGS-procedure meerdere ke-
ren. Elke keer wordt een andere prioriteitsregel toegepast. De regels worden
hierbij vaak gebruikt in volgorde van dalende toepasbaarheid. Ook kan een prio-
riiteitsgetal bekomen worden door een convexe combinatie van I prioriteitsregels:
v(j) =∑I
i=1wivi(j), waarin alle wi ≥ 0 en∑I
i=1(wi) = 1. Kolisch & Hartmann
(1999) geven een overzicht van concrete voorstellen in de RCPSP-literatuur.
• Forward-backward methodes gebruiken een SGS om schedules iteratief op te
bouwen, wisselend tussen voorwaartse en achterwaartse scheduling. Voorwaartse
scheduling stemt overeen met de hierboven beschreven SGS-procedures, terwijl
achterwaartse scheduling een van de SGS-procedures toepast op het geınverteerde
’precedence network’. De prioriteiten in een iteratie worden meestal bepaald op
basis van de sTj die toegewezen werden in het schedule van de vorige iteratie.
• Sampling methodes maken meestal slechts gebruik van een SGS en een priori-
teitsregel. Verschillende schedules worden echter bekomen door een stochastische
variatie toe te voegen aan de selectie van de prioriteitsregel. Er wordt geen sca-
laire prioriteit v(j) berekend maar een selectie-probabiliteit p(j) (voor elke taak
j). p(j) is dan de kans dat bij de eerstvolgende scheduling-beslissing taak j wordt
uitgekozen om in te plannen. Drie invalshoeken zijn mogelijk:
– Random sampling: Elke activiteit die op basis van de ’precedence graph’ in
aanmerking komt voor inplanning krijgt eenzelfde probabiliteit toegewezen.
p(j) =1
| Dg | ∀j ∈ Dg
Hierbij is Dg de ’eligible set ’ in iteratie g, waarin de g-de activiteit wordt
toegewezen, of dus de set van vrijgegeven activiteiten die kunnen toegewezen
worden (alle voorgangers in ’precedence graph’ toegewezen).
– Biased random sampling zet de door de prioriteitsregels bekomen waarden
om naar genormaliseerde selectieprobabiliteiten. Indien het de bedoeling is
dat de activiteiten met de hoogste prioriteitswaarde v(j) eerst geselecteerd
worden, gebeurt dit volgens onderstaande formule. Indien de laagste waarde
eerst moet geselecteerd worden, kan het complement van onderstaande p(j)
gebruikt worden, dus 1− p(j).
p(j) =v(j)∑i∈Dg
v(i)∀j ∈ Dg
– Regret-based biased random sampling maakt indirect gebruik van de waarden
v(j) via ’regret ’-waarden. Wanneer opnieuw de hoogste prioriteiten eerst
3.2 Classificatie van heuristieken uit de literatuur 34
moeten ingepland worden, dan is r(j), de regretwaarde van een activiteit,
gelijk aan het verschil tussen de prioriteit van die activiteit en de minimale
prioriteit over alle activiteiten in de vrijgegeven verzameling (eligible set):
r(j) = v(j)−mini∈Dg
v(i) ∀j ∈ DgIndien eerder de laagste v(j) eerst moeten geselecteerd worden kan r(j) bere-
kend worden als de maximale waarde van v(i) over de vrijgegeven activitei-
ten min de waarde v(j). Vervolgens worden de regret-waarden nog aangepast
tot r′(j) = (r(j)+ ε)α, waarbij ε ervoor zorgt dat alle regretwaarden positief
worden, zodanig dat alle eruit berekende probabiliteiten p(j) ook positief
worden. De parameter α bepaalt dan weer de ’bias’ (vertekening). Uit de-
ze r′(j) worden tenslotte de p(j) voor alle vrijgegeven activiteiten berekend.
De hoogste regretwaarde moet hierbij natuurlijk de grootste p(j) toegewezen
krijgen. Een manier om dit te bereiken is bijvoorbeeld:
p(j) =r′(j)∑i∈Dg
r′(i)∀j ∈ Dg
3.2.3 Metaheuristieken
Simulated Annealing
Simulated annealing (SA) werd voor het eerst geıntroduceerd door Kirkpatrick et al.
(1983) en is gebaseerd op het fysische ’annealing ’-proces uit de metallurgie (spannings-
vrij gloeien). Hierbij wordt metaal warmgegloeid en traag tot afkoeling gebracht om
het zachter, minder bros en beter bewerkbaar te maken.
Bij SA start men van een initiele oplossing en een zogenaamde buur-oplossing (’neigh-
bour solution’) wordt gegenereerd door een perturbatie van de beginoplossing. Indien
de buur-oplossing beter is (met betrekking tot de te optimaliseren doelfunctie, in ons
geval de minimale makespan), dan wordt ze aanvaard, en wordt daarvan dan weer een
buuroplossing gegenereerd,. . . Indien de buur-oplossing echter een slechtere doelfunc-
tiewaarde levert, wordt ze slechts aanvaard met een probabiliteit die afhangt van zowel
de mate van verslechtering als van een zogenaamde ’temperatuurparameter’.
SA is duidelijk een uitbreiding van greedy schedulers (zogenaamde ’First Fit Strate-
gies ’), die een betere oplossing aannemen maar alle slechtere buuroplossingen verwer-
pen.
Tabu Search
Tabu Search (TS) werd het eerst geıntroduceerd in Glover (1989a) en Glover (1989b),
en is in feite een ’snelste daling/zwakste stijging’-methode (’steepest descent/mildest
3.2 Classificatie van heuristieken uit de literatuur 35
ascent ’). Dit wil zeggen, het bekijkt alle buuroplossingen van de huidige startoplossing
en kiest er de beste uit, dus diegene die in dit geval een maximale reductie geeft van de
makespan, of indien nergens een reductie te bekomen valt, diegene kiest met de minste
stijging van de makespan. Aangezien met zo’n methode ’cycling ’ (het steeds terugkeren
naar dezelfde oplossingen overeenstemmend met lokale minima) zeer waarschijnlijk is,
wordt een zogenaamde ’tabu list ’ bijgehouden als een soort geheugen van het algoritme.
De tabu list verbiedt dan die sprongen naar buur-oplossingen die het effect van recent
uitgevoerde sprongen zou kunnen opheffen en die dus zouden kunnen terugleiden naar
een recente oplossing. Deze tabu-status wordt echter soms genegeerd, bijvoorbeeld
wanneer de sprong in kwestie leidt naar een globaal minimum.
Deze strategie is duidelijk een uitbreiding van de klassieke ’steepest descent ’-methodes
(ook gradient-methodes genoemd of ’Best Fit Strategy ’), die steeds naar de beste buur-
oplossing springen tot geen enkele van de buuroplossingen de doelfunctiewaarde verbe-
tert.
Genetische algoritmes
’Genetic Algorithms’ (GA) zijn gebaseerd op het biologisch evolutieproces en werden
geıntroduceerd door Holland (1975). Anders dan TS en SA, bekijkt een genetisch
algoritme gelijktijdig een verzameling oplossingen (SA en TS beschouwen slechts een
buur-oplossing tegelijk). Na het opbouwen van een initiele ’populatie’ (verzameling be-
ginoplossingen), worden nieuwe oplossingen gegenereerd door het combineren van twee
oplossingen binnen de beginpopulatie, wat een ’cross-over ’-operatie genoemd wordt,
of door een operator toe te passen op een enkel lid van de beginpopulatie, wat een
’mutatie’ genoemd wordt. De operatoren bewaren hierbij feasibility van de gegenereer-
de oplossingen en zijn aldus zeer specifiek per probleem. Na het genereren van deze
nieuwe oplossingen, ’overleven’ de beste, wat overeenstamt met het genetische begrip
’survival of the fittest ’, de minder goede worden uit de populatie geschrapt. De ’beste’
oplossingen worden hierbij bepaald op basis van een criterium dat meestal gebaseerd
is op de te optimaliseren doelfunctie van de probleemstelling.
’Ant Systems’
Deze metaheuristiek is een redelijk recente techniek en werd geıntroduceerd in Dorigo
et al. (1996) en aangepast voor het RCPSP door Merkle et al. (2002). Bij deze laatste
correspondeert een ’mier’ (ant) met een toepassing van het seriele SGS. De volgende in
te plannen activiteit wordt hierbij bepaald door een gewogen criterium van enerzijds
de ’Latest Start Time’-prioriteitsregel en zogenaamde ’feromonen’ die het leereffect van
vorige ’ants’ voorstellen. Een feromoonwaarde τij geeft weer hoe veelbelovend het is
3.2 Classificatie van heuristieken uit de literatuur 36
om activiteit j als i-de in te plannen in de SGS.
Metaheuristieken en schedule-voorstellingen
Onder een schedule wordt meestal verstaan: de toegewezen starttijden sTj (of eindtij-
den) voor alle activiteiten. Metaheuristieken gebruiken echter meestal andere voorstel-
lingen (’representations ’) waarop ze hun operaties uitvoeren, in plaats van de schedules
zelf. Van de voorstelling van het schedule kan dan op ondubbelzinnige wijze een eigen-
lijk schedule gegenereerd worden door een duidelijk omschreven decodeerprocedure.
Unaire operators werken dan in op een schedule-voorstelling om een andere schedule-
voorstelling te genereren. Op die manier worden in SA en TS de buuroplossingen
gegenereerd en worden de ’mutaties’ van een GA uitgevoerd om een nieuw lid te krij-
gen van de populatie, gebaseerd op een reeds aanwezig lid. Binaire operators werken
daarentegen op twee schedule-voorstellingen en genereren een nieuw. De cross-over
operatie bij GA is hier een voorbeeld van.
Kolisch & Hartmann (1999) onderscheiden vijf soorten schedule-voorstellingen in de
literatuur. We overlopen deze hier kort zonder de specifieke overzichten van unaire en
binaire operatoren uit de literatuur te vermelden. Het is immers vooral de bedoeling de
specifieke invalshoeken kort te overlopen, om het later voorgestelde algoritme te kunnen
situeren. Voor een uitgebreider overzicht wordt verwezen naar Kolisch & Hartmann
(1999).
1. Activiteitenlijst-voorstelling: De ’list schedule’-procedure zoals besproken bij het
seriele SGS (cfr. 3.2.1) is hiervan een voorbeeld. Hierbij is de SGS de decodeer-
procedure en wordt een schedule voorgesteld door een geordende lijst λ van de
activiteiten:
λ = [j1, . . . , jJ ]
Zoals in de SGS-sectie reeds gesteld is moet in deze geordende lijst elke activiteit ji
een hogere index i hebben dan al zijn voorgangers in de ’precedence graph’, m.a.w.
de lijst moet ’precedence feasible’ zijn. De seriele SGS kan hier rechtstreeks
op toegepast worden. Om de parallelle procedure te kunnen toepassen moeten
aanpassingen gebeuren.
De startlijst kan bekomen worden door het eenmaal toepassen van de SGS, en
daarbij bij elke schedule-beslissing een activiteit random te selecteren uit de lijst
met vrijgegeven activiteiten (’eligible set’). Om de kwaliteit van de beginoplossing
te verbeteren kan eventueel de keuze uit de eligible set ook gemaakt worden op
basis van een klassieke prioriteitsregel. De activiteiten worden dan in de lijst
3.2 Classificatie van heuristieken uit de literatuur 37
opgenomen in de volgorde waarin ze door de SGS-procedure ingepland worden.
Dit levert dan uiteraard een lijst op die precedence feasible is.
2. De ’random key’-voorstelling wijst aan elke activiteit j een scalaire waarde rj
(’random key’) toe. Dit kunnen prioriteitswaarden zijn, maar Kolisch & Hart-
mann (1999) geven ook enkele andere invalshoeken.
ρ = (r1, . . . , rJ)
Om de initiele scalaire waarden te bekomen kunnen de ’random keys’ willekeurig
worden toegewezen of ze kunnen berekend worden met een klassieke prioriteits-
regel. Decodering kan gebeuren met beide SGS, waarbij bij de g-de scheduling-
beslissing de taak j uit de eligible set gekozen wordt, die de grootste random key
heeft: rj = max{ri | i ∈ Dg}. De random keys bepalen dus de prioriteit van de
activiteiten.
3. De prioriteitsregel-voorstelling is gebaseerd op een geordende lijst van prioriteits-
regels πj:
π = [π1, π2, . . . , πJ ]
Als decodeerprocedure kunnen beide SGS worden gebruikt om de i-de activiteit
in te plannen, waarbij deze geselecteerd wordt uit de vrijgegeven activiteiten door
prioriteitsregel πi.
4. ’Shift vector representation’ : Deze werd de eerste maal voorgesteld door Sampson
& Weiss (1993) voor het RCPSP. Een schedule wordt voorgesteld door een ’shift
vector’ waarin σj een niet-negatief geheel getal is:
σ = (σ1, σ2, . . . , σ3)
Als decodeerprocedure wordt hier geen SGS gebruikt maar een uitbreiding van
de klassieke voorwaartse recursie volgens Elmaghraby (1977). Hierbij wordt sTj
berekend als de maximale eindtijd sTj + Tj van de voorgangers van taak j in
de ’precedence graph’ plus de shift σj van activiteit j. Deze decodeerprocedure
houdt dus enkel rekening met de tijdscontraints. Een gegenereerd schedule kan
dus infeasible zijn qua resources. De doelfunctie kan aldus uitgebreid worden met
extensies die het schenden van de resources-beperkingen bestraffen.
5. De ’Schedule scheme’-voorstelling werd aangebracht door Brucker et al. (1998)
bij een branch-and-bound algoritme voor het RCPSP. De voorstelling die hier
gebruikt wordt, bestaat uit vier disjuncte verzamelingen die activiteiten-koppels
bevat (geen enkel koppel kan dus in meer dan een verzameling voorkomen):
(C,D,N, F )
3.2 Classificatie van heuristieken uit de literatuur 38
Hierbij komt (i, j) ∈ C overeen met de precedence constraints in het kwantitatief
model van Van Goubergen (2001), komt (i, j) ∈ D overeen met een paarsgewijze
disjunctie tussen i en j (geen overlap). (i, j) ∈ N impliceert dan weer dat bei-
de activiteiten minstens in 1 tijdsslot moeten overlappen. Dit is niet hetzelfde
als de concurrente koppels in het kwantitatief model, want daar werden dezelfde
starttijden geeist. Tenslotte wil (i, j) ∈ N zeggen dat er geen restricties zijn
tussen taak i en taak j. De voorstelling (C,D,N, F ) stelt alle schedules voor die
voldoen aan de constraints in C,D en F . In T. Baar (1997) wordt als decodeer-
procedure een heuristiek voorgesteld die schedules genereert die voldoen aan alle
constraints van C en D en aan ’veel’ van de N -constraints. In hetzelfde werk
worden operators voorgesteld om naar buuroplossingen te springen.
3.2.4 Andere heuristieken
Kolisch & Hartmann (1999) geven nog enkele andere heuristische procedures die niet
ondergebracht kunnen worden onder een van de voorgaande aanpakken:
• ’Truncated branch-and-bound’ methodes : Optimale branch-and-bound methodes
kunnen eveneens aangepast worden tot heuristieken, door niet de volledige boom
te doorlopen maar branch-beslissingen te baseren op bijvoorbeeld prioriteitswaar-
den (enkel branchen naar de activiteiten met de hoogtste prioriteiten). Op die
manier wordt slechts een gedeeltelijke oplossingsboom opgesteld, die echter goe-
de oplossingen kan opleveren indien de branchbeslissingen op een goede manier
genomen worden.
Er kan ook beslist worden om de branch-and-bound procedure na een bepaalde
tijdslimiet af te breken. Ook hier zorgen efficiente branching-regels ervoor dat
vroeg goede oplossingen bekomen worden bij het doorzoeken van de oplossings-
boom.
• ’Disjunctive arc’-methodes steunen op het toevoegen van extra koppels (’disjunc-
tive arcs’) in de precedence graph om zo de ’minimal forbidden sets’ te elimineren.
Een minimal forbidden set is hier een verzameling onafhankelijke activiteiten die
nooit kunnen overlappen door de resource-beperkingen. ’Minimal’ wil zeggen
dat deze verzamelingen zo samengesteld zijn dat indien er 1 activiteit geschrapt
zou worden uit de verzameling, de resterende activiteiten wel kunnen overlappen
zonder de resource-capaciteiten te overschrijden. Een minimal forbidden set is
dus elimineerbaar door een precedence-relatie toe te voegen tussen twee willekeu-
rige taken van de verzameling. Voor een overzicht van de studies die dit concept
hanteren wordt verwezen naar Kolisch & Hartmann (1999).
3.3 Andere literatuuroverzichten RCPSP 39
• Andere benaderingen: Kolisch & Hartmann (1999) bespreken nog twee andere
benaderingen, namelijk de heuristiek gebaseerd op ’integer programming’ van
Oguz & Bala (1994), die gebaseerd is op het model van Pritsker et al. (2000) dat
reeds hoger vernoemd werd, en de aanpak van Mausser & Lawrence (1998) die
gebruik maakt van ’block structures’ om de makespoan te minimaliseren. Ook in
Hartmann & Kolisch (2000) en Kolisch & Hartmann (2006) worden nog enkele
heuristieken overlopen die niet binnen de klassieke indeling vallen.
3.3 Andere literatuuroverzichten RCPSP
In de vorige paragraaf werd een overzicht van de RCPSP-heuristieken gegeven volgens
de indeling van Kolisch en Hartmann. Hierbij zijn directe verwijzingen naar papers die
de methodes toepassen voor het overgrote deel weggelaten, omdat de literatuur dien-
aangaande dermate uitgebreid is dat het vrijwel onmogelijk is deze bijeen te brengen.
Nog talrijke andere surveys zijn beschikbaar. Daar wordt dan ook naar verwezen om
specifieke toepassingen te vinden van de verschillende methodes. Het zou trouwens
bladvulling zijn om al deze methodes te bepreken, daar in de volgende paragrafen zal
duidelijk worden dat er een bijzonder geval is van RCPSP dat veel dichter aanleunt
bij de probleemeigenschappen van het omstelprobleem. De bedoeling van de vorige
paragraaf was dan ook vooral om een overzicht te geven van verschillende strategieen
die mogelijk zijn bij het ontwerpen van een heuristiek.
Voor de lezer die meer infomatie wil over de algemene probleemstelling van het RCPSP
wordt hier een kort (niet exhaustief) overzicht gegeven van surveys die heuristieken en
optimale methodes samenbrengen en onderling vergelijken. Deze onderlinge vergelij-
king gebeurt door de prestaties op benchmark-problemen te testen. Het is duidelijk dat
de resultaten in dit werk hier geen direct nut hebben, aangezien de probleemstructuur
van het omstelprobleem ingrijpend anders is dan het gewone RCPSP.
• De literatuuroverzichten van Hartmann & Kolisch (2000), Hartmann & Kolisch
(2000), Hartmann & Kolisch (2000) geven een duidelijke indeling van heuristieken
en voeren vergelijkende tests uit op basis van hun zelfingevoerde gestandaardi-
seerde experimentele testproblemen. Optimale methodes worden niet behandeld.
Ook in Kolisch (1996a) wordt een overzicht gegeven van literatuur, zowel opti-
male benaderingen als heuristieken, met natuurlijk meer focus op methodes die
priority rules gebruiken, omdat dit het onderwerp van de studie is.
• In Ozdamar & Ulusoy (1995) wordt een indeling gemaakt van de heuristieken
en optimale methodes, vooral op basis van de probleemstelling (doelfuncties en
beperkingen). Zij maken dan ook een iets bredere studie die niet enkel RCPSP
3.4 Het RCPSP/max-probleem 40
met minimaliseren van de makespan bespreekt, maar verschillende varianten.
Ook hier een computationele studie op basis van benchmark-problemen.
• In Elmaghraby (1994) wordt een zeer bevattelijke uitleg gegeven over RCPSP
en hun voorstelling door middel van Activity-on-Node netwerken (AoN). Dit is
wat we tot nu toe beschreven hebben als de ’precedence graph’ van het project.
Sectie 9 ervan geeft een overzicht van moeilijkheden bij RCPSP en een beperkt
literatuuroverzicht.
• Icemeli et al. (1993) geeft een algemene survey van project scheduling, waaronder
ook scheduling onder resource-constraints.
• Minder recente overzichten zijn Davis (1978), Willis (1985), Herroelen (1972).
• Herroelen et al. (1998) is recenter en focust op optimale oplossingswijzen. Door
Herroelen, Demeulemeester en De Reyck is trouwens zeer veel werk gepubliceerd
op het gebied van resource-constrained project scheduling, vooral optimale me-
thodes.
• Brucker et al. (1999) geeft een formeel classificatieschema voor het RCPSP en de
bijzondere gevallen daarvan. De door hun ingevoerde notatie wordt echter om-
streden door andere auteurs. Er wordt ook een overzicht gegeven van heuristische
en optimale methodes.
3.4 Het RCPSP/max-probleem
In sectie 3.1 werd het klassieke RCPSP besproken, waarnaar Van Goubergen (2001)
verwijst als een mogelijk aanpasbaar probleem om de eerste stap van het kwantitatief
optimalisatiemodel (minimaliseren van de downtime), heuristisch op te lossen. Het
is echter duidelijk dat de verschillende tijdsbeperkingen van het omstelprobleem niet
rechtlijnig in te passen zijn in deze probleemstelling.
Er is echter een bijzonder geval waarover publicaties bestaan: het ’Resource Cons-
trained Project Scheduling Problem with Generalized Precedence Constraints’, in de
nomenclatuur meestal beschreven als ’RCPSP/max’. In het originele RCPSP zijn
enkel precedence constraints toegelaten. Dit stemt overeen met een ’time-lag’ (tijds-
vertraging) van minstens Tj (duur van taak j). Soms wordt het RCPSP trouwens niet
gedefinieerd als puur bestaande uit precedence constraints, maar uit minimale time-
lags met een arbitraire waarde (algemener geval). In RCPSP/max daarentegen worden
zowel minimale als maximale time-lags toegelaten tussen starttijden van activiteiten.
3.4 Het RCPSP/max-probleem 41
Merk op dat time-lags tussen eindtijden onderling of tussen een start- en een eindtijd
te herleiden zijn tot start-start time-lags door het incrementeren of het decrementeren
met de constant veronderstelde waarde Tj, de duur van de activiteit.
Gebaseerd op Cesta et al. (2002) en Smith (2004) kan het RCPSP/max als volgt ge-
formuleerd worden:
Definitie 3.2 (RCPSP/max) Een RCPSP/max bestaat uit een set J = {1, . . . , J}van uit te voeren taken/activiteiten en een set hernieuwbare resources K = {1, . . . , K}.Elke activiteit j heeft een starttijd sTj en een constante en deterministische lengte Tj.
Elke resource (productiemiddel) k heeft een maximum (en constante) capaciteit Rk en
activiteit j verbruikt rj,k eenheden van resource k gedurende elk tijdsinterval van de
uitvoering. De beperking op de resources in tijdsslot t kan dus als volgt geformaliseerd
worden: ∑{j∈J |sTj≤t<sTj+Tj}
rj,k ≤ Rk ∀t = 1, . . . , Tmax;∀k ∈ K
Twee soorten binaire beperkingen kunnen optreden tussen verschillende activiteiten m
en n:
• lagminm,n legt een minimale tijdsvertraging op tussen sTm en sTn:
sTn − sTm ≥ lagminm,n
• lagmaxm,n legt een maximale tijdsvertraging op tussen sTm en sTn:
sTn − sTm ≤ lagmaxm,n
Het doel van het RCPSP/max is het vinden van een schedule (vastleggen van alle sTj)
zodanig dat alle tijdsbeperkingen en resource-capaciteiten gerespecteerd worden, en het
daarbij bereiken van een minimale ’makespan’:
MK = maxj∈J
(sTj + Tj − 1)
Het is duidelijk dat deze strengere probleemformulering al meer ruimte geeft voor
de implementering van de beperkingen van het omstelprobleem. Voor de specifieke
aanpassing van het omstelprobleem aan de RCPSP/max-formulering, zie sectie 4.1 in
het volgende hoofdstuk.
Ook hier wordt duidelijk dat de oplossing van ons probleem NP-hard is; Bartusch
et al. (1988) besluiten immers dat zelfs het vinden van een ’feasible schedule’ voor
het RCPSP/max reeds NP-hard is. Het vinden van een schedule met een minimale
makespan is aldus een zeer complex probleem, in elk geval NP-hard.
3.5 Literatuur RCPSP/max en keuze van een heuristiek 42
3.5 Literatuur RCPSP/max en keuze van een heu-
ristiek
Zoals reeds hoger vermeld zijn de voorgestelde oplossingen voor het RCPSP/max veel
minder talrijk dan die voor het algemene RCPSP. In wat volgt wordt een kort overzicht
gegeven.
• Herroelen et al. (1998, sectie 4) beschrijft het zogenaamde ’RCPSP-GPR’ met
als precedence relations de mogelijkheden van start-start (SS), start-finish (SF ),
finish-start (FS) en finish-finish (FF )-relaties tussen activiteiten i, j ∈ J , die zo-
als eerder vernoemd eigenlijk volledig te herleiden zijn tot constraints tussen de
starttijden van i en j, aangezien alle activiteiten verondersteld worden een con-
stante lengte te hebben. Verder kunnen deze vier constraints voorkomen met zo-
wel minimale time-lags als maximale time-lags. Hun definitie van RCPSP-GPR is
dus consistent met onze hoger gegeven definitie van RCPSP/max. Ook hier wordt
bevestigd dat het RCPSP streng NP-hard is en het testen of een probleemstel-
ling een ’feasible’ oplossing bezit is zelfs NP-complete probleem. Dit werk geeft
evenwel geen bespreking van heuristieken maar van exacte methoden. Op dat
moment waren klaarblijkelijk maar twee exacte oplossingsmethodes voorgesteld
in de literatuur, namelijk door de reeds eerder vernoemde Bartusch et al. (1988)
en door de auteurs zelf in De Reyck & Herroelen (1997). Aangezien we echter
met een NP-hard probleem te maken hebben, zullen dergelijke optimale metho-
des zeer gevoelig zijn voor probleemgrootte en dus lijken ze a priori ongeschikt
voor wat wij proberen te bereiken. In het kwantitatief model van Van Goubergen
(2001) werd immers net een optimale branch-and-boundprocedure toegepast en
is gebleken dat de rekentijd voor grote problemen te hoog werd. Een heuristische
procedure lijkt dus meer aangewezen.
• In De Reyck & Herroelen (1999) wordt het nog specifiekere ’MRCPSP-GPR’
probleem behandeld, waarbij multi-mode activiteiten optreden, dit wil zeggen
dat er verschillende uitvoeringswijzen mogelijk zijn voor eenzelfde activiteit. Het
kan bijvoorbeeld zijn dat een activiteit een kortere duur heeft indien er meer
personen voor ingezet worden. Dit is duidelijk niet van toepassing voor ons
probleem. Er wordt echter ook een kort overzicht gegeven van literatuur i.v.m.
RCPSP/max zelf. Buiten enkele nieuwe optimale methodes sinds Herroelen et al.
(1998) (zie vorig punt), worden nu ook enkele heuristieken aangehaald: Zhan
(1994), Neumann & Zhan (1995), Brinkmann & Neumann (1996), Schwindt &
Neumann (1996), Franck & Neumann (1996), Schwindt (1998).
Ook het recente boek door Neumann et al. (2003) geeft een uitgebreide studie
3.5 Literatuur RCPSP/max en keuze van een heuristiek 43
van RCPSP/max. (Neumann et al., 2002) sluit hierbij aan. De probleemstel-
ling wordt duidelijk uiteengezet aan de hand van het AoN-diagram (’precedence
graph’) en de structuur van de oplossingsruimte van dergelijke problemen wordt
besproken. In sectie 6 van het document worden heuristische oplossingsmethoden
voor het RCPSP/max besproken aan de hand van de opbouw van de heuristiek:
– ’Truncated branch-and-bound’ methodes, waarbij de zoektocht naar een op-
timaal schedule ’voortijdig’ wordt gestopt. Er wordt een branch-and-bound
(optimale) procedure omgevormd naar een heuristiek, waarbij een relatieve
fout van niet groter dan ε > 0 kan vooropgesteld worden.
Voor grote problemen (> 100 activiteiten) is dit echter meestal te rekenin-
tensief en wordt een ’filtered beam’ zoekprocedure voorgesteld, waarbij in
elk branch-punt van de beslissingsboom maar een maximaal aantal takken
mogen vertrekken (overeenkomstig de vastgelegde ’beam width’).
– Verder wordt verwezen naar heuristieken op basis van prioriteitsregels. De-
ze genereren meestal veel sneller ’feasible schedules’ dan branch-and-bound
methodes. Opnieuw wordt verwezen naar Neumann & Zhan (1995), Brink-
mann & Neumann (1996), Neumann et al. (1999c), Neumann et al. (1999a),
Neumann et al. (1999b), Franck et al. (2001), Selle & Zimmermann (2000).
– Prioriteitsregel-methodes genereren slechts 1 feasible schedule. Als de be-
komen makespan te ver afwijkt van een berekende ondergrens, kunnen nog
’schedule improvement methods’ toegepast worden. Deze zijn in feite local-
search metaheuristieken (betere buuroplossingen worden gezocht). Er wordt
verwezen naar de tabu-search methodes beschreven door Neumann et al.
(1999b) en Franck et al. (2001).
– Neumann et al. (1999c) en Neumann et al. (1999b) geven enkele heuristie-
ken op basis van priority rules. Een gelijkaardige heuristiek is te vinden
in het werk van Smith (2004). Het gaat hier over een Ph.D.-scriptie die
zeer uitgebreid procedurale beschrijvingen geeft van een algoritme dat ’fea-
sible schedules’ genereert op basis van priority rules. Hierbij worden enkele
aanpassingen gedaan die het algoritme van een pure multi-pass heuristiek
omzetten naar een niet-standaard toepassing van local search. De opbouw
van de redenering vertoont vele gelijkenissen met de hoger vernoemde heu-
ristieken door Neumann en Zimmermann.
Aangezien de heuristiek voor RCPSP/max door Smith (2004) uitgebreider beschreven
is dan de andere twee in Neumann et al. (1999c) en Neumann et al. (1999b), wordt
geopteerd voor een implementatie van deze eerste in de object-georienteerde program-
meertaal Java. Een leidraad hierbij is het werk van Shixin & Mengguang (2000) waarin
3.5 Literatuur RCPSP/max en keuze van een heuristiek 44
een generiek raamwerk wordt voorgesteld voor het implementeren van heuristieken en
meta-heuristieken voor het RCPSP. De gebruiksaanwijzing van de geımplementeerde
code wordt gegeven in hoofdstuk 5, de methodologie van het algoritme in hoofdstuk
4.
WERKING VAN HET WINDOW-BASED ALGORITME 45
Hoofdstuk 4
Werking van het window-based
algoritme
We kiezen voor een implementatie van een time-window algoritme gebaseerd op het
algoritme voor RCPSP/max door Smith (2004). Het eerste wat dus moet gedaan
worden is de beperkingen en voorwaarden van het omstelprobleem aanpassen aan de
RCPSP/max-definitie (cf. 3.2).
4.1 Aanpassing omstelprobleem aan RCPSP/max
4.1.1 Tijdsbeperkingen: time-lags
Het RCPSP/max werkt met twee soorten tijdsbeperkingen tussen activiteiten i en j,
namelijk minimale en maximale tijdsvertragingen (time-lags). Drie van de vier soorten
tijdsbeperkingen uit het omstelprobleem (cf. 2.3) kunnen geschreven worden in functie
van deze constraints. De naamgeving en symbolen zijn dezelfde als deze besproken in
secties 2.1 en 3.2.
• Precedence-koppels (verzameling PD) kunnen we voorstellen door een enkele
minimale time-lag met als lengte de duur van de eerst uit te voeren activiteit (cf.
beperking 2.3):
∀(i, j) ∈ PD : sTj − sTi ≥ Ti ⇐⇒ lagmini,j = Ti (4.1)
• Activiteiten i, j die vlak na elkaar moeten uitgevoerd worden (verzameling CS)
moeten exact Ti tijdsslots verschil hebben tussen starttijden sTj en sTi. We
kunnen dit opdringen door zowel een minimale als een maximale time-lag in te
voeren:
4.1 Aanpassing omstelprobleem aan RCPSP/max 46
∀(i, j) ∈ CS :
lagmini,j = Ti
lagmaxi,j = Ti(4.2)
• Ook voor activiteiten die gelijktijdig moeten beginnen (koppel (i, j) ∈ CC kunnen
we dit uitdrukken d.m.v. zowel een minimale als een maximale time-lag, met
waarde 0.
∀(i, j) ∈ CC :
lagmini,j = 0
lagmaxi,j = 0(4.3)
Disjunctieve relaties kunnen niet gemodelleerd worden aan de hand van time-lags, om-
dat het invoeren van een time-lag tussen activiteit i en j impliceert dat j sowieso na
i moet uitgevoerd worden, ongeacht of we een lagmin of een lagmax invoeren. Een
disjunctie daarentegen is niet-directioneel. De activiteiten mogen gewoon niet overlap-
pen, maar het zou een verkleining van de oplossingsruimte impliceren om een van de
twee activiteiten a priori als de eerst uitgevoerde vast te leggen. Dit zou ertoe kunnen
leiden dat optimale oplossingen a priori uitgesloten worden en zelfs dat het probleem
infeasible wordt.
Wij nemen de paarsgewijze en de machinedisjuncties (cf. 2.4 en 2.5, respectievelijk) dan
ook niet op bij de tijdsbeperkingen, die in de probleemformulering van RCPSP/max
volledig door middel van time-lags worden uitgedrukt. In de volgende sectie wordt ech-
ter aangetoond dat deze disjuncties kunnen worden ingevoerd als resource-beperkingen.
4.1.2 Resource-beperkingen
In het omstelprobleem zoals het gedefinieerd is in het kwantitatief model van Van Gou-
bergen (2001) is er maar sprake van 1 echte hernieuwbare en gelimiteerde resource, na-
melijk het aantal beschikbare werknemers Lmax. In het model werd deze voorwaarde
uitgedrukt door vergelijking 2.2a of 2.2b. We kunnen de notatie Lj overnemen als beno-
digde werknemers voor uitvoering van taak j gedurende elk tijdsslot van de uitvoering.
Stel dat de werknemers overeenstemmen met resource k, kunnen we, overeenkomstig
de definitie van RCPSP/max, stellen:
rj,k = Lj ∀j ∈ J (4.4a)
Lmax is dan de capaciteit van de ingevoerde werknemers-resource k:
Rk = Lmax (4.4b)
4.2 Basisprincipes van de heuristiek 47
Verder zijn de disjunctie-relaties natuurlijk nog niet ingevoerd bij de time-lag beper-
kingen om redenen die reeds besproken werden. Voor elke disjunctieve set activiteiten
(j1, j2, . . . , jn) kunnen we dan een fictieve gedeelde resource k invoeren met een ca-
paciteit Rk = 1. Alle onderling disjuncte taken van de set gebruiken dan 1 eenheid
van resource k in elk uitvoerings-tijdsslot. Op die manier kan inderdaad maximaal een
van deze taken gelijktijdig in uitvoering zijn en is aan de disjunctie voldaan. Voor de
ingevoerde fictieve resource k kunnen we dus stellen:
rji,k = 1 ∀i = 1, . . . , n (4.5a)
Rk = 1 (4.5b)
Merk op dat een disjunctie tussen alle taken van een bepaalde machine, dus alle j ∈J(m), hier gewoon een bijzonder geval van is, waarbij de set (j1, j2, . . . , jn) simpelweg
alle taken ∈ J(m) bevat.
4.2 Basisprincipes van de heuristiek
4.2.1 Constraint-graph en herleiden van lagmax
We kunnen de tijdsbeperkingen van het RCPSP, die gedefinieerd worden met behulp
van time-lags, voorstellen in een graaf die lijkt op de klassieke ’precedence graph’
(Activity-on-Node netwerk) die Van Goubergen (2001) gebruikt om de PD-relaties
voor te stellen. Het verschil is echter dat nu bij elke tak de waarde van de lag vermeld
wordt als ’gewicht’; bij de PD-relaties (i, j) bepaalt Ti immers de waarde van de pijl,
maar bij onze veralgemeende graaf kan de waarde elk positief geheel getal zijn.
Een zeer belangrijke opmerking hierbij is dat alle ingevoerde maximum-lags volledig
equivalent zijn met een minimum-lag in tegenovergestelde richting (Smith (2004)). We
kunnen dus steeds werken met minimum time-lags in ons algoritme. Het verband
tussen een lagmax en de equivalente lagmin is als volgt:
sTj − sTi ≤ z z ∈ Z+ (dit is dus een lagmaxi,j ) (4.6a)
msTi − sTj ≥ −z z ∈ Z+ (dit is dus een lagminj,i ) (4.6b)
We kunnen maximum-lagsdus vervangen door minimum-lags in tegengestelde richting
met een tegengestelde waarde. Vergelijkingen 4.2 en 4.3 herschrijven we als:
∀(i, j) ∈ CS :
lagmini,j = Ti
lagminj,i = −Ti(4.7)
4.2 Basisprincipes van de heuristiek 48
∀(i, j) ∈ CC :
lagmini,j = 0
lagminj,i = 0(4.8)
In figuur 4.1 wordt een voorbeeld gegeven van een constraint graph met minimum-
lags en activiteitsnummers van 1 tot 4. Merk op dat, anders dan bij een precedence
graph, de pijl (1, 4) niet zomaar kan geschrapt worden omdat er een pijl (1, 2) en (2, 4)
aanwezig zijn. Deze pijl kan pas geschrapt worden indien het gewicht (de waarde van
de minimum-lag) kleiner dan of gelijk aan de som van de pijlen (1, 2) en (2, 4) zou zijn.
Merk op dat het echter niet de bedoeling is voor het toepassen van het algoritme
expliciet een dergelijke graph uit te schrijven en zelf te vereenvoudigen. De precedence-
relations kunnen gesimplifieerd aan de hand van een gewone ’precedence graph’, maar
in de implementatie van het algoritme (cf. volgende hoofdstuk), worden PD-, CC-
en CS-constraints apart ingegeven en de implementatie genereert de overeenkomstige
minimum-lags. De ’constraint graph’ is hier dus puur ter illustratie gegeven, om de
concepten te verduidelijken.
Figuur 4.1: Voorbeeld van een constraint graph met minimum-lags
4.2.2 Het bijhouden van time-windows
Time-windows
Om de complexiteit van het zoeken naar geschikte starttijden (bij elke schedule-beslissing)
te verkleinen, vertrekt de heuristiek van time-windows die bijghouden worden per ac-
tiviteit.
Definitie 4.1 (time-feasible schedule) Een schedule (alle toegewezen sTj,∀j ∈ J )
is time-feasible als door de toegewezen sTj voldaan is aan alle opgelegde time-lags.
4.2 Basisprincipes van de heuristiek 49
Definitie 4.2 (resource-feasible schedule) Een schedule is resource-feasible als de
nergens in de horizon t = 1, . . . , Tmax de resourcecapaciteiten Rk overschreden worden
(∀k ∈ K).
Definitie 4.3 (feasible schedule) Een schedule is feasible als het zowel resource- als
time-feasible is.
Gedurende het opbouwen van de schedules door het algoritme, worden twee ’windows’
bijgehouden door het algoritme voor elke taak j ∈ J :
1. De ’hard windows’, [hLj, hUj] (L staat voor ondergrens of ’Lower bound’, U
voor bovengrens op ’Upper bound’). Deze bepalen alle tijdstippen t (hLj ≤ t ≤hUj) waarvoor een time-feasible schedule bestaat met sTj = t. Met andere woor-
den, indien geen van de activiteiten reeds een starttijd toegewezen gekregen heeft,
kan de eerste te schedulen activiteit j op elke waarde binnen zijn hard-window
gestart worden. Er kan dan gegarandeerd worden dat alle andere activiteiten nog
kunnen ingepland worden zodanig dat de time-constraints voldaan zijn. Let wel:
de resource-beperkingen kunnen er nog steeds voor zorgen dat geen enkele sTj
binnen de hard windows een feasible schedule zal leveren. Bij de uitleg over de
windows hebben we het vooreerst enkel over de time-constraints. De activitei-
ten worden binnen het algoritme een voor een ingepland, maar de hard-windows
blijven onveranderd.
2. Dit ligt anders voor de ’soft-windows’, die overeenstemmen met een partieel
schedule. Naarmate activiteiten ingepland worden, wordt het aantal time-feasible
start-tijdsslots voor de nog in te plannen activiteiten kleiner. De ’soft windows’
[sLj, sUj] worden geınitialiseerd op de waarden van de hard-windows, maar wor-
den gradueel verkleind telkens wanneer een nieuwe activiteit ingepland wordt.
De soft windows voor activiteit j bevatten dan alle tijdsslots t waarvoor er een
time-feasible schedule bestaat met sTj = t (en alle reeds ingeplande activiteiten
blijven ingepland op dezelfde plaats).
Beide windows worden volledig opgebouwd aan de hand van de lengte van de horizon
(aantal tijdsslots), de releasetimes van de activiteiten en de time-lag beperkingen. Het
voorstel om twee soorten windows te gebruiken is een nieuwe aanpak, geıntroduceerd
door Smith (2004).
Initialisatie van de windows
Voor het sequentieel inplannen van de activiteiten moeten eenmalig de hard-windows
geınitialiseerd worden.
4.2 Basisprincipes van de heuristiek 50
1. Elke taak op zich kan pas beginnen vanaf het tijdsslot dat overeenstemt met de
vrijgeeftijd (Relt(m)). Er is ook een bovengrens die afhangt van de beschouwde
horizon Tmax: de taak kan ten laatste gestart worden op tijdstip Tmax − Tj + 1.
2. De verschillende hard-windows moeten dan verder beperkt worden met betrek-
king tot de time-lags. Als er tussen activiteiten i en j een lagmini,j opgelegd wordt,
zullen de hard-windows van i en j elkaar wederzijds beınvloeden op twee manie-
ren:
• De ondergrens van i (hLi) zal ervoor zorgen dat in geen enkel geval kan
gestart worden met activiteit j voor tijdsslot hLi + lagmini,j . Dit wordt de
nieuwe ondergrens voor j, indien groter dan de huidige hLj. De ondergrens
van elke activiteit kan dus mogelijk hogere ondergrenzen eisen voor alle
opvolger-activiteiten in de constraint graph.
• De bovengrens van j (hUj) kan de bovengrens van directe voorgangers in de
constraint graph verkleinen. Indien hUj − lagmini,j kleiner is dan de huidige
bovengrens hU(i) van activiteit i, wordt dit de nieuwe bovengrens.
Deze mechanismen kunnen verduidelijkt worden aan de hand van een eenvoudig voor-
beeld met twee activiteiten en een time-lag daartussen (zie figuur 4.2). Op basis van de
unaire beperkingen vinden we als hard-windows [2, 5] voor activiteit 1 en [1, 3] voor 2.
Door de aanwezigheid van de constraint lagmin1,2 = 1 zal echter de ondergrens van activi-
teit 2 naar 3 gedwongen worden en de bovengrens van activiteit 1 naar 2. We bekomen
dan de windows [2, 2] (1) en [3, 3] (2). Bijgevolg is er maar 1 mogelijke time-feasible
toewijzing bij horizon Tmax = 5.
De aanwezigheid van cycli in de constraint graph zorgt ervoor dat de windows van een
activiteit meerdere keren moeten worden aangepast gedurende de procedure van de
windows-initialisatie. We splitsen de procedure op in een voorwaarts deel en een ach-
terwaarts, die de minimumlags doorlopen respectievelijk in de richting van de directe
opvolgers en de directe voorgangers in de constraint graph. Bij de voorwaartse proce-
dure worden de hL (ondergrenzen) aangepast, bij de achterwaartse procedure worden
de hU (bovengrenzen) aangepast. Elke keer als het hard-window van een activiteit
wordt veranderd moeten daarbij de directe opvolgers of voorgangers opnieuw toege-
voegd worden aan de lijst van te reviseren activiteiten (deze lijst wordt Q genoemd).
De initialisatie-procedure kan als volgt beschreven worden in pseudocode:
4.2 Basisprincipes van de heuristiek 51
Figuur 4.2: Eenvoudige constraint-graph
Window-Initialisatie
1. for j = 1, . . . , J do
2. hLj ← Relt
3. hUj ← Tmax − Tj + 1
4. initialiseer Q← {j | j ∈ (J)}5. while Q 6= {} en ∀j ∈ J : hLj ≤ hUj do
6. Kies willekeurige taak i ∈ Q7. for elke opvolger j van i in constraint graph do
8. nieuweOndergrens← hLi + lagmini,j
9. if nieuweOndergrens > hLj
10. then hLj ← nieuweOndergrens , Q← Q ∪ {j}11. initialiseer Q← {j | j ∈ (J)}12. while Q 6= {} en ∀j ∈ J : hLj ≤ hUj do
13. Kies willekeurige taak i ∈ Q14. for elke voorganger j van i in constraint graph do
15. nieuweBovengrens← hUi − lagmini,j
16. if nieuweBovengrens < hUj
17. then hUj ← nieuweBovengrens , Q← Q ∪ {j}18. for j ← 1, . . . , J do
19. sTj ← −1
20. sLj ← hLj
21. sUj ← hUj
In lijn 19 wordt de starttijd voor elke activiteit geınitialiseerd op -1. Dit is een default-
waarde zonder verdere betekenis: een waarde -1 geeft enkel aan dat er nog geen starttijd
toegewezen is. In de volgende twee lijnen worden de soft-windows gelijkgesteld aan de
hard-windows. Merk ook op dat op lijn 5 en 12 terminatie-statements zijn ingevoerd;
van zodra een van de hard-windows door propagatie leeg wordt (d.w.z. hLj > hUj),
heeft het geen zin de initialisatie verder te zetten; het probleem is dan time-infeasible
voor de horizon Tmax. In dat geval zal het natuurlijk niet mogelijk zijn een schedule
4.2 Basisprincipes van de heuristiek 52
te vinden die zowel time als resource-feasible is. In het later besproken algoritme-
raamwerk wordt pas begonnen met de eigenlijke scheduleconstructie van het moment
dat er een Tmax is waarbij alle windows na initialisatie minstens 1 tijdsslot bevatten.
Propagatie van de windows tijdens schedule-constructie
Eens de hard-windows geınitialiseerd zijn, begint de eigenlijke constructie van het sche-
dule. Overeenkomstig de toegewezen prioriteiten worden activiteiten een voor een in-
gepland binnen hun soft-windows (dit is op zich een seriele SGS). Het omkaderend
raamwerk van het algoritme wordt in de volgende sectie besproken.
Elke keer als aan een activiteit j een starttijd sTj wordt toegewezen, worden de soft-
windows overeenkomstig verkleind. Er is immers geen onzekerheid meer over waar in
het feasible tijdsdomein (soft-windows) de activiteit geplaatst wordt en de time-lags
zullen meer bindende voorwaarden geven. Door het toewijzen van een sTj zetten we
eigenlijk zowel de bovengrens als de ondergrens voor het inplannen van j op sTj.
Geheel analoog als bij het propagatiemechanisme van de hard-windows zullen de directe
opvolgers i van j een eventuele verhoging van hun ondergrenzen zien. Indien hun sLi
verhoogd wordt, zal opnieuw moeten doorgepropageerd worden, ook de ondergrenzen
van de directe opvolgers van i moeten eventueel aangepast worden,. . .
Eveneens moet teruggewerkt worden in de constraint graph: de directe voorgangers h
van activiteit j krijgen verkleinde bovengrenzen,. . .
Telkens als bij het propageren een activiteit bereikt wordt die al een sT toegewezen
heeft gekregen, dus die al ingepland is, wordt de propagatieketen gestopt. Immers, de
toegewezen starttijd voor activiteit j is gekozen uit de waarden die mogelijk bleven na
de propagatie van die bepaalde toegewezen activiteit.
We kunnen de procedure ”Starttijd toewijzenals volgt in pseudocode beschrijven:
4.2 Basisprincipes van de heuristiek 53
Starttijd-Toewijzen(j, tijd)
1. sTj ← tijd
2. initialiseer teUpdatenOpvolgers← {}3. for elke directe opvolger k van j in constraint graph do
4. hulpvark ← sTj + lagminj,k
5. teUpdatenOpvolgers← teUpdatenOpvolgers ∪ {k}6. while teUpdatenOpvolgers 6= {} do
7. Verwijder een willekeurige j uit teUpdatenOpvolgers
8. if hulpvarj > sLj
9. then sLj ← hulpvarj
10. if sTj = −1
11. then for elke directe opvolger k van j in constraint graph do
12. if k ∈ teUpdatenOpvolgers13. then hulpvark ← max(hulpvark, hulpvarj + lagminj,k )
14. else hulpvark ← hulpvarj + lagminj,k
15. teUpdatenOpvolgers← teUpdatenOpvolgers ∪ {k}16. initialiseer teUpdatenV oorgangers← {}17. for elke directe voorganger i van j in constraint graph do
18. hulpvari ← sTj − lagmini,j
19. teUpdatenV oorgangers← teUpdatenV oorgangers ∪ {i}20. while teUpdatenV oorgangers 6= {} do
21. Verwijder een willekeurige j uit teUpdatenV oorgangers
22. if hulpvarj < sUj
23. then sUj ← hulpvarj
24. if sTj = −1
25. then for elke directe voorganger i van j in constraint graph do
26. if i ∈ teUpdatenV oorgangers27. then hulpvari ← min(hulpvari, hulpvarj − lagmini,j )
28. else hulpvari ← hulpvarj − lagmini,j
29. teUpdatenV oorgangers = teUpdatenV oorgangers ∪{i}
Gevolgen van cycli in de ’constraint graph’
Smith (2004) maakt een duidelijk onderscheid tussen scheduling-problemen met en
zonder cycli in de ’constraint graph’. Acyclische problemen zijn immers veel efficienter
op te lossen omdat een topologische sortering kan toegepast worden en het propage-
ren (inkrimpen) van de soft-windows veel efficienter kan gebeuren, namelijk 1 maal
voorwaarts en achterwaarts in de richting van de topologische sort. Doordat er echter
4.2 Basisprincipes van de heuristiek 54
zowel minimum als maximum lags worden toegelaten in RCPSP/max is het duidelijk
dat cycli zullen ontstaan. Bijvoorbeeld een CC-relatie (i, j) geeft onmiddellijk een cy-
clus i→ j → i. De procedures zoals hierboven besproken zullen dus verder in de cycli
doorpropageren tot een activiteit geen aanpassing in de windows meer ondervindt. In
dat geval worden de directe opvolgers (voorwaartse procedure) of de directe voorgangers
(achterwaartse procedure) niet meer opnieuw toegevoegd aan de lijst met te updaten
activiteiten en wordt de cyclus doorbroken. Het kan dus niet gegarandeerd worden dat
de timewindow-propagatie in een cyclische ’constraint graph’ binnen polynomiale tijd
voltooit.
Verder geeft Smith (2004) aan dat voor cyclische scheduling-problemen het kan voor-
komen dat de time-windows niet ’sound’ zijn, dit wil zeggen dat alle time-feasible
tijdssloten er in elk geval in vervat zijn maar dat er bepaalde inwendige punten niet
time-feasible zijn (de randpunten van de windows zijn echter altijd time-feasible). Er
blijkt echter dat dergelijke infeasible time-points enkel voorkomen bij problemen waar-
bij de kalender-representatie gebruikt wordt. Bijvoorbeeld bij tijdsbetrekkingen tussen
een activiteit die enkel maandag tot vrijdag kan uitgevoerd worden en een activiteit
die maandag, woensdag, vrijdag en zaterdag kan uitgevoerd worden, kunnen de gespe-
cifieerde time-lags tot infeasible time-points binnen de soft-windows leiden. Aangezien
we hier echter uitgaan van een continue tijdsschaal (alle tijdsslots zijn a priori even
bruikbaar voor een activiteit), zullen dergelijke problemen niet voorkomen en zullen
we besluiten dat onze windows zowel ’complete’ (alle time-feasible tijdsslots vallen erin)
als ’sound’ (alleen de feasible tijdsslots vallen erin) zijn. Backtracking door het selec-
teren van een time-infeasible tijdsslot zal in ons algoritme dus niet moeten voorzien
worden.
Heropbouw van de windows tijdens schedule-deconstructie
Op bepaalde plaatsen in ons algoritme is backtracking nodig. Het is dan nodig om een
activiteit j ∈ J terug te kunnen plaatsen op sTj = −1, de default-tijd. Om terug te
keren naar de toestand voor het inplannen van j is het dan echter ook nodig om de
daaruit volgende window-propagatie ongedaan te maken. Ook hier kan niet zomaar een
herexpansie worden gedefinieerd, net door de aanwezigheid van cycli in de constraint
graph.
In de procedure Starttijd-Toewijzen wordt doelbewust bij het toewijzen van sTj
niet gesteld dat sLj = sTj en sUj = sTj, hoewel dit impliciet wel de betekenis is.
In de plaats daarvan worden de oude sL en sU onveranderd gelaten. Bij een acycli-
sche constraint graph zullen ze inderdaad ook door de voorwaartse en achterwaart-
se propagatie nooit veranderd worden, want j kan natuurlijk zelf pas op de lijsten
4.2 Basisprincipes van de heuristiek 55
teUpdatenOpvolgers of teUpdatenV oorgangers terechtkomen na het doorlopen van
een cyclus j → andere activiteiten→ j. Bij een acyclische constraint graph is dit per
definitie onmogelijk.
Wij hebben echter te maken met een cyclisch netwerk door het toelaten van zowel
minimum als maximum lags. Net door deze cycli is het mogelijk dat een activiteit
zichzelf blijft constrainen. Hoewel we de waarden sLj en sUj niet expliciet wijzigen,
kan het zijn dat door de propagatie, zij na het doorlopen van een cyclus automatisch
gewijzigd worden.
Om dit op een zeer eenvoudige manier aan te tonen kunnen we het voorbeeld van figuur
4.3 bekijken. We zien 2 activiteiten met een CC-constraint die weergegeven wordt in
equivalente minimum-lags. Dit vormt onmiddelijk een cyclus 1 → 2 → 1. Op basis
van de unaire constraints (lijnen 1 t.e.m. 3 van Window-Initialisatie) bekomen we
hard-windows [2,4](1) en [1,5](2). Na de rest van procedure Window-Initialisatie
(de propagatie van de time-lags) komen we natuurlijk uit bij twee identieke hard-
windows en dus tweemaal hetzelfde soft-window [2,4].
Wanneer we nu bijvoorbeeld activiteit 1 een starttijd sT1 = 3 toewijzen, zullen de
windows als volgt aangepast worden:
• Activiteit 2 komt op de lijst teUpdatenOpvolgers en sL2 wordt 3.
• Door de wijziging wordt ook activiteit 1 bij teUpdatenOpvolgers gevoegd en
wordt sL1 = 3.
• Activiteit 2 komt nogmaals bij teUpdatenOpvolgers maar sL2 wordt niet meer
gewijzigd.
• Activiteit 2 wordt eveneens op de lijst teUpdatenV oorgangers geplaatst en sU2
wordt 3.
• Analoog als hierboven wordt ook sU1 = 3
We kunnen dus besluiten dat door het doorlopen van de cyclus niet alleen sL2 = 3
en sU2 = 3, maar ook sL1 = 3 en sU1 = 3. De waarden sL1 en sU1 kunnen dus niet
meer gebruikt worden om de ondergrenzen van de opvolgers en de bovengrenzen van
de voorgangers weer te relaxeren naar de toestand voor het inplannen van activiteit 1.
Algemeen zullen de soft-windows dus om backtracking te kunnen uitvoeren, volledig
moeten geherpropageerd worden, omdat anders de invloed van de weggehaalde activi-
teit nooit kan weggehaald worden. We zetten dus sTj = −1, opnieuw sLj = hLj en
sUj = hUj. Vervolgens vindt de propagatie opnieuw plaats. In pseudocode:
4.2 Basisprincipes van de heuristiek 56
Figuur 4.3: Voorbeeld: Zelf-constrainende soft-windows
Unschedule-Met-Cycli(i)
1. sTi ← −1
2. for j ← 1, . . . , J do
3. sLj ← hLj
4. sUj ← hUj
5. initialiseer Q← J (verz. van alle activiteiten)
6. while Q 6= ∅7. Verwijder willekeurige i uit Q
8. for elke opvolger j van i in constraint graph do
9. if sTj = −1
10. then nieuweOndergrens← sLi + lagmini,j
11. else nieuweOndergrens← sTi + lagmini,j
12. if nieuweOndergrens > sLj
13. then sLj ← nieuweOndergrens
14. Q← Q ∪ {j}15. initialiseer Q← J16. while Q 6= ∅17. Verwijder willekeurige j uit Q
18. for elke voorganger i van j in constraint graph do
19. if sTi = −1
20. then nieuweBovengrens← sUj − lagmini,j
21. else nieuweBovengrens← sTj + lagmini,j
22. if nieuweBovengrens < sUi
23. then sUi ← nieuweBovengrens
24. Q← Q ∪ {i}
4.2 Basisprincipes van de heuristiek 57
4.2.3 Het kernalgoritme: Squeaky Wheel Optimization
De basis van het geımplementeerde algoritme is een multi-pass greedy SGS-procedure.
Voor de eerste iteratie wordt aan elke activiteit een initiele prioriteitj(∈ Z) toegewezen.
Vervolgens worden de activiteiten j in volgorde van dalende prioriteit ingepland op de
vroegste resource-feasible tijd binnen de soft-windows.
Indien echter binnen [sLj, sUj] geen resource-feasible tijd gevonden wordt, zal de ac-
tiviteit worden geplaatst op sTj = sLj (maar de overeenkomstige resources worden
echter niet toegewezen aan deze activiteit; dit zou het inplannen van verdere activi-
teiten nodeloos moeilijk maken in een iteratie die globaal toch al ’infeasible’ is). Het
aldus bekomen partiele schedule is dan time-feasible maar niet meer resource-feasible.
Aan elke taak j wordt een ’vlag’ (boolean-waarde) scheduledFeasibly toegewezen die
aangeeft of de activiteit op een resource-feasible plaats kon ingepland worden. Een
globale boolean-waarde feasible geeft aan of het volledige geconstrueerde schedule fea-
sible is, dus deze wordt voor de SGS-procedure geınitialiseerd op true en wordt naar
false omgezet van zodra een activiteit waarde scheduledFeasibly = false krijgt
(dus als deze noodgedwongen ingepland wordt op sT = sL). Na de eerste iteratie
worden de prioriteiten van de ’probleemactiviteiten’ met scheduledFeasibly = false
geıncrementeerd: de activiteiten zullen in de volgende iteratie sneller ingepland wor-
den, wat meer kans geeft op een feasible schedule. Deze methode is eigenlijk een ’local
search’ op de activiteitenlijst-voorstelling van een schedule (cf. 3.2.3), en is een voor-
beeld van ’Squeaky Wheel Optimization’. In de volgende puntjes wordt de procedure
beschreven in pseudocode, beginnende met de basismethodes die vervolgens als bouw-
stenen worden gebruikt om het globale algoritme samen te stellen.
Resource-gebruik registreren en bepalen van resource-feasible tijdsslots
Voor elk van de resources k ∈ K moet een ’resource profile’ bijgehouden worden, dit
is eigenlijk een trapfunctie die in elk tijdsinterval het gecumuleerde verbruik van de
resources door de reeds ingeplande activiteiten weergeeft. Wanneer dan een nieuwe
activiteit ingepland wordt kan gecheckt worden of voor de kandidaat-uitvoeringstijden
de resource-capaciteiten Rk niet overschreden worden. Een resource-profiel voor een
horizon Tmax kan eigenlijk bekeken worden als een geordende lijst (array) van Tmax
elementen: profielk(i) is dan het aantal eenheden van resource k dat reeds in gebruik
is in tijdsslot i en profielk = [profielk(1), . . . , profielk(Tmax)]. In figuur 4.4 wordt een
visuele voorstelling getoond.
We implementeren dan de hierna volgende procedure om te checken of er nog genoeg
resources over zijn om een activiteit j ∈ J op kandidaat-starttijd t in te plannen
(1 ≤ t ≤ Tmax). Indien deze procedure ’false’ teruggeeft (cf. return-statement lijn 6)
4.2 Basisprincipes van de heuristiek 58
Figuur 4.4: Voorbeeld: Profiel van resource k met Tmax = 5
dan zijn er niet genoeg resources vrij om te starten op sTj = t.
Check-Resource-Feasible(j,t)
1. initialiseer feasible← true
2. for teller ← t to t+ Tj − 1 do
3. for k ∈ K : rj,k > 0 do
4. if profielk(teller) + rj,k > Rk
5. then feasible← false
6. return feasible
Verder geven we nog de sterk gelijkaardige procedure VERHOOG-PROFIELEN(j),
die net na het toewijzen van een sTj de profielen van de verschillende verbruikte re-
sources overeenkomstig verhoogt (indien tenminste een resource-feasible tijdsslot ge-
vonden wordt, anders wordt sTj = sLj maar worden de profielen niet overeenkomstig
verhoogd. sTj wordt verondersteld al ingegeven te zijn bij de activiteitsgegevens en
moet dus niet meer expliciet als argument meegegeven worden bij de methode. Volle-
dig analoog geven we de duale methode VERLAAG-PROFIELEN(j), die net voor de
procedure UNSCHEDULE-MET-CYCLI(j) wordt opgeroepen bij het verwijderen van
een activiteit van het schedule (backtracking) (tenzij het ging over een activiteite met
scheduledFeasibly = false natuurlijk, anders zouden we extra resources creeren). In
die gevalklen zal echter deze procedure niet opgeroepen worden, dus dat moet hier niet
in rekening gebracht worden.
Verhoog-Profielen(j)
1. for teller ← sTj to (sTj + Tj − 1) do
2. for k ∈ K : rj,k > 0 do
3. profielk(teller)← profielk(teller) + rj,k
4.2 Basisprincipes van de heuristiek 59
Verlaag-Profielen(j)
1. for teller = sTj to (sTj + Tj − 1) do
2. for k ∈ K : rj,k > 0 do
3. profielk(teller)← profielk(teller)− rj,k
Bepalen van de ondergrens voor Tmax
Er is een minimale horizon Tmax vindbaar voor time-feasibility. Een horizon is im-
mers time-feasible als en slechts als geen enkele van de initiele windows leeg is, dus
als voor geen enkele taak j ∈ J de ondergrens strikt groter wordt dan de bovengrens.
De bovengenoemde procedure Window-Initialisatie is niet zeer rekenintensief voor
een klein aantal iteraties en is niet recursief, dus wordt voorgesteld om de minima-
le horizon te bepalen op de meest brute manier: incrementeren vanaf 1 en checken
vanaf welke Tmax geen van de windows leeg is. Dit wordt dan de starthorizon van
de eerste iteratie. Hoe kleiner immers de horizon is, hoe minder rekentijd want de
bewerkingen op de resourceprofielen (sommeren en vergelijken met capaciteit), zullen
natuurlijk voor minder tijdsslots moeten gebeuren. Verder zou het in feite niet echt een
bezwaar leveren om met een grote horizon te starten; alle activiteiten worden immers
ingepland op hun vroegste resource-feasible time en de horizon zal dus geen invloed
hebben op de uiteindelijke makespan. Een te kleine horizon zal echter leiden tot een
infeasible probleem zodanig dat de horizon, startend vanaf de minimale horizon, moet
geıncrementeerd worden indien het SWO-mechanisme van het algoritme niet binnen
een aantal iteraties tot een feasible schedule komt (zie verder).
Zoek-Minimale-Horizon
1. Tmax ← 1
2. while Window-Initialisatie levert een j ∈ J : hLj > hUj
3. Tmax ← Tmax + 1
4. return Tmax
Updaten van Tmax aan het begin van een iteratie
Tussen twee verschillende iteraties van de SGS-constructor kan het nodig zijn de horizon
Tmax te incrementeren zoals in het vorige puntje reeds werd aangehaald. Dit wordt in
onze implementatie gedaan nadat tien schedule-pogingen gefaald zijn. In dat geval is
het waarschijnlijk dat de huidige Tmax niet volstaat om een tijd- en resource-feasible
te construeren. Het incrementeren van de horizon zal aanleiding geven tot meer optel-
en vergelijk-bewerkingen bij het bepalen van resource-feasibility voor starrtijden van
4.2 Basisprincipes van de heuristiek 60
activiteiten, maar is verder van weinig belang voor de uiteindelijke makespan. Het zorgt
immers enkel voor een verhoging van de bovengrenzen van hard windows (de hUi) en
de daaraan gelijke initialisatiewaarden van de sUi. Maar omdat activiteiten ingepland
worden op hun vroegste resource-feasible time zal een verlenging van de horizon dus
geen verlenging van de makespan met zich meebrengen.
We kiezen toch om te starten met een lage ondergrens van de horizon omdat gebleken is
bij onderzoek van de testcases dat de uiteindelijke minimale bekomen makespan zelden
meer dan tien tijdsslots hoger is dan de minimale horizon (cf. vorig onderdeel). Dus is
het waarschijnlijk dat we rekencapaciteit besparen door te beginnen bij de ondergrens
en telkens te incrementeren na tien infeasible iteraties bij de huidige horizon.
In het geval dat een feasible schedule bekomen wordt in het algoritme van Smith
(2004) de te gebruiken horizon gedecrementeerd. Wij wijken hier structureel van af
om hoger genoemde redenen.: en hogere horizon heeft bij onze implementatie, in te-
genstelling tot die van Smith (2004), geen invloed op de makespan. Bovendien zou
het contraproductief zijn om eens we een horizon (met n tijdsslots) bekomen waarbij
een oplossing gevonden wordt, telkens te ddecrementeren; er zijn dan weer minstens
tien infeasible iteraties nodig bij een (waarschijnlijk onhaalbare) horizon n− 1 vooral-
eer weer naar horizon n geıncrementeerd wordt. Aangezien we graag zoveel mogelijk
alternatieve oplossingen met een minimale makespan willen genereren, om vervolgens
nog eventueel te sorteren op basis van objectieven f2 en f3, is dit duidelijk een groot
nadeel. We incrementeren de horizon dus enkel.
De in de nieuwe iteratie te gebruiken nieuweHorizon wordt gestockeerd in een integer-
variabele en bij het begin van elke iteratie wordt dan de procedure
Zet-Horizon(nieuweHorizon) opgeroepen. Merk op dat deze procedure ook moet
opgeroepen als de horizon niet veranderd is t.o.v. de vorige iteratie; de resource-
profielen moeten immers terug op nulwaarden geınitialiseerd worden.
Zet-Horizon(nieuweHorizon)
1. Tmax ← nieuweHorizon
2. for alle k ∈ K (alle resources) do
3. for i← 1, . . . , Tmax (i ∈ Z)
4. initialiseer profielk(i)← 0
Het inplannen van de activiteiten
De propagatie van de softwindows bij het toewijzen van een starttijd werd reeds vroe-
ger besproken (procedure Starttijd-Toewijzen(j, tijd), zie 4.2.2). Deze procedure
4.2 Basisprincipes van de heuristiek 61
mag natuurlijk slechts opgeroepen worden voor tijd ∈ [sLj, sUj]. Ook de resource-
constraints worden niet gecheckt.
Daarom stellen we een overkoepelende procedure Schedule(j) op die j zal inplannen
vanaf het eerste resource-feasible tijdsslot. Indien er geen resource-feasible tijd gevon-
den is (voorwaarde op lijn 5 is vervuld), zal de activiteit j worden ingepland op sTj =
sLj, echter zonder de resource-profielen te verhogen. Indien we dat wel zouden doen
zou dit volgende activiteiten bij voorbaat blokkeren omdat dan de resource-profielen
sowieso al overschreden zijn (want deze activiteit wordt uiteindelijk op een plaats inge-
pland waar niet genoeg resources meer beschikbaar zijn). Bijgevolg zouden alle nog te
schedulen activiteiten na de iteratie een vlag scheduledFeasibly = False meegekregen
hebben en opschuiven naar de voorkant van de activiteitenlijst-representatie.
Indien we echter de resources niet toewijzen, is er veel kans dat volgende activiteiten
nog op haalbare plaatsen kunnen ingepland worden; enkel activiteit j wordt dan naar
voor geschoven aan het eind van de iteratie. Op die manier kunnen we het prioriteiten-
mechanisme een veel soepelere werking geven: probleemactiviteiten worden geısoleerd
van de andere en afzonderlijk naar voor geschoven in de priority-queue.
De procedure kan als volgt in pseudocode worden geformuleerd:
Schedule(j)
1. initialiseer t← −1
2. for tijdTeller ← sLj to sUj
3. if Check-Resource-Feasible geeft True terug
4. then t = tijdTeller en breek for-loop af
5. if tijdTeller = −1
6. then Starttijd-Toewijzen(j, sLj)
7. scheduledFeasiblyj = False
8. return False
9. else Starttijd-Toewijzen(j, tijdTeller)
10. Verhoog-Profielen(j)
11. scheduledFeasiblyj = True
11. return True
Het bepalen van de Makespan
Indien alle activiteiten ingepland werden op een zowel tijd- als resource-feasible manier
kunnen we de makespan van het schedule op simpele wijze bepalen:
4.2 Basisprincipes van de heuristiek 62
Bepaal-Makespan(j)
1. initialiseer makespan← −1
2. for alle j ∈ J3. if (sTj + Tj − 1) > makespan
4. then makespan← (sTj + Tj − 1)
5. return makespan
Merk hier op dat deze makespan-procedure ook kan toegepast worden op een schedule
dat niet feasible is. Er moet dus uitwendig voor gezorgd worden dat de makespan
enkel bepaald wordt in iteraties waar na het inplannen alle activiteiten j een vlag
scheduledFeasiblyj = True hebben.
Initiele prioriteiten
Voor de eerste iteratie moeten, zoals hoger beschreven, alle windows geinitialiseerd
worden met de procedure Window-Initialisatie. De initiele prioriteiten worden
bepaald door middel van een soort ’LST’-prioriteitsregel (Latest Start Time), dus op
basis van de bovengrenzen hUj = sUj van de oorspronkelijke windows. De activiteiten
met de laagste waarden voor hUj krijgen de hoogste prioriteiten, deze hebben immers
de meest ’dringende’ deadline hU en kunnen dus best eerder behandeld worden, om
meer kans te hebben op een feasible schedule vanaf de eerste iteraties. De prioriteiten
worden steeds genormaliseerd tot waarden 1, . . . , J ∈ Z (met J het aantal activiteiten),
omdat het enkel gaat over de onderlinge rangschikking van de prioriteiten en niet
over de waarde op zich. IOp die manier worden berekeningen met onnodig grote
prioriteitswaarden vermeden. De procedure wordt hier niet expliciet beschreven, maar
wordt verder in het raamwerk opgeroepen door ’Initialiseer-Prioriteiten’.
Aanpassen prioriteiten tussen iteraties
Na elke iteratie geven de boolean-variabelen ’scheduledFeasiblyj’ voor alle activiteiten
j ∈ J aan of de activiteit in de laatste iteratie succesvol gescheduled is. We willen alle
actviteiten die niet succesvol ingepland werden naar de voorkant van de activiteitenlijst-
voorstelling schuiven, d.w.z. we wijzen er de hoogste prioriteiten aan toe. Hiertoe
bepalen we de hoogste huidige aanwezige prioriteit en nemen die als increment voor
alle prioriteitj waarvoor scheduledFeasiblyj = False. Hierna worden de prioriteiten
genormaliseerd, dit wil zeggen de rangschikking blijft behouden maar zo dat de waarden
prioriteitj oplopen van 1 tot J (het aantal activiteiten in J ). Dit doen we omdat enkel
de onderlinge volgorde en niet de echte waarde van de prioriteiten belang heeft.
Vervolgens kunnen ook de prioriteitj-waarden waarvoor scheduledFeasiblyj = True
aangepast worden, om een random-variatie te introduceren in de prioriteitsrij. Op die
4.2 Basisprincipes van de heuristiek 63
manier worden ook in geval van een feasible schedule de prioriteiten gewijzigd. Het is
natuurlijk niet de bedoeling om even drastisch bij te sturen als voor de niet succesvol
ingeplande activiteiten, het is eerder de bedoeling om hier een additionele ’random’
drift te implementeren (naar analogie met ’random sampling’-methodes). We kiezen
ervoor om voor elke succesvol ingeplande activiteit de prioriteitj met een probabiliteit
0,1 te incrementeren met waarde twee. Na een nieuwe sortering op prioriteitswaarde
komt dit overeen met een plaats opschuiven naar de bovenkant van de priority-queue.
Voor de normalisatie worden de activiteiten immers eerst gehersorteerd op basis van
dalende prioriteitj. Er wordt een ’stabiele’ sorteringsmethode toegepast, dit wil zeggen
dat activiteiten met een zelfde prioriteitswaarde in dezelfde relatieve volgorde blijven
staan.
Stel bijvoorbeeld dat we een lijst met vier activiteiten hebben die succesvol ingepland
werden. Voor het updaten van hun prioriteitenlijst is de activiteitenlijst-voorstelling
dan bijvoorbeeld:
λ = [a, b, c, d] met a, b, c, d ∈ JAangezien we werken met prioriteiten komt deze voorstelling overeen met:
prioriteita = 4, prioriteitb = 3, prioriteitc = 2, prioriteitd = 1
Stel nu dat de randomprocedure beslist om prioriteitc te incrementeren. Na stabiele
hersortering krijgen we dan:
prioriteita = 4, prioriteitc = 4, prioriteitb = 3, prioriteitd = 1
De normalisatie geeft dan:
prioriteita = 4, prioriteitc = 3, prioriteitb = 2, prioriteitd = 1
λ′ = [a, c, b, d] met a, b, c, d ∈ JWe zien dus dat b inderdaad ’over’ c gesprongen is in de activiteitenlijst.
Voor de implementatie van de probabiliteit 0,1 in de programmacode (zie appendix B
en korte bespreking in volgende hoofdstuk), wordt een random geheel getal in interval
[0, 10[ gegenereerd. Bijgevolg zal dit getal in ongeveer 1/10 gevallen gelijk zijn aan 0.
Indien er een nul gegenereerd wordt zal de prioriteitj geıncrementeerd worden met 2.
Het updaten van de prioriteiten volgens hiervoor beschreven methode gebeurt door de
procedure Update-Prioriteiten.
4.2 Basisprincipes van de heuristiek 64
SWO-iteraties
Het aantal schedules (feasible of infeasible) dat geconstrueerd wordt is bij een multi-
pass methode natuurlijk bepaald door het aantal iteraties van de constructormethode.
Dit kan vrij gekozen worden en wordt meegegeven als een parameter van de SWO-
procedure. De variabele bestMakespan ∈ Z wordt geınitialiseerd op -1, analoog aan
de ’default’-waarde van sTj voor het inplannen van j, en houdt de minimale makespan
bij van alle gevonden feasible schedules. Dit is dan ook de returnwaarde op het einde
van het algoritme.
Swo(aantalIteraties)
1. initialiseer bestMakespan← −1
2. initialiseer minimaleHorizon← Zoek-Minimale-Horizon
3. initialiseer nieuweHorizon← minimaleHorizon
4. Initialiseer-Prioriteiten
5. for iteratieTeller ← 1 to aantalIteraties do
6. initialiseer feasible← True
7. Zet-Horizon(nieuweHorizon)
8. reset alle variabelen uit vorige iteraties
9. Window-Initialisatie
10. for i← 1 to J do (J = aantal activiteiten)
11. kies activiteit j met hoogste prioriteitj uit {j ∈ J | sTj = −1}12. scheduledFeasiblyj ← Schedule(j)
13. if scheduledFeasiblyj = False
14. then feasible← False
15. if feasible
16. if (Bepaal-Makespan< bestMakespan of bestMakespan = −1)
17. then bestMakespan←Bepaal-Makespan
18. if 10 iteraties zonder feasible = True bij huidige horizon
19. then nieuweHorizon← nieuweHorizon+ 1
20. Update-Prioriteiten
21. return bestMakespan
4.2.4 Aanvulling 1: Bulldozing
De basisversie van het Swo-algoritme gebruikt enkel prioriteitenlijst als volgorde van
inplannen. Bij het toelaten van maximum-lags, zoals typisch bij omstelproblemen
het geval is, kan er echter een bijkomende moeilijkheid ontstaan voor de ’greedy’-
constructor procedure. Stel bijvoorbeeld dat een we een activiteit 1 relatief vroeg
inplannen omdat er genoeg resources beschikbaar zijn. Het kan echter zijn dat er
4.2 Basisprincipes van de heuristiek 65
met een activiteit 2 een lagmax1,2 bestaat waardoor de vroege inplanning van activiteit
1 er net voor zorgt dat de activeit een leeg soft-window krijgt of een soft-window
zonder resource-feasible times erin (de maximumlag zal immers de bovengrens van het
softwindow van activiteit 2 mogelijks verlagen). Bij de aanwezigheid van meerdere zulke
subproblemen (van twee of meerdere activiteiten) met strenge onderlinge beperkingen
kan het zijn dat het eerder besproken prioriteits-updatemechanisme niet snel tot een
oplossing komt, omdat de ’probleemactiviteiten’ van de verschillende subproblemen
tegelijk naar de voorkant van de prioriteitsrij worden geschoven.
In sommige gevallen kan het echter nodig zijn om de activiteiten van een dergelijk
subprobleem net na elkaar te behandelen, omdat activiteiten die ertussenin schuiven
in de activiteitenlijst-voorstelling net beslag kunnen leggen op resources die kritisch
zijn voor het inplannen van het subprobleem. Het kan dus voorkomen dat het pas
achteraf blijkt dat een activiteit niet op de vroegste resource-feasible tijd binnen het
soft-window mag ingepland worden, net door de tijdsbetrekkingen met later in te plan-
nen activiteiten, die pas succesvol kunnen ingepland worden als eerstgenoemde op een
later tijdstip werd geplaatst.
Om dergelijke problemen efficienter te kunnen aanpakken, stelt Smith (2004) een ’lo-
cal repair’ mechanisme voor om resource-conflicten op te lossen, dat hij ’bulldozing’
noemt. Indien er voor een activiteit j geen resource-feasible tijd gevonden wordt bin-
nen het soft-window (dat geldt dus ook als het soft-window leeg is of sU < sL), wordt
niet onmiddelijk scheduledFeasiblyj = False gezet,maar er wordt verder gezocht naar
de vroegste resource-feasible tijd tot aan de hLj, de bovengrens van de hard windows.
Indien er een feasible tijd t te vinden is in ]sUj, hUj] wil dit zeggen dat deze tijd aanvan-
kelijk tijds-feasible was, maar door reeds ingevoerde activiteiten buiten de soft-windows
gepropageerd werd. Taak j wordt dan in de in wezen ongeldige tijd t gestart (t = sTj),
de vensters worden gepropageerd via de procedure Starttijd-Toewijzen(j, t) en de
profielen worden overeenkomstig verhoogd. Bij het doorpropageren van de windows
ontstaan onvermijdelijk inverse (lege soft-windows), want het feit dat t buiten het
soft-window van j valt wijst er net op dat de tijdstoewijzing t conflicteert met eerder
ingeplande activiteiten.
Er zijn dus een aantal reeds ingeplande activiteiten i waarbij de starttijd sTi niet
voldoet aan de lagmini,j of lagminj,i (rechtreekse relatie tussen i en j). Al deze activiteiten
worden bijgevoegd in een verzameling teHerplannen, voorzover ze er nog niet inzitten
(geen dubbels).
Vervolgens worden de activiteiten uit teHerplannen in willekeurige volgorde uit de
verzameling gehaald, van het schedule verwijderd door het oproepen van Verlaag-
4.2 Basisprincipes van de heuristiek 66
Profielen(i) en Unschedule-Met-Cycli(i) (deze procedure bouwt de vensters
opnieuw op zonder de toewijzing van de betreffende activiteit), en opnieuw ingepland.
Indien een herplande activiteit een starttijd krijgt boven de bovengrens van zijn huidige
soft-window (dus ook als het soft-window leeg is), zullen opnieuw een aantal directe
time-lags niet gerespecteerd worden; dit resulteert in een nieuw aantal activiteiten die
toegevoegd worden aan de lijst teHerplannen.
Indien op een bepaald moment teHerplannen = ∅ dan is de bulldozing-procedure suc-
cesvol afgerond en krijgt de eerste opgeroepen activeit de vlag scheduledFeasibly =
True. Indien op gelijk welk moment in de procedure een activiteit geen resource-
feasible tijd heeft binnen [sL, hU ] wil dit zeggen dat door het stapsgewijs verder schui-
ven van de activiteiten in de horizon (wat bulldozing in feite doet), de horizon te klein
geworden is. Alle herplande activiteiten worden terug op hun vorige waarden gezet
(dus alle bulldozing wordt ongedaan gemaakt), en net zoals bij de gewone schedule-
procedure van het basisalgoritme wordt dan de eerst opgeroepen activiteit j wordt
ingepland op sTj = sLj, de profielen worden niet verhoogd (om dezelfde redenen als
hierboven) en de vlag scheduledFeasiblyj wordt op False gezet. Bulldozing is dus in
feite een recursieve methode en doet aan backtracking na een gefaalde bulldoze.
Dit alles kan doorgevoerd worden door in de code van het basisalgoritme Swo (zie
blz. 64) de procedure Schedule(j) te vervangen door de hieronder gegeven procedure
Schedule-Met-Bulldozing(j). Om alle bulldozing te kunnen ongedaan te maken
wordt net voor het oproepen van de procedure Schedule-Met-Bulldozing(j) eerst
een backup genomen van de huidige schedule-situatie in ’reservevariabelen (procedure
Take-Backup). Merk hierbij op dat de hard-windows steeds dezelfde blijven en dus
niet moeten bijgehouden worden als reservekopie. Bij een onsuccesvolle bulldoze kan
dan teruggekeerd worden naar de situatie van de backup met behulp van de procedure
Restore-Backup. De boolean-variabele die dit triggert is revertToInitial. De drie
procedures kunnen als volgt in pseudocode worden beschreven:
Take-Backup
1. for alle j ∈ J (alle activiteiten) do
2. sLbackupj ← sLj
3. sUbackupj ← sUj
4. sTbackupj ← sTj
5. scheduledFeasiblyBackup← scheduledFeasibly
6. for alle k ∈ K (alle resources) do
7. profielBackupk ← profielk
4.2 Basisprincipes van de heuristiek 67
Restore-Backup
1. for alle j ∈ J (alle activiteiten) do
2. sLj ← sLbackupj
3. sUj ← sUbackupj
4. sTj ← sTbackupj
5. scheduledFeasibly ← scheduledFeasiblyBackup
6. for alle k ∈ K (alle resources) do
7. profielk ← profielBackupk
4.2 Basisprincipes van de heuristiek 68
Schedule-Met-Bulldozing(j)
1. initialiseer t← −1
2. initialiseer teHerplannen← {j}3. Take-Backup
4. initialiseer revertToInitial←False
5. while teHerplannen 6= ∅ do
6. verwijder een willekeurige taak n uit teHerplannen
7. if sTn 6= −1
8. if scheduledFeasiblyn = True
9. Verlaag-Profielen(n) EN scheduledFeasiblyn ←True
10. Unschedule-Met-Cycli(n)
11. initialiseer t← −1
12. for tijdTeller ← sLn to hUn
13. if Check-Resource-Feasible=True
14. then t← tijdTeller en breek for-loop af
15. if t = −1
16. then revertToInitial← True en breek do-while lus af
17. else
18. if t ≤ sUn
19. Starttijd-Toewijzen(n, t)
20. Verhoog-Profiel(n)
21. scheduledFeasiblyn ← true
22. else
23. Starttijd-Toewijzen(n, t)
24. Verhoog-Profiel(n)
25. scheduledFeasiblyn ← true
26. for alle directe opvolgers o ∈ J van n in constraint graph do
27. if sTo 6= −1 EN sTo − sTn < lagminn,o
28. then teHerplannen← teHerplannen ∪ {o}29. for alle directe voogangers m ∈ J van n in constraint graph
do
30. if sTm 6= −1 EN sTn − sTm < lagminm,n
31. then teHerplannen← teHerplannen ∪ {m}32. if revertToInitial = True
33. then Restore-Backup
34. Starttijd-Toewijzen(j, sLj)
35. scheduledFeasiblyj ← False
36. return False
37. else return True;
4.2 Basisprincipes van de heuristiek 69
4.2.5 Aanvulling 2: Refilling
De bulldozing-procedure kan ervoor zorgen dat met een bepaalde activiteitenlijst-
volgorde een feasible schedule wordt geconstrueerd, terwijl dit met de simpele greedy
constructor niet zou lukken bij een relatief krappe horizon. Inherent aan bulldozing is
echter wel dat activiteiten verder opgeschoven worden in het schedule omdat andere
activiteiten hiermee een sterk begrensd subprobleem vormen. Wanneer een activiteit
echter door bulldozing naar achter wordt geschoven in de horizon, komen er op die
vroegere uitvoeringstijden natuurlijk resources vrij. Vaak kan het zijn dat een of enke-
le activiteiten teruggeschoven kunnen worden in de horizon.
Figuur 4.5: Voorbeeld: nut van refilling-mechanisme
We illustreren met volgende voorbeeld hoe refilling nuttig kan zijn na bulldozing. Het
probleem is samengevat op de constraint graph van figuur 4.5. Stel dat de prioriteiten
bij een bepaalde iteratie leiden tot de activiteitenlijst-volgorde λ = [1, 2, 3].
Het basisalgoritme plaatst 1 op starttijd 1, vervolgens 2 op starttijd 2 (want hL2 is naar
2 verschoven door de tijdsbeperkingen met activiteit 3, die exact een tijdsslot vroeger
moet beginnen). Deze inplanning maakt dat het soft-window van 3 beperkt wordt tot
[1, 1], terwijl er eigenlijk geen werknemer meer over is om op dat moment te starten
met activiteit 3. Activiteit 3 wordt dan ingepland op zijn ondergrens sT3 = sL3 = 1
en de vlag scheduledFeasibly = wordt op False gezet (zie figuur 4.6(a)).
Hierdoor komt na de procedure Update-Priorities activiteit 3 aan het begin van de
activiteitenlijst-presentatie: λ′ = [3, 1, 2]. Hierbij is de random-prioriteitendrift voor
activiteiten j met scheduledFeasiblyj = True voor de duidelijkheid van de redenering
4.2 Basisprincipes van de heuristiek 70
weggelaten. Op figuur 4.6(b) is te zien dat ook deze volgorde niet onmiddelijk tot een
feasible schedule zal leiden bij gebruik van het basisalgoritme Swo. In de volgende
iteratie wordt activiteit 2 naar voor geschoven zodat λ′′ = [2, 3, 1] en dit leidt tot het
feasible schedule van figuur 4.6(c).
Figuur 4.6: Voorbeeld: Swo-basisalgoritme vindt feasible schedule na 3 iteraties
Als we de iteraties van het algoritme met bulldozing bekijken, startend vanaf dezelfde
activiteitenlijst λ = [1, 2, 3], bekomen we de iteraties van figuur 4.7. Dit algoritme
vindt na een succesvolle bulldoze van activiteit 2 onmiddelijk een feasible schedule
vertrekkend van λ. We kunnen echter direct zien dat dit schedule niet optimaal is;
indien immers zowel activiteit 2 als 3 een plaats vroeger geschoven worden zullen we
een feasible schedule vinden met een kleinere makespan. Deze actie, getoond in figuur
4.8 is exact de aanvulling nog gemaakt wordt door Smith (2004) bij zijn RCPSP/max
heuristiek, nl. ’refilling’.
4.2 Basisprincipes van de heuristiek 71
Na een succesvolle bulldoze kan het dus zijn dat de gehele, onderling sterkt gecons-
trainde verzameling van gebulldozede activiteiten collectief kan vervroegd worden door
resources die vrijgemaakt zijn (net door het bulldozen). We definieren procedures
Refill-Groep en Refill-Individueel die opgeroepen na een succesvolle bulldoze.
De boolean useOfBulldozing geeft aan of er bulldozing is gebruikt en of dus de pro-
cedures moeten opgeroepen worden. Beide hieronder beschreven procedures kunnen
worden bijgevoegd onderaan de procedure Schedule-Met-Bulldozing, en enkele
variabelen worden toegevoegd om info te stockeren.
Figuur 4.7: Voorbeeld: Swo-Met-Bulldozing vindt feasible maar niet-optimaal sche-dule na 1 iteratie
Refill-Groep poogt de alle activiteiten die deelnamen aan de bulldoze (die gestoc-
keerd worden in de verzameling bulldozedSet, simultaan naar links te schuiven. Dit
zal meer kans op succes hebben dan elke activiteit afzonderlijk te schuiven; het is net
door de strenge beperkingen tussen de activiteiten dat de bulldoze-procedure inge-
schakeld werd. Om deze procedure succesvol te kunnen volbrengen worden alle taken
in bulldozedSet van het schedule gehaald, echter niet met behulp van de procedure
Unschedule-Met-Cycli, omdat deze elke keer de soft-windows opnieuw opbouwt,
wat tussendoor onnodig is. In de plaats daarvan worden de starttijden gewoon op
-1 geplaatst en de profielen overeenkomstig verlaagd. Nadat dan alle activiteiten in
bulldozedSet op deze manier van het schedule zijn gehaald worden alle soft-windows
opnieuw opgebouwd. Op basis van de time-constraints wordt bepaald wat de maximale
4.2 Basisprincipes van de heuristiek 72
Figuur 4.8: Voorbeeld: Swo-Met-Bulldozing-Refilling kan het laatste schedule uitfig. 4.7 verbeteren
shift is van alle activiteiten tegelijk. Om dan te kunnen checken of een bepaalde shift
ook resource-feasible is wordt een gecumuleerd profiel hulpprofielk ingevoerd voor elke
resource, dit is het profiel van het resourcegebruik van alle activiteiten in bulldozedSet,
zoals ze gepland zijn voor het oproepen van de refill-procedure. Als we dan bijvoor-
beeld willen checken of een opschuiving van alle activiteiten in bulldozedSet van -2
tijdsslots ook resourcefeasible is, kunnen we de de hulpprofielen twee plaatsen naar
links opschuiven en bijtellen bij de profielen die overblijven na het unschedulen van
alle activiteiten in bulldozedSet.
Refill-Individueel probeert na een succesvolle bulldoze en na het oproepen van
Refill-Groep de nog overgebleven ’gaten’ in het schedule te dichten door alle ac-
tiviteiten j ∈ J afzonderlijk van het schedule te halen en terug te plaatsen met de
basismethode Schedule(j). Alle activiteiten j waarvoor sTj > sLj komen in aanmer-
king.
Bij de refilling dient nog opgemerkt te worden dat Smith (2004) de refilling-procedure
voor bulldozedSet niet volledig succesvol geımplementeerd heeft (zie voetnoot op pa-
gina 78 in zijn werk). Slechts een kandidaat-positie wordt daar telkens in aanmerking
genomen. In het voorbeeld dat besproken is zal zijn procedure activiteit 2 en 3 elk 2
plaatsen naar links proberen te schuiven, maar omdat dit niet lukt worden de pogingen
4.2 Basisprincipes van de heuristiek 73
gestaakt. De mogelijkheid om een plaats terug te schuiven wordt aldus niet benut (cf.
figuur 4.8). De code die hier voorgesteld wordt checkt alle mogelijke terugschuifgroot-
tes, maar riskeert om zeer rekenintensief te worden t.o.v. de vorige aanpassing en het
basisalgoritme. De pseudocode kan als volgt geformuleerd worden:
Refill-Groep(bulldozedSet)
1. Take-Backup
2. initialiseer maximumShift← Tmax
3. for alle resources k ∈ K do
4. initialiseer hulpprofielk ← [0, . . . , 0](Tmaxelementen)
5. for alle activiteiten j ∈ bulldozedSet do
6. for teller ← sTj to sTj + Tj − 1 do
7. hulpprofielk(teller)← hulpprofielk(teller) + rj,k
8. for alle activiteiten j ∈ bulldozedSet do
9. if scheduledFeasiblyj = True
10. Verlaag-Profielen(j)
11. sTj ← −1
12. scheduledFeasiblyj = False
13. bouw soft-windows opnieuw op (cf. procedure Unschedule-Met-
Cycli)
14. for alle activiteiten j ∈ bulldozedSet do
15. if (sTbackupj − sLj < maximumShift)
16. then maximumShift← sTbackupj − sLj17. for teller ← maximumShift to 0 (decrementeren!) do
18. if teller = 0
19. then Restore-Backup
20. initialiseer resourceFeasible← True
21. for alle resources k ∈ K do
22. for t← 1 to (Tmax −m) do
23. if profielk(t) + hulpprofielk(t+m) > Rk
24. then resourceFeasible← False en breek for loop lijn 21 af
25. if resourceFeasible = True
26. then
27. for activiteiten j ∈ bulldozedSet do
28. Starttijd-Toewijzen(j, sT backupj −m)
29. Verhoog-Profielen(j)
31. breek for-lus lijn 17 af
4.2 Basisprincipes van de heuristiek 74
Refill-Individueel
1. for alle activiteiten j ∈ J do
2. Take-Backup
3. if sTj 6= −1
4. if scheduledFeasiblyj = True
5. Verlaag-Profielen(j)
6. Unschedule-Met-Cycli(j)
7. if Schedule(j) = False
8. Restore-Backup
De beide bovenstaande procedure kunnen in Schedule-Met-Bulldozing(j) ge-
plaatst worden, om een procedure Schedule-Met-Bulldozing-Refilling te be-
komen. Er moet dan ook nog wel de variabele bulldozedSet bijgehouden worden, op
bijna dezelfde manier als teHerplannen, met als verschil dat de activiteiten er niet
terug uitgehaald worden naarmate ze opnieuw worden ingepland. Het basisalgoritme
kan dan rechtreeks gebruikt worden als we de procedure Schedule(j) vervangen door
Schedule-Met-Bulldozing-Refilling(j). We bouwen deze laatste als volgt op:
Schedule-Met-Bulldozing-Refilling(j)
1. initialiseer bulldozedSet = j
2. −lijnen 1 t.e.m. 36 van Schedule-Met-Bulldozing
+ aanpassing bijhouden van bulldozedSet (lijnen 28 en 32)−3. else
4. if #(bulldozedSet) > 1
5. then Refill-Group(bulldozedSet)
6. Refill-Individueel
7. return True
4.2.6 Aanpassingen voor secundaire objectieven
Het basisalgoritme (al dan niet met aanvullingen bulldozing en/of refilling) zoals het
hierboven beschreven is heeft maar een output, namelijk ’besteMakespan’, de gehele
returnwaarde van de methode. Nu is bij het testen van deze drie versies van het algo-
ritme gebleken dat de implementatie m.b.t. het vinden van deze minimale makespan
f1 zeer goed presteert ten opzichte van de optimale resultaten van het kwantitatief mo-
del uit Van Goubergen (2001). Het algoritme is vaak tevens in staat vele alternatieve
schedules te genereren met diezelfde minimale makespan f1.
Hoewel de manier van inplannen van de activiteiten in de Swo-procedure volledig ge-
concipieerd is om een minimale makespan te bereiken, en enkel dat, is het dan toch
4.2 Basisprincipes van de heuristiek 75
mogelijk uit de bekomen gelijkwaardige (wat betreft de makespan) schedules een selec-
tie te maken op basis van de f2-waarde die uit dit schedule kan berekend worden. Men
kan zelfs nog verder gaan en een selectie maken op zowel f1, f2 als f3. Op die manier
kan nagegaan worden of het algoritme eventueel als vervanger van niet enkel de eerste
trap van algoritme A1 (cf. figuur 2.1) kan beschouwd worden, maar zelfs als vervanger
van de eerste twee trappen of zelfs nog de eerste drie (hoewel betrouwbare resultaten
wat dat betreft weinig waarschijnlijk zijn).
Alle informatie van de bekomen schedules kan natuurlijk niet meer teruggegeven wor-
den in een simpele return van de methode Swo. Daarom is er in de Java-implementatie,
waarvan de code in appendix B te vinden is en op bijgeleverde CD-rom, voor gekozen
om een extra datastructuur aan te maken waarin van per gegenereerd schedule hetzij
f1, hetzij f1 en f2, hetzij f1 en f2 en f3 kan bijhouden. Voorts moeten natuurlijk
ook alle starttijden van het schedule weggeschreven worden in de datastructuur. De
gebruiker kan dna een keuze maken uit de te optimaliseren objectieven (f1, f1 − f2 of
f1 − f2 − f3) en de uit te voeren versie van het algoritme (basisversie, met bulldozing
of met bulldozing en refilling).
Indien enkel f1 wordt geoptimaliseerd worden alle reeds weggeschreven schedules uit de
datastructuur gewist indien een nieuwe besteMakespan gevonden wordt in een bepaalde
iteratie. Voor een verder gevonden schedule dat dezelfde f1 waarde heeft als de reeds
gestockeerde schedules, wordt gecheckt of het schedule nog niet opgeslagen is. Indien
het schedule minstens in een starttijd sT verschilt van alle andere reeds opgeslagen
schedules, wordt het weggeschreven in de datastructuur (met behoud van de elementen
die er reeds inzaten).
Wanneer we uutbreiden naar selectie op basis van zowel f1 als f2 kunnen we ons baseren
op de pre-emptieve beslissingsregels van algrotime A1:
• indien een schedule met een nieuwe besteMakespan gevonden wordt is dit sowieso
beter dan alle vorige; wis datastructuur en voeg schedule toe.
• indien schedule gevonden met makespan= besteMakespan: bereken f2
– Indien f2 beter dan de reeds gestockeerde f2-waarden van de schedules: wis
datastructuur en voeg huidig schedule toe.
– Indien f2 gelijk aan de waarde van de reeds weggeschreven schedules: check
of schedule verschillend van de andere en voeg desgevallend toe aan data
– Indien f2 groter is dan de reeds gestockeerde waarden: verwerp schedule,
niet opslaan.
4.2 Basisprincipes van de heuristiek 76
• indien schedule met makespan> besteMakespan: verwerp schedule, niet opslaan.
Op volledige analoge manier kunnen we de beslissingregels uitbreiden naar f1−f2−f3.
Dit is in de implementatie allemaal ingebouwd in de verschillende Swo-varianten. Er
zijn bovendien nog enkele methoden geschreven met behulp van het open-source pakket
JExcel voor Java, waarmee input en output uit en naar MS Excel kan bekomen worden.
Op die manier kunnen alle data voor een relevant probleem ingelezen worden via een
ingevulde template. Op het einde van de Swo-methode wordt dan automatisch in de
inputfile een bijkomende sheet ’Results’ aangemaakt, waarin de relevante gegevens van
de geselecteerde schedules weggeschreven worden (geselecteerd volgens de hierboven
uiteengezette beslissingsregels). Voor de concrete gebruiksaanwijzing van het pakket,
zie het volgende hoofdstuk.
Verder zijn natuurlijk nog de methoden Bepaal-f2 en Bepaal-f3 nodig om de doel-
functiewaarden na het opbouwen van een feasible schedule te kunnen berekenen. Deze
worden opgebouwd op basis van de formules 2.14 en 2.11, respectievelijk. In pseudo-
code:
Bepaal-F2(huidigeMakespan ∈ Z)
1. initialiseer totalSlack ← 0
2. for teller ← 1 to huidigeMakespan do
3. totalSlack ← totalSlack + Lmax − profiellabor[teller]4. initialiseer avgSlack ← totalSlack/huidigeMakespan (∈ R)
5. initialiseer f2 ← 0 (∈ R)
6. for teller ← 1 to huidigeMakespan do
7. f2 ← f2 + |Lmax − profiellabor[teller]− avgSlack|8. return f2
Bepaal-F3(makespan ∈ Z)
1. initialiseer f3 ← 0 (∈ Z)
2. for teller ← 1 to makespan do
3. initialiseer slack ← Lmax − profiellabor[teller] (∈ Z)
4. initialiseer coeff ← ((makespan− teller − 1)(Lmax + 1))+1 (∈ Z)
5. f3 ← f3 + slack · coeff6. return f3
GEBRUIK EN DETAILS JAVA-IMPLEMENTATIE 77
Hoofdstuk 5
Gebruik en details
Java-implementatie
5.1 Gebruiksaanwijzing Java-implementatie
Alle geımplementeerde Java-klassen zijn verpakt in een file (RunSwo.jar) die vanaf de
commandline (het programma ’Command Prompt’ in MS Windows XP bijvoorbeeld)
kan opgeroepen worden. De data-input (en ook de keuzes van het algoritme en het
aantal iteraties) gebeuren via het invullen van een MS Excel template. In volgende
stappen worden de gebruiks-instructies stapsgewijs overlopen.
5.1.1 Installatie van de JRE
Aangezien Java gecompileerd wordt tot platformonafhankelijke code, die geınterpreteerd
wordt door de te installeren ’Java Virtual Machine’, is een specifiek besturingssysteem
a priori niet vereist. Omdat het programma echter geschreven is met Excel-I/O is het
wel noodzakelijk om ’*.xls’-files te kunnen lezen en bewerken op een correcte manier.
Om de gecompileerde code te runnen moet bovendien ook de Java Virtual Machine
geınstalleerd worden. Deze kan best gedownload worden als de JRE (’Java Runtime
Environment ’), waarbij de API en de Virtual Machine beide samen gedistribueerd
worden, zodanig dat de twee zeker compatibel zijn met elkaar (dit is een noodzaak).
Op het moment van het opstellen van deze tekst is de meest recente versie JRE 6
Update 1. De installatiefile mag door derden vrij verspreid worden onder bepaalde
voorwaarden en is op bijgeleverde cd-rom te vinden in de map ’JRE’ (dit is enkel de
installatiefile voor 32-bit Windows OS; voor andere besturingssystemen wordt verwezen
naar http://java.sun.com).
Opdat de Java-programma’s die opgeroepen worden vanaf de ’command prompt’ de
5.1 Gebruiksaanwijzing Java-implementatie 78
juiste bibliotheken van de JRE zouden kunnen vinden, kan best de ’Environment Va-
riable’ CLASSPATH aangepast worden. Indien de JRE-distributie bijvoorbeeld in de
typische folder C:\\Program Files\Java\jre1.6.0_01\ wordt geınstalleerd, kan men
de CLASSPATH-variabele in Windows XP als volgt aanpassen:
1. Ga naar het ’Control Panel’ (via Start>Control Panel)
2. Klik eventueel linksboven op ’Switch to Classic View’
3. Dubbelklik op system en kies de tab ’Advanced’
4. Klik onderaan op de knop ’Environment Variables’ (=Omgevingsvariabelen)
5. Dubbelklik op de lijn die links ’CLASSPATH’ vermeldt
6. Voeg achteraan de weergegeven tekstlijn de tekst
”; C:\\Program Files\Java\jre1.6.0_01\bin” toe. Pas dit aan aan de wer-
kelijke folder waar de JRE op uw systeem geınstalleerd is.
Nu zou het mogelijk moeten zijn om in de command prompt vanuit elke mogelijke
folder de programmas java.exe (om programma’s uit te voeren) en javac.exe (om pro-
grammacode te compileren) uit te voeren.
5.1.2 Invullen van de MS Excel template
Op de bijgeleverde cd-rom, in de map ’Template’, is de blanco MS-Excel template
terug te vinden die als input voor het programma kan dienen. Op elke sheet is info
gegeven over de manier van invullen. Het is belangrijk de layout en de positie van
de cellen niet te wijzigen en de instructies strikt op te volgen. We tonen hier enkele
screenshots van de input van testcase 1 (zie ook appendix A) ter illustratie:
Sheet ’Opties’
Op deze sheet wordt gekozen welke versie van het algoritme wordt uitgevoerd en op
basis van welke doelfuncties de output wordt bepaald:
5.1 Gebruiksaanwijzing Java-implementatie 79
Figuur 5.1: De sheet opties van de input-template case 1
Sheet ’Taken’
Hierin worden de taken gedefinieerd met al hun relevante parameters. Per taak wordt
een lijn gebruikt. Voor het invoeren van meerdere machinenummers per taak mag
verder naar rechts gewerkt worden.
Figuur 5.2: De sheet taken van input Case 1
Sheet ’PD’
Hier wordt per lijn een ’ketting’ van de precedence graph ingegeven. Dit is zo
geımplementeerd omdat het heel wat tijd vraagt om de precedence-relaties per twee
activiteiten in te voeren. Bij deze manier van invoeren moet er op gelet worden om geen
PD-relaties dubbel in te voeren. De gebruiker kan natuurlijk ook opteren om telkens
per twee activiteiten te werken (op elke lijn komt dan een koppel volgnummers).
5.1 Gebruiksaanwijzing Java-implementatie 80
Figuur 5.3: De sheet PD van input Case 1
Sheet ’DJ’
Een aparte lijn is opgenomen voor het ingeven van machinedisjuncties (per cel 1 ma-
chinenummer). Voor de rest gebeurt de input analoog aan die van de sheet ’PD’.
Figuur 5.4: De sheet DJ van input Case 1
Sheets ’CC’ en ’CS’
Deze sheets worden op dezelfde manier ingegeven als de sheet ’PD’ (meer dan twee
volgnummers van taken per rij zijn toegelaten, in voorkomend geval).
5.1.3 Uitvoeren van het Swo-algoritme
1. Plaats de map ’RunSwo’ van bijgeleverde CD-ROM op de harde schijf waar ze
gemakkelijk toegankelijk is vanaf de ’command prompt’, stel C:\\RunSwo.
2. Vul de template in met de probleemgegevens en sla deze op in de net aange-
maakte map RunSwo, stel onder de naam ’filename.xls’. Zorg ervoor dat er
geen sheet met de naam ’Results’ aanwezig is, aangezien het programma deze zal
aanmaken. Een mogelijkheid is een aanwezige sheet ’Results’ hernoemen naar
een willekeurige naam die niet voor de gegevensinput gebruikt wordt.
3. Sluit het MS Excel bestand.
4. Open de ’command prompt’ (in Windows) en navigeer naar de map RunSwo.
5.2 Structurering van de JAVA-implementatie 81
5. Geef als commando java -jar runswo.jar filename.xls, waarbij
’filename.xls’ natuurlijk moet worden vervangen door de naam van de inputfile.
6. De voortgang wordt op het scherm aangegeven en na afloop kan de inputfile terug
geopend worden. De resultaten zijn te vinden in de sheet ’Results’.
5.2 Structurering van de JAVA-implementatie
De implementatie is integraal gebaseerd op de methodes beschreven in het voorgaan-
de hoofdstuk. De code is bijgeleverd in appendix B en op de cd-rom in de map
’Sourcecode’. Een overzicht van de geprogrammeerde klassen wordt gegeven in fi-
guur 5.5. De klasse Task omvat bijna alle hulpprocedures die in hoofdstuk 4 besproken
werden, terwijl de klasse SchedulingAlgoritmes de verschillende versies van het globale
algoritme implementeert. Aangezien dit geen scriptie in de computerwetenschappen
is, wordt geen uitgebreide uitleg gegeven over de methodes en datastructuren. Er is
enorm veel detailwerk en debug-tijd aan besteed, maar voor het doel van deze scriptie
volstaat het de pseudocode-methodes uiteen te zetten.
Figuur 5.5: Geımplementeerde Java-classes
RESULTATEN: TOEPASSING OP TESTCASES 82
Hoofdstuk 6
Resultaten: toepassing op testcases
In dit hoofdstuk wordt besproken welke oplossingen bekomen worden door het uitvoe-
ren van de verschillende algoritme-procedures van de implementatie, op de gegevens
van de drie testcases die ontleend werden aan Van Goubergen (2001). Deze bekomen
oplossingen worden met de oplossingen van het kwantitatief model die Van Goubergen
(2001) aangeeft en die eerder besproken werden (zie blz. 23 e.v.). Alle inputgege-
vens zijn te vinden in appendix A. De bekomen sheets met resultaten (en dus ook de
inputgegevens) zijn op bijgeleverde CD-ROM opgenomen in de map ’CaseResultaten’.
Aangezien bij het testen van het algoritme vastgesteld is dat het niet noodzakelijk een
beter resultaat oplevert om een zeer groot aantal iteraties te laten lopen, worden enkele
tests gedaan bij 100.000 iteraties (5 runs per algoritme-versie). Het zou voorbarig zijn
om te vervallen in diepgaande statistische analyses op basis van referentiegegevens van
slechts drie testcases. De keuze van 100.000 iteraties is gemaakt op basis van een af-
weging tussen enerzijds genoeg ruimte laten om het prioriteiten-mechanisme zijn gang
te laten gaan, en anderzijds de berekening binnen praktisch bruikbare rekentijden te
houden. Bij 50.000 iteraties werd gemerkt dat er nog merkbaar minder alternatie-
ve schedules gegenereerd werden dan bij 100.000, maar bij de overstap naar 500.000
iteraties was er niet veel verschil meer op te merken.
Verder kan een niet al te groot aantal iteraties ook nuttig zijn om de verbeteringen van
de aanpassingen aan te tonen; bij bulldozing bijvoorbeeld zullen sneller meer schedules
gegenereerd worden dan bij het basis-algoritme. Bij een miljoen iteraties wordt de
rekentijd ook al minder praktisch werkbaar. De rekentijden zijn telkens aangegeven
per geval.
De experimenten gebeurden op een PC met Intel(R) Core2 CPU T7200 @2,00 GHz.
Aangezien het algoritme volledig sequentieel werkt en niet in meerdere threads geschre-
ven is wordt evenwel slechts 1 processorkern gebruikt bij de uitvoering.
6.1 Case 1-1: Voor toepassing van SMED 83
6.1 Case 1-1: Voor toepassing van SMED
6.1.1 Selectie op basis van f1
Basis-Swo
In elk van de vijf runs wordt makespan f1 = 11 gevonden. Dit is de optimale waarde
die Van Goubergen (2001) aangeeft. Er worden minstens respectievelijk 189, 176, 172,
174, schedules weggeschreven met makespan 11, wat dus een vrij robuuste prestatie
is. Gemiddeld worden er 198 schedules gegenereerd. De rekentijd bedraagt telkens
ongeveer 15 seconden of dus 0, 15 ms per iteratie.
Swo met bulldozing
Ook hier wordt steeds de makespan f1=11 bereikt. Er is echter een duidelijke stijging
in het aantal gegenereerde schedules (respectievelijk 270, 267, 256, 269, 268). Hieruit
kunnen we afleiden dat bulldozing inderdaad een geschikte strategie is om meer feasible
schedules te genereren. De rekentijd wordt wel gevoelig hoger, namelijk 0, 22 ms per
iteratie, wat neerkomt op een verhoging met ongeveer factor 1,5 ten opzichte van het
basisalgoritme.
Swo met bulldozing en refilling
f1 = 11 wordt steeds bereikt. Het aantal gegenereerde schedules met deze makespan is
in de vijf runs respectievelijk 255, 232, 257, 253 en 230. Deze aantallen liggen weliswaar
allemaal hoger dan die van het basisalgoritme, echter duidelijk lager dan die bij enkel
toepassing van bulldozing. Daarbij komt nog de veel langere rekentijd: 130 seconden
voor de 100.000 iteraties, of dus ongeveer 1, 3 ms per iteratie. Dit is ongeveer 10 keer
langer dan het basisalgoritme en 6 keer langer dan bij enkel toepassing van bulldozing.
Het is niet meteen duidelijk waarom het refilling-mechanisme onderpresteert. De lange
rekentijd valt te verklaren door de nogal omslachtige implementatie van de procedures
Refill-Groep en Refill-Individueel. Dit is echter nog geen verklaring waarom
er minder schedules worden gegenereerd dan bij bulldozing alleen (in se is refilling
immers een uitbreiding). Blijkbaar zit er ergens een anomalie in de logica van de
refill-procedure. Aangezien we slechtere resultaten en een hard oplopende rekentijd
constateren voor een redelijk beperkte probleemomvang, kan het verwacht worden dat
bij grotere cases zoals Case 3, de refilling-procedure de rekentijd nog meer onnodig
doet oplopen, zonder daarbij een beter resultaat te geven. Er wordt daarom gekozen
om vanaf alle volgende situaties de test op refilling achterwege te laten.
6.1 Case 1-1: Voor toepassing van SMED 84
6.1.2 Selectie op basis van f1 − f2
Basis-Swo
In alle vijf de runs worden de door Van Goubergen (2001) opgegeven optimale waarden
f1 = 11 en f2 = 3, 2727 gevonden, echter niet altijd in evenveel schedules. Het aantal
bekomen schedules per run: 2, 13, 14, 48 en 39. Hieruit wordt duidelijk dat het ba-
sisalgoritme zeker niet alle feasible schedules met een makespan 11 kan bepalen, anders
zou minstens het aantal schedules met minimale f2 ongeveer gelijk zijn. Onmiddellijk
zien we de nadelen van het bij-optimaliseren van doelfunctie f2; door de nervositeit van
het prioriteitenmechanisme (random-functie) kunnen zowel zeer weinig als relatief veel
schedules met minimale f2 voor f1 = 11 gevonden worden. Een betrouwbare oplossing
vinden zal dienaangaande bijvoorbeeld meer iteraties vergen (minder praktisch), maar
zeker ook uitvoering van verschillende gescheiden runs achter elkaar .
Het verschil in rekentijd met het basisalgoritme en selectering enkel op basis van f1
is verwaarloosbaar klein. Verschillen worden veroorzaakt door de randomness van het
algoritme. Dit valt te verklaren doordat in feite op net dezelfde manier schedules
worden gegenereerd; het enige verschil is dat enkel die met een minimale f2 worden
bijgehouden (bij een reeds geminimaliseerde f1).
Swo met bulldozing
Respectievelijk 2, 12, 15, 24 en 3 schedules worden gevonden met de referentie-optimale
waarden voor de twee doelfuncties. We beomen hier dus een lager gemiddeld aantal
schedules dan bij het basisalgoritme, hoewel voor enkel de optimalisatie van f1 bull-
dozing steevast meer schedules genereerde met f1 = 11 dan het basis Swo-algoritme.
De random-trend weegt dus door op de verbetering die bulldozing aanbrengt; hieruit
mag echter niet geconcludeerd worden dat bulldozing slechter presteert dan het basis-
algoritme, echter wel dat de huidige implementatie van de heuristiek zeer random is en
dat sluitende garanties in verband met oploskwaliteit moeilijk te geven zijn.
Bemoedigend is dat in elk van de vijf runs de optimale waarden voor de twee doelfunc-
ties wel gevonden worden. De rekentijd is bij benadering gelijk aan die met bulldozing
en enkel f1-selectie.
6.1.3 Selectie op basis van f1 − f2 − f3
Basis-Swo
In elke run worden dezelfde vier schedules weggeschreven, met optimale waarden voor
f1 en f2, en met f3 = 54. De optimale waarde van Van Goubergen (2001) wordt dus
6.2 Case 1-2: Na toepassing van SMED 85
niet bereikt; we kunnen reeds vermoeden dat alle drie de doelfuncties optimaliseren een
brug te ver is voor de heuristiek die in se geconstrueerd is voor enkel de minimalisatie
van f1. De rekentijd is dezelfde als bij het basisalgoritme met selectie o.b.v. f1.
Swo met bulldozing
• # weggeschreven: 22, 18, 21, 19, 19
• overal objectieven f1 en f2 optimaal.
• f3 is nergens optimaal, maar nu wel f3 = 46 (10 kleiner dan bij basisalgoritme),
en er worden meer schedules gegenereerd. Hier blijkt dus weer de constructieve
meerwaarde van het bulldozing-mechanisme.
• Rekentijd is dezelfde als bulldozing met enkel f1-selectie.
6.2 Case 1-2: Na toepassing van SMED
6.2.1 Selectie op basis van f1
Basis-Swo
• Telkens 10 schedules weggeschreven met optimale f1 (60).
• Ongeveer 24 seconden per run, dus 0, 24 ms per iteratie.
Swo met bulldozing
• Opnieuw telkens 10 schedules weggeschreven met optimale f1 (60).
• Ongeveer 37 seconden per run, dus 0, 37 ms per iteratie (opnieuw ongeveer 1,5x
langer dan basisalgoritme).
6.2.2 Selectie op basis van f1 − f2
Basis-Swo
• Zelfde 10 schedules gegenereerd als hiervoor, zij hebben immers allen f2 = 0 = f ∗2 .
• Zelfde rekentijd als basis-Swo met enkel f1-selectie.
Swo met bulldozing
• Zelfde 10 schedules gegenereerd als hierboven.
• Zelfde rekentijd als bulldozing-Swo met enkel f1-selectie.
6.3 Case 1-3: Na SMED, nieuwe Relt(m) 86
6.2.3 Selectie op basis van f1 − f2 − f3
Basis-Swo
• Zelfde 10 schedules gegenereerd als hiervoor, zij hebben immers allen f2 = 0 = f ∗2en f3 = 0 = f ∗3 .
• Zelfde rekentijd als basis-Swo met enkel f1-selectie.
Swo met bulldozing
• Zelfde 10 schedules als hierboven.
• Zelfde rekentijd als bulldozing-Swo met enkel f1-selectie.
6.3 Case 1-3: Na SMED, nieuwe Relt(m)
6.3.1 Selectie op basis van f1
Basis-Swo
• In elk van de vijf runs worden 8 schedules gegenereerd met de door Van Goubergen
(2001) opgegeven optimale f ∗1 (72).
• Ongeveer 24 seconden per run, dus 0, 24 ms per iteratie, ongeveer even lang als
bij ongewijzigde releasetime (Case 1−2).
Swo met bulldozing
• Zelfde resultaten als basis-algoritme; telkens 8 schedules met makespan 72.
• 0, 35 ms per iteratie (1,5x langer dan basisalgoritme).
6.3.2 Selectie op basis van f1 − f2
Basis-Swo
• Er worden per run 3, 1, 3, 1 en 2 schedules met makespan 72 en f2 = 41 weg-
geschreven. Van Goubergen (2001) geeft als f ∗2 echter een waarde 36 op. Ons
basisalgoritme is dus niet in staat hier de optimale f2-waarde te bereiken.
• 0, 25 ms per iteratie.
6.3 Case 1-3: Na SMED, nieuwe Relt(m) 87
Swo met bulldozing
• Er worden 4, 3, 4, 4 en 4 schedules weggeschreven, telkens met optimale makespan
en f2 = 39. Deze f2 is lager dan die bekomen door het basisalgoritme, maar de
optimale waarde 36 wordt ook hier niet bereikt. Bulldozing zorgt wel voor een
verbetering, en een robuustere prestatie m.b.t. het aantal geselecteerde schedules.
• Opnieuw 0, 35 ms per iteratie (1,5x langer dan basisalgoritme).
6.3.3 Selectie op basis van f1 − f2 − f3
Aangezien in de vorige stap (selectie op basis van f1−f2) nergens de optimale f2 bereikt
werd, kunnen natuurlijk geen schedules gevonden worden met de optimale waarden van
de drie eerste doelfuncties, wegens de preemptiviteit van de benadering. We geven toch
de resultaten ter volledigheid.
Basis-Swo
• Alle vijf runs geven 4 weggeschreven schedules met waarden f1 = 72 (optimaal),
f2 = 39 en f3 = 6612. De reden waarom het basisalgoritme nu wel aan een
waarde 39 komt voor f2 tegenover 41 wanneer enkel f1 − f2 als selectiecriteria
dienden, is niet duidelijk. Waarschijnlijk is dit te wijten aan de random-functie
op de prioriteitenlijst en de systeemtijd; de random-generators in Java gebruiken
als ’sead’ een getal afgeleid van de systeemtijd.
• 0, 25 ms per iteratie.
Swo met bulldozing
• Zelfde resultaten als bij het basisalgoritme: 4 weggeschreven schedules met waar-
den f1 = 72 (optimaal), f2 = 39 en f3 = 6612.
• 0, 35 ms per iteratie.
6.4 Case 1-4: Na SMED, nieuwe Relt(m), Lmax = 4 88
6.4 Case 1-4: Na SMED, nieuwe Relt(m), Lmax = 4
Samengevatte resultaten worden gegeven in tabel 6.1. Er wordt merkwaardig genoeg in
alle procedures een downtime f1 = 65 gevonden (steeds slechts 1 schedule, altijd hetzelf-
de). Dit is een tijdsslot minder dan de door Van Goubergen (2001) gevonden oplossing
(zie *** in tabel). Aangezien Van Goubergen (2001) een optimaal model voorstelt is
dit een contradictie. Aan de hand van de voorwaarden opgegeven in Van Goubergen
(2001) en opgenomen in appendix A en het multischema van de oplossing (tabel 6.1), is
gecheckt dat aan alle voorwaarden in de hier gevonden oplossing wel degelijk voldaan
is. Een mogelijke oorzaak is dat een voorwaarde van de case-situatie niet opgenomen is
in de tekst van Van Goubergen (2001). Als gevolg van de inconsistentie hebben we hier
weinig aan de referentierichtwaarden; doelfunctiewaarde f1 is het belangrijkst dus in de
regel is het hier bekomen schedule beter dan de door Van Goubergen (2001) bekomen
oplossingen. De hier gevonden oplossing is in ieder geval consistent met de ingegeven
voorwaarden.
Tabel 6.1: Resultaten heuristiek voor case 1-4
# schedules f1 f2 f3 rekentijd/iteratie
optimalisatie f1
basis-swo 1 (x5) 65*** 0, 25 ms
bulldozing 1 (x5) 65*** 0, 35 ms
optimalisatie f1, f2
basis-swo 1 (x5) 65*** 48,46 0, 25 ms
bulldozing 1 (x5) 65*** 48,46 0, 35 ms
optimalisatie f1, f2, f3
basis-swo 1 (x5) 65*** 48,46 14501 0, 25 ms
bulldozing 1 (x5) 65*** 48,46 14501 0, 35 ms
6.4 Case 1-4: Na SMED, nieuwe Relt(m), Lmax = 4 89
Figuur 6.1: Multi-machine schema case 1-4
6.5 Case 2-1: Na SMED-stap 1 90
6.5 Case 2-1: Na SMED-stap 1
De resultaten zijn samengevat in tabel 6.2. Ook hier worden kleinere makespans f1
bereikt dan in Van Goubergen (2001), namelijk 48 tegenover 50 (zie *** in tabel).
De multischema’s (voorbeeld figuur 6.2) werden geverifieerd met de voorwaarden (cf.
appendix A).
Tabel 6.2: Resultaten heuristiek voor case 2-1
# schedules f1 f2 f3 rekentijd/iteratie
optimalisatie f1
basis-swo 37 (5x) 48*** 0, 18 ms
bulldozing 40 (x2), 41(x2), 42 48*** 0, 26 ms
optimalisatie f1, f2
basis-swo 37 (5x) 48*** 21,96 0, 18 ms
bulldozing 40 (x3), 41(x2) 48*** 21,96 0, 26 ms
optimalisatie f1, f2, f3
basis-swo 37 (5x) 48*** 21,96 1820 0, 18 ms
bulldozing 37 (4x), 36 48*** 21,96 1820 0, 26 ms
6.6 Case 2-2: Na SMED-stappen 2-3 91
Figuur 6.2: Multi-machine schema case 2-1
6.6 Case 2-2: Na SMED-stappen 2-3
De resultaten zijn samengevat in tabel 6.3. Opnieuw wordt een kleinere makespan
bekomen dan de door Van Goubergen (2001) opgegeven waarde (40). Een van de
bekomen oplossingen is voorgesteld in figuur 6.3.
6.6 Case 2-2: Na SMED-stappen 2-3 92
Tabel 6.3: Resultaten heuristiek voor case 2-2
# schedules f1 f2 f3 rekentijd/iteratie
optimalisatie f1
basis-swo 30 (x5) 39*** 0, 18 ms
bulldozing 34, 35 (x2), 36(x2) 39*** 0, 25 ms
optimalisatie f1, f2
basis-swo 30 (x5) 39*** 19,49 0, 18 ms
bulldozing 35(x4), 36 39*** 19,49 0, 25 ms
optimalisatie f1, f2, f3
basis-swo 7(x5) 39*** 19,49 1432 0, 18 ms
bulldozing 7(x5) 39*** 19,49 1432 0, 25 ms
Figuur 6.3: Multi-machine schema Case 2-1
6.7 Case 3 93
6.7 Case 3
Voor case 3 geeft Van Goubergen (2001) enkel de geoptimaliseerde f1-waarde, aangezien
de CPLEX-procedure na enkele dagen rekenen werd stilgelegd. Bijgevolg heeft het
weinig zin om 100.000 iteraties te doen voor alle opties van onze heuristiek. Enkel de
optimalisatie van f1 wordt getest in vijf runs (van 100.000 iteraties). De rekentijd is
sterk opgelopen voor deze case, omdat we te maken hebben met een grotere horizon,
een groter aantal activiteiten (69) en meer constraints. De resultaten zijn te vinden in
tabel 6.4.
Aangezien voor selectie op basis van f1 zowel het basisalgoritme als het algoritme met
bulldozing zeer vele oplossingen vonden, werd een test met 100.000 iteraties uitgevoerd,
bulldozing en selectie op basis van f1 − f2 − f3, om zodoende richtwaarden mee te
geven voor f ∗2 en f ∗3 . Deze kunnen natuurlijk niet getoetst worden aan de resultaten
van Van Goubergen (2001). Er werden waarden f1 = 68, f2 = 142, 82 en f3 = 90834
gevonden.
Tabel 6.4: Resultaten heuristiek voor case 3
# schedules f1 f2 f3 rekentijd/iteratie
optimalisatie f1
basis-swo 376, 358, 371, 353, 383 68 / / 4, 5 ms
bulldozing 3300, 2346, 2789, 2138, 2087 68 / / 7, 6 ms
BESLUITEN 94
Hoofdstuk 7
Besluiten
7.1 Verwezenlijkingen
7.1.1 Vervangen model ’1D’ in kwantitatief model door Van
Goubergen (algoritme A1)
Uit de resultaten van de toepassing op de testcases is duidelijk gebleken dat het algo-
ritme zeer betrouwbaar is met betrekking tot het oplossen van objectief f1, het vinden
van de minimale makespan.
Dit is dus op zich al een verwezenlijking, daar Van Goubergen (2001) ook aangeeft dat
de eerste stap in het volledig preemptief model (algoritme A1 - stap 1D), een groot deel
van de rekentijd voor zich neemt. De input voor de volgende stap is enkel de optimale
makespan f ∗1 . De f ∗1 -waarden die Van Goubergen (2001) opgeeft worden in alle testcase-
gevallen behaald door de hier geıntroduceerde heuristiek, meestal zelfs al vanaf de eerste
tientallen iteraties. Er dient hier echter wel benadrukt te worden dat op basis van de
drie cases, in hun verschillende situaties, moeilijk allesomvattende besluiten kunnen
getrokken worden. Het zou echter geen zin hebben om vele andere omstelproblemen te
testen; we kunnen de bekomen oplossingen immers niet toetsen aan een referentiewaar-
de van een optimaal model. Een optimale oplossing bekomen met de heuristiek kan
trouwens nooit gegarandeerd worden; dit is van nature niet mogelijk, aangezien het al-
goritme steeds polynomiaal is qua rekentijd, en het RCPSP/max-scheduling probleem,
dat we als model voor onze omstelproblemen gebruikten, NP-hard is.
Zoals aangehaald bij de resultaten (vorige hoofdstuk), zijn er enkele case-situaties waar-
bij een makespan bekomen werd die kleiner is dan de optimaal veronderstelde oplossin-
gen uit Van Goubergen (2001). Na uitgebreid nazicht van de gegenereerde schedules
werden geen fouten gevonden m.b.t. de ingegeven probleemstelling en beperkingen.
Het is dan ook gissen naar de reden waarom het kwantitatief optimalisatiemodel van
7.1 Verwezenlijkingen 95
Van Goubergen (2001), dat gebruik maakt van optimale branch-and-bound technieken,
niet de oplossingen genereert die wij bekomen. Enerzijds is het mogelijk dat er ergens
een implementatiefoutje ingeslopen is, anderzijds is het ook mogelijk dat in de tekst een
of meerdere voorwaarden vergeten zijn, waardoor wij met een minder beperkt geheel te
maken hebben. Dit lijkt het meest waarschijnlijk, omdat voor alle andere case-gevallen
onze gevonden downtime wel overeenstemt met de door Van Goubergen (2001) gegeven
f ∗1 . Verder onderzoek is hierover is in elk geval aangewezen, maar kon niet binnen de
vereiste tijd afgerond worden.
7.1.2 Verschillende versies van het Swo-algoritme
Wat betreft het verschil tussen de verschillende geımplementeerde varianten van het
basisalgoritme (basis-Swo, Swo met bulldozing en Swo met bulldozing en refilling)
is gebleken dat het basisalgoritme behoorlijk presteert, maar dat voor een gegeven
aantal iteraties de bulldozing-procedure het aantal gegenereerde schedules met optimale
makespan gevoelig verhoogt. De iteraties met bulldozing vergen wel ongeveer de helft
meer rekentijd dan die van het basisalgoritme.
De refilling-procedure gaf, tegen de verwachtingen, na tien keer langere rekentijden
per iteratie dan het basisalgoritme, slechtere resultaten dan het algoritme met bulldo-
zing (echter wel iets betere dan het basisalgoritme). In de refilling-implementatie zit
waarschijnlijk een anomalie, die echter niet getraceerd kon worden.
7.1.3 Bruikbare Java-implementatie
De algoritmes werden geprogrammeerd en getest in de programmeertaal Java. Een
geıntegreerde procedure werd ontwikkeld waarbij alle input, de keuze van het uit te
voeren algoritme en het aantal iteraties kunnen ingevoerd worden via een MS Excel
inputsheet. De resultaten worden als extra sheet bijgevoegd in de inputfile. Het gebruik
van deze implementatie (bijgeleverd op cd-rom), werd uitgelegd in hoofdstuk 5.
7.1.4 Uitbreiden tot verdere stappen van algoritme A1
Hoewel het algoritme qua methodologie opgebouwd is om een minimale makespan
te vinden, is gaandeweg gebleken dat voor een gegeven optimale f ∗1 nog een ruim
aantal verschillende schedules met die downtime bekomen werden. In plaats van enkel
het getal f ∗1 als onze output te kijken, en de-optimalisatie van verdere objectieven
f2,f3 en f4 aan het kwantitatief model van algoritme A1 (zoals geformuleerd door
Van Goubergen (2001)) over te laten, is het dus ook mogelijk om uit de alternatieve
7.2 Verdere mogelijkheden tot onderzoek 96
schedules met f1 = f ∗1 een selectie te maken op basis van verdere doelfuncties f2 (en
eventueel f3).
Hierbij is echter vastgesteld dat moeilijk besluiten kunnen getrokken worden over de
betrouwbaarheid van het algoritme. Ook door de inconsistentie met de f1-waarden uit
Van Goubergen (2001), blijven er weinig testcases over waar een duidelijk beeld kan
gevormd worden over de bekomen f2 en f3-waarden. Indien de gebruiker van de imple-
mentatie richtwaarden wil bekomen voor de optimale f2 en f3, kunnen best een ruim
aantal iteraties (meer dan honderdduizend) uitgevoerd worden met het bulldozing-
mechanisme, en dit enkele keren na elkaar (wegens de random-drift bij het doorzoeken
van de prioriteitslijst-ruimte). Voor f2 worden op die manier redelijke waarden beko-
men (optimaal voor case 1-1 en 1-2, drie eenheden hoger dan optimale waarde in case
1-3). Voor case 3 is geen referentie-f2 beschikbaar. Voor de overblijvende cases werd
een lagere f1 gevonden dan die van Van Goubergen (2001), waardoor ook de vergelij-
king met f2 vervalt (f1 is immers een belangrijker objectief, dus een schedule met een
lagere f1 is altijd een ’beter’ schedule).
Voor het bij-optimaliseren van f3 worden niet echt betrouwbare resultaten bekomen
(enkel optimaal bij case 1-2).
Wegens in vorige punt aangehaalde redenen is het gebruik van de refilling-procedure
ook bij de uitbreiding naar f2 en f3 steeds af te raden.
7.2 Verdere mogelijkheden tot onderzoek
Een eerste punt dat nader onderzoek vraagt, is het bekomen van kleinere downtimes
dan de door Van Goubergen (2001) aangehaalde waarden. Aangezien op basis van
de in die tekst besproken voorwaarden en taakeigenschappen geen conflicten werden
gevonden met de door de heuristiek bekomen schedules, moet dus nagekeken worden
of bijvoorbeeld alle voorwaarden wel vermeld werden in de tekst. Indien dit niet het
geval is, zal dat waarschijnlijk de oorzaak van de verschillen zijn. Anders zal onderzoek
van de CPLEX-implementatie van Van Goubergen (2001) raad moeten brengen.
De heuristiek die hier geımplementeerd werd is qua raamwerk een vrij eenvoudig mecha-
nisme. Een local-search mechanisme wordt geıntroduceerd door taken te verschuiven
in de priority queue. Smith (2004) geeft aan dat de filosofie van het bijhouden van
soft- en hard-windows zich eveneens leent voor het inbouwen in TS-strategieen (Tabu
Search, metaheuristiek). Aangezien een dergelijk algoritme de ruimte van prioriteits-
volgordes efficienter verkent en vermijdt dat ’in rondjes’ wordt geıterereed (cycling),
is een dergelijke strategie waarschijnlijk bevorderlijk voor het vinden van nog meer al-
7.2 Verdere mogelijkheden tot onderzoek 97
ternatieve feasible schedules en zal dit dus ook meer schedules met minimale f ∗1 geven
(en bij uitbreiding, meer schedules met minimale f ∗1 , f∗2 en eventueel f ∗3 , preemptief in
die volgorde).
Indien het echter enkel de bedoeling is om f1 te minimaliseren, is dit niet strikt nood-
zakelijk aangezien de hier voorgestelde multipass-heuristiek f ∗1 accuraat bepaalt in alle
bekeken gevallen. Op basis van de bekomen waarde f ∗1 zou dan nog moeten getest
worden of de vervanging van de eerste stap ’1D’ in het model A1 van Van Goubergen
(2001) door onze heuristiek inderdaad de verhoopte tijdsreductie teweegbrengt in de
totale berekeningstijden van het kwantitatief model van Van Goubergen (2001). De
multi-pass heuristiek (hier besproken) geeft dan f ∗1 door aan de tweede stap ’1B’ van
algoritme A1.
Het onderpresteren van het methodologisch gezien nochtans logische ’refilling’ kan ook
onderzocht worden. Een meer efficiente implementatie is niet evident (zoals ook aan-
gehaald door Smith (2004)), maar kan misschien een oplossing bieden voor deze ano-
malie.
GEGEVENS VAN DE TESTCASES 98
Bijlage A
Gegevens van de testcases
De drie testcases worden ontleend aan Van Goubergen (2001), zodoende kan een ’bench-
mark’ gebeuren van de hier bekomen oplossingen t.o.v. de optimale oplossingen van het
kwantitatief model volgens Van Goubergen (2001). Aangezien we zonder benchmark-
resultaten weinig zinnig kunnen besluiten over onze oplossing, worden dan ook enkel
de gevallen gegeven waarin Van Goubergen (2001) de oplossingen van het kwantitatief
model geeft. Voor case 1 en 2 behandelt Van Goubergen (2001) telkens enkele situaties,
voor case 3 wordt er maar 1 ge-analyseerd. De betekenis van de grbuikte symbolen is
te vinden in sectie 2.1.
A.1 Case 1
A.1.1 Voor toepassing van SMED
• Aantal beschikbare werknemers:
Lmax = 3
A.1 Case 1 99
• Taken en eigenschappen:
Tabel A.1: Gegevens activiteiten van case 1 voor SMED-toepassing
Taak lengte Tj werknemers Lj releaseTime machine 1 machine 2
1 1 1 1 1 2
2 2 1 1 1
3 2 1 1 2
4 2 1 1 1 2
5 1 2 1 3
6 1 2 1 4
7 2 1 1 3
8 2 1 1 4
9 2 1 1 3 4
10 6 1 1 5
11 2 1 1 6
12 4 1 1 5 6
13 1 1 1 3 4
14 1 1 1 5 6
• ’Precedence’ AoN-diagramma:
Figuur A.1: Precedence-relaties case 1 (Van Goubergen, 2001)
Omzetting naar Excel-input van de precedence-graph:
A.1 Case 1 100
Tabel A.2: Precedence-relaties van case 1 voor SMED-toepassing
1 2 4
1 3 4
1 5 7 15 17
1 6 8 16 17
1 10 12
1 11 12
• Machinedisjuncties:
Tabel A.3: Machine-disjuncties van case 1 voor SMED-toepassing
1 2 3 4 5 6
• CC = ∅
• CS = ∅
• DJ = ∅
A.1.2 Na toepassing van SMED
• Aantal beschikbare werknemers:
Lmax = 3
• Taken en eigenschappen:
De taken die na toepassing van SMED geelimineerd werden krijgen overal nul-
waarden. De reden dat ze in de excel-input niet geschrapt werden is omdat zo
de precedence-ralaties kunnen behouden blijven. Indien we ze zouden schrappen
moet elke referentie naar de betrokken activiteiten uit de constraints gehaald
worden, omdat Java anders tracht te verwijzen naar een niet-bestaand object.
De implementatie van het algoritme heeft echter geen enkele moeite om taken
met lengte ’0’ te behandelen, dus is het voor de gebruiker eenvoudiger gewoon
Lj = 0 in te voeren. De geschrapte activiteiten worden in onderstaande tabel
cursief gegeven.
A.1 Case 1 101
Tabel A.4: Gegevens activiteiten van case 1 na SMED-toepassing
Taak lengte Tj werknemers Lj releaseTime machine 1 machine 2
1 0 0 0 0
2 15 1 1 1
3 15 1 1 2
4 0 0 0 0
5 0 0 0 0
6 0 0 0 0
7 22 1 1 3
8 22 1 1 4
9 0 0 0 0
10 25 2 1 5
11 25 1 1 6
12 0 0 0 0
13 0 0 0 0
14 0 0 0 0
15 13 1 1 3
16 13 1 1 4
17 5 1 1 3 4
• ’Precedence’ AoN-diagram:
idem als voor SMED-toepassing
• Machinedisjuncties:
idem als voor SMED-toepassing
• CC = ∅
• CS = ∅
• DJ = ∅
A.1.3 Situatie met gewijzigde ReleaseTimes
Om de reele situatie beter weer te geven worden releaseTimes per machine gedefinieerd.
Het model is echter zo opgebouwd dat voor elke taak expliciet de releasetime wordt
ingegeven. De taakgegevens met gewijzigde releasetimes zijn in onderstaande tabel
weergegeven.
• Aantal beschikbare werknemers:
Lmax = 3
A.1 Case 1 102
• Taken en eigenschappen:
Tabel A.5: Gegevens activiteiten van case 1 na SMED, met gewijzigde Relt(m)
Taak lengte Tj werknemers Lj releaseTime machine 1 machine 2
1 0 0 0 0
2 15 1 20 1
3 15 1 20 2
4 0 0 0 0
5 0 0 0 0
6 0 0 0 0
7 22 1 1 3
8 22 1 1 4
9 0 0 0 0
10 25 2 40 5
11 25 1 41 6
12 0 0 0 0
13 0 0 0 0
14 0 0 0 0
15 13 1 1 3
16 13 1 1 4
17 5 1 1 3 4
• ’Precedence’ AoN-diagram:
idem als voor SMED-toepassing
• Machinedisjuncties:
idem als voor SMED-toepassing
• CC = ∅
• CS = ∅
• DJ = ∅
A.1.4 Situatie met gewijzigde ReleaseTimes en een extra per-
soon
We behouden voor deze vierde situatie van case 1 de gewijzigde releaseTimes maar een
extra persoon wordt toegevoegd om de reductie van de downtime te onderzoeken.
A.2 Case 2 103
• Aantal beschikbare werknemers:
Lmax = 4
• Taken en eigenschappen:
idem als in vorige situatie
• ’Precedence’ AoN-diagram:
idem als in vorige situatie
• Machinedisjuncties:
idem als in vorige situatie
• CC = ∅
• CS = ∅
• DJ = ∅
A.2 Case 2
A.2.1 Na SMED-stap 1
• Aantal beschikbare werknemers:
Lmax = 2
• Taken en eigenschappen:
*activiteit 13 wordt eigenlijk pas een echte activiteit met een Lj 6= 0 in de vol-
gende situatie, na het toepassen van SMED 2-3.
A.2 Case 2 104
Tabel A.6: Gegevens activiteiten van case 2 na SMED-1
Taak lengte Tj werknemers Lj releaseTime machine 1
1 10 1 1 1
2 14 1 1 1
3 1 1 1 1
4 8 0 1 1
5 2 1 16 2
6 6 1 1 1
7 4 1 16 4
8 4 1 16 5
9 12 1 16 6
10 15 1 16 7
11 6 1 16 3
12 5 1 16 5
13* 0 0 16 6
• ’Precedence’ AoN-diagram:
Figuur A.2: Precedence-relaties case 2 (Van Goubergen, 2001)
Omzetting naar Excel-input van de precedence-graph:
A.2 Case 2 105
Tabel A.7: Precedence-relaties van case 2 na SMED-1
1 2 3 4 6 12
1 5 12
1 8 11 12
1 9 13 12
1 10 12
• Machinedisjuncties:
Tabel A.8: Machine-disjuncties van case 2 na SMED-1
1 2 5
• CC = ∅
• CS = {(1, 2), (2, 3)}Input in Excel:
Tabel A.9: CS-set van case 2 na SMED-1
1 2 3
• DJ = ∅
A.2.2 Na SMED-stappen 2-3
• Aantal beschikbare werknemers:
Lmax = 2
• Taken en eigenschappen:
A.3 Case 3 106
Tabel A.10: Gegevens activiteiten van case 2 na SMED 2-3
Taak lengte Tj werknemers Lj releaseTime machine 1
1 7 1 1 1
2 12 1 1 1
3 1 1 1 1
4 8 0 1 1
5 2 1 16 2
6 6 1 1 1
7 4 1 16 4
8 2 1 16 5
9 4 1 16 6
10 10 1 16 7
11 6 1 16 3
12 5 1 16 5
13 7 0 16 6
• ’Precedence’ AoN-diagram:
idem als na SMED-stap 1
• Machinedisjuncties:
idem als na SMED-stap 1
• CC = ∅
• CS = {(1, 2), (2, 3)}
• DJ = ∅
A.3 Case 3
A.3.1 Na SMED-stap 1
• Aantal beschikbare werknemers:
Lmax = 11
• Taken en eigenschappen:
A.3 Case 3 107
Tabel A.11: Gegevens activiteiten van case 3Taak lengte Tj werknemers Lj releaseTime machine 1
1 2 1 1 1
3 2 1 11 8
4 7 1 11 7
5 1 1 11 7
6 13 1 11 7
7 12 1 11 7
8 12 1 11 7
11 1 1 11 8
12 1 1 11 7
13 1 1 11 8
14 1 1 1 0
15 1 1 11 8
18 9 1 4 3
20 14 1 8 4
22 1 1 11 8
23 2 1 11 8
24 3 1 11 8
25 3 1 11 8
26 2 1 11 8
27 5 1 11 8
28 1 1 11 8
29 4 1 11 8
30 2 1 11 8
31 1 1 11 8
32 1 1 11 8
33 2 1 11 8
34 1 1 11 7
36 1 1 1 1
37 14 1 1 1
40 1 1 11 6
45 3 1 11 8
48 1 1 1 1
49 2 1 1 1
50 2 1 1 1
51 2 1 1 1
52 1 1 11 7
53 17 1 11 7
54 8 1 11 7
55 18 1 11 7
56 3 1 11 7
64 6 1 4 3
66 1 1 4 3
68 1 1 4 3
69 3 1 4 3
71 1 1 4 3
81 3 1 1 1
83 7 1 1 1
84 5 1 8 4
86 30 1 4 3
90 2 1 1 1
94 3 1 1 1
96 58 1 1 1
97 1 1 1 1
105 61 1 1 1
117 6 1 1 1
119 5 1 1 1
121 5 1 1 1
123 2 1 1 1
125 2 1 1 1
129 17 1 11 7
130 9 1 11 7
131 7 1 11 7
132 18 1 11 7
133 9 1 11 7
138 24 1 11 5
139 19 1 11 6
156 21 1 11 5
157 10 1 11 6
A.3 Case 3 108
• ’Precedence’ AoN-diagram:
Figuur A.3: Precedence-relaties case 3 (Van Goubergen, 2001)
A.3 Case 3 109
Omzetting naar Excel-input van de precedence-graph:
Tabel A.12: Precedence-relaties van case 1 voor SMED-toepassing
1 94 96 51
1 105 51
1 117 119 121 123 125 90 81 50 37 36 48 49
37 97 83 51
83 49
64 66 68 69 71 86 18
68 84
156 40 157
156 139
138 40
129 130 131 132
52 53 54 55 56 133
4 5 6 7 8 12 34
55 8
3 22 11 13 15
23 24 25 26 27 28 29 30 31 32 33
24 45
• Machinedisjuncties:
Tabel A.13: Machine-disjuncties van case 3 na SMED-1
3 4
• CC = ∅
• CS = ∅
A.3 Case 3 110
• DJ : Op elke lijn van de excel-input vinden we een aantal taken die onderling
disjunct zijn:
Tabel A.14: Disjuncties (andere dan machinedisjuncties) van case 3 na SMED-1
1 36 37 48 49 50 81 90 117 119 121 123 125
40 157
4 5 6 7 8 12 34
23 24 25 26 27 28 29 30 31 32 33
JAVA-IMPLEMENTATIE SOURCECODE 111
Bijlage B
JAVA-implementatie sourcecode
B.1 Overzicht van de klassen
In onderstaande figuur (screenshot uit het programma ’BlueJ’, een freeware Java IDE),
wordt een overzicht gegeven van alle aangemaakte klasses en hun hierarchie/verbondenheid.
In de volgende secties wordt voor elke geımplementeerde klasse de sourcecode gegeven.
Figuur B.1: Overzicht van de klasse-structuur
B.2 Klasse ’Task’
1
B.2 Klasse ’Task’ 112
2/∗∗3∗ Een o b j e c t k l a s s e met a l l e r e l e v a n t e gegevens per ingevoerde a c t i v i t e i t .
4∗ Ook de timewindows worden in d i t o b j e c t t y p e bewaard .
5∗ Als c l a s s v a r i a b l e s ( gemeenschappe l i j k voor a l l e Task−o b j e c t e n ) wordt een l i j s t (
type ArrayList ) onderhouden waarin
6∗ a l l e taken in hun i n v o e r v o i l g o r d e g e s t o c k e e r d worden .
7∗8∗ @author J o r i s Apr i l
9∗ @version 1.0
10∗/11import java . u t i l . ArrayList ;
12import java . lang . Math ;
13import java . u t i l . Comparator ;
14import java . u t i l .Random ;
15import java . u t i l . Abs t r a c tCo l l e c t i on ;
16import java . u t i l . Co l l e c t i o n s ;
17
18
19public class Task implements Comparable {20
21public stat ic ArrayList<Task> l i j s t=new ArrayList<Task>() ;
22public stat ic int i n t e rva lBeg in =1;
23public stat ic int i n t e rva lE ind ;
24
25
26public int p r i o r i t e i t ;
27public int l ength ;
28public int hL ;
29public int sL ;
30public int sT ;
31public int sU ;
32public int hU;
33public ArrayList<Integer> resourceGebru ik=new ArrayList<Integer >() ;
34public int re leaseTime ;
35public int volgnummer ;
36public int [ ] machinenummers ;
37public int hu lpva r i abe l e ;
38public boolean s chedu l edFeas ib ly ;
39
40public int sLbackup ;
41public int sTbackup ;
42public int sUbackup ;
43public boolean scheduledFeas ib lyBackup ;
44
45public Task ( int volgnummer , int l ength , int Labor , int re leaseTime , int . . .
machinenummers ) {46
47this . l ength=length ;
48this . r e sourceGebru ik . add (new I n t eg e r ( Labor ) ) ;
49this . sT=−1;
50this . r e l easeTime=re leaseTime ;
51this . volgnummer=volgnummer ;
52this . machinenummers=machinenummers ;
53this . s chedu l edFeas ib ly=fa l se ;
54l i j s t . add ( this ) ;
55}56
57public void ve rhoogPro f i e l en ( ) {58for ( int i =0; i<Resource . l i j s t . s i z e ( ) ; i++){
B.2 Klasse ’Task’ 113
59for ( int j=this . sT−1 ; j < ( this . sT + this . l ength −1) ; j++){60
61
62int hulp=Resource . l i j s t . get ( i ) . p r o f i e l . g e tLeve l s ( ) [ j ]+ this . r e sourceGebru ik
. get ( i ) ;
63Resource . l i j s t . get ( i ) . p r o f i e l . g e tLeve l s ( ) [ j ]=hulp ;
64}65}66
67}68
69public void v e r l a a gP r o f i e l e n ( ) {70for ( int i =0; i<Resource . l i j s t . s i z e ( ) ; i++){71for ( int j=this . sT−1 ; j < ( this . sT + this . l ength −1) ; j++){72Resource . l i j s t . get ( i ) . p r o f i e l . g e tLeve l s ( ) [ j ]−=this . r e sourceGebru ik . get ( i ) ;
73}74}75}76
77public void unscheduleMetCycl i ( ) {78this . sT=−1;
79
80for ( Task i : Task . l i j s t ) {81i . sL=i . hL ;
82i . sU=i .hU;
83}84
85ArrayList<Task> Q=(ArrayList<Task>) Task . l i j s t . c l one ( ) ;
86
87while ( Q. s i z e ( ) != 0 ) {88Task f i r s tTa s k=Q. remove (0 ) ;
89int newEarly ;
90
91for (Lag i : Lag . l i j s t ) {92i f ( f i r s tTa s k == i . getTask1 ( ) ) {93i f ( f i r s tTa s k . sT == −1) {94newEarly= f i r s tTa s k . sL + i . getValue ( ) ;
95} else {96newEarly= f i r s tTa s k . sT + i . getValue ( ) ;
97}98i f ( newEarly > i . getTask2 ( ) . sL ) {99i . getTask2 ( ) . sL= newEarly ;
100Q. add ( i . getTask2 ( ) ) ;
101}102}103}104}105
106Q=(ArrayList<Task>) Task . l i j s t . c l one ( ) ;
107
108while ( Q. s i z e ( ) != 0 ) {109Task f i r s tTa s k=Q. remove (0 ) ;
110int newLate ;
111
112for (Lag i : Lag . l i j s t ) {113i f ( f i r s tTa s k == i . getTask2 ( ) ) {114i f ( f i r s tTa s k . sT == −1) {115newLate= f i r s tTa s k . sU − i . getValue ( ) ;
116} else {
B.2 Klasse ’Task’ 114
117newLate= f i r s tTa s k . sT − i . getValue ( ) ;
118}119
120i f ( newLate < i . getTask1 ( ) . sU) {121i . getTask1 ( ) . sU=newLate ;
122Q. add ( i . getTask1 ( ) ) ;
123}124
125}126}127}128}129
130
131public void s t a r t t i j dToew i j z en ( int t i j d I n t e r v a l ) {132this . sT=t i j d I n t e r v a l ;
133ArrayList<Task> successorsToUpdate= new ArrayList<Task>() ;
134
135for (Lag i : Lag . l i j s t ) {136i f ( this == i . getTask1 ( ) ) {137i . getTask2 ( ) . hu lpva r i abe l e = t i j d I n t e r v a l + i . getValue ( ) ;
138successorsToUpdate . add ( i . getTask2 ( ) ) ;
139}140}141sh r i nkSucc e s s o r s ( successorsToUpdate ) ;
142ArrayList<Task> predecessorsToUpdate = new ArrayList<Task>() ;
143
144for (Lag i : Lag . l i j s t ) {145i f ( this==i . getTask2 ( ) ) {146i . getTask1 ( ) . hu lpva r i abe l e=t i j d I n t e r v a l − i . getValue ( ) ;
147predecessorsToUpdate . add ( i . getTask1 ( ) ) ;
148}149}150sh r i nkPrede c e s s o r s ( predecessorsToUpdate ) ;
151}152
153public stat ic void sh r i nkSucc e s s o r s ( ArrayList<Task> toShr ink ) {154while ( toShr ink . s i z e ( ) != 0) {155Task f i r s tTa s k=toShr ink . remove (0 ) ;
156i f ( f i r s tTa s k . hu lpva r i abe l e > f i r s tTa s k . sL ) {157f i r s tTa s k . sL=f i r s tTa s k . hu lpva r i abe l e ;
158i f ( f i r s tTa s k . sT == −1){159for (Lag i : Lag . l i j s t ) {160i f ( f i r s tTa s k == i . getTask1 ( ) ) {161i f ( toShr ink . conta in s ( i . getTask2 ( ) ) ) {162i . getTask2 ( ) . hu lpva r i abe l e = Math .max( i . getTask2 ( ) .
hu lpva r i abe l e , f i r s tTa s k . hu lpva r i abe l e + i . getValue ( )
) ;
163} else {164toShr ink . add ( i . getTask2 ( ) ) ;
165}166}167}168}169}170}171}172
173public stat ic void sh r i nkPrede c e s s o r s ( ArrayList<Task> toShr ink ) {
B.2 Klasse ’Task’ 115
174while ( toShr ink . s i z e ( ) != 0) {175Task f i r s tTa s k=toShr ink . remove (0 ) ;
176i f ( f i r s tTa s k . hu lpva r i abe l e < f i r s tTa s k . sU) {177f i r s tTa s k . sU = f i r s tTa s k . hu lpva r i abe l e ;
178i f ( f i r s tTa s k . sT == −1){179for (Lag i : Lag . l i j s t ) {180i f ( f i r s tTa s k == i . getTask2 ( ) ) {181i f ( toShr ink . conta in s ( i . getTask1 ( ) ) ) {182i . getTask1 ( ) . hu lpva r i abe l e = Math . min ( i . getTask1 ( ) .
hu lpva r i abe l e , f i r s tTa s k . hu lpva r i abe l e − i . getValue ( )
) ;
183} else {184toShr ink . add ( i . getTask1 ( ) ) ;
185}186}187}188}189}190}191}192
193public stat ic void zetHor izon ( int a an t a lT i j d s i n t e r v a l l e n ) {194in t e rva lBeg in =1;
195in t e rva lE ind=aan t a lT i j d s i n t e r v a l l e n ;
196Resource . updatePro f i l e sForHor i zon ( a an t a lT i j d s i n t e r v a l l e n ) ;
197}198
199public stat ic boolean checkHardWindows ( ) {200boolean f l a g=true ;
201for (Task i : Task . l i j s t ) {202i f ( i . hL > i . hU) {203f l a g=fa l se ; return f l a g ;
204}205}206return f l a g ;
207}208
209public stat ic boolean w ind ow I n i t i a l i s a t i e ( ) {210
211i f ( ! checkHardWindows ( ) ) {212return fa l se ;
213}214
215for (Task i : Task . l i j s t ) {216i . hL=Math .max( i . re leaseTime , i n t e rva lBeg in ) ;
217i .hU=inte rva lE ind−i . l ength +1;
218}219
220i f ( ! checkHardWindows ( ) ) {221return fa l se ;
222}223
224ArrayList<Task> Q=(ArrayList<Task>) Task . l i j s t . c l one ( ) ;
225while ( Q. s i z e ( ) !=0 && checkHardWindows ( ) ) {226Task f i r s tTa s k=Q. remove (0 ) ;
227
228for (Lag i : Lag . l i j s t ) {229i f ( f i r s tTa s k == i . getTask1 ( ) ) {230int newEarly=f i r s tTa s k . hL + i . va lue ;
B.2 Klasse ’Task’ 116
231i f ( newEarly > i . getTask2 ( ) . hL) {232i . getTask2 ( ) . hL=newEarly ;
233Q. add ( i . getTask2 ( ) ) ;
234}235}236}237}238
239i f ( ! checkHardWindows ( ) ) {240return fa l se ;
241}242
243Q=(ArrayList<Task>) Task . l i j s t . c l one ( ) ;
244
245while ( Q. s i z e ( ) !=0 && checkHardWindows ( ) ) {246Task f i r s tTa s k=Q. remove (0 ) ;
247
248for (Lag i : Lag . l i j s t ) {249i f ( f i r s tTa s k == i . getTask2 ( ) ) {250int newLate=f i r s tTa s k .hU − i . va lue ;
251i f ( newLate < i . getTask1 ( ) .hU) {252i . getTask1 ( ) .hU=newLate ;
253Q. add ( i . getTask1 ( ) ) ;
254}255}256}257}258i f ( ! checkHardWindows ( ) ) {259return fa l se ;
260}261for (Task i : Task . l i j s t ) {262i . sL=i . hL ;
263i . sU=i .hU;
264}265return true ;
266}267
268public boolean checkResourceFeas ib l e ( int kand idaatStar tTi jd ) {269
270for ( int i =0; i<Resource . l i j s t . s i z e ( ) ; i++){271for ( int j=kandidaatStartTi jd−1 ; j < ( kand idaatStar tTi jd + this . l ength −1) ; j
++){272i f ( Resource . l i j s t . get ( i ) . p r o f i e l . g e tLeve l s ( ) [ j ]+ this . r e sourceGebru ik . get ( i
) . intValue ( )>Resource . l i j s t . get ( i ) . capac i ty ) {273return fa l se ;
274}275}276}277return true ;
278}279
280public boolean schedu le ( ) {281
282int hu l p t i j d=−1;
283for ( int i=this . sL ; i<=this . sU ; i++) {284i f ( this . checkResourceFeas ib l e ( i ) ) {285hu l p t i j d=i ;
286break ;
287}
B.2 Klasse ’Task’ 117
288}289i f ( hu l p t i j d == −1){290this . s t a r t t i j dToew i j z en ( this . sL ) ;
291this . s chedu l edFeas ib ly=fa l se ;
292return fa l se ;
293} else {294this . s t a r t t i j dToew i j z en ( hu l p t i j d ) ;
295this . v e rhoogPro f i e l en ( ) ;
296this . s chedu l edFeas ib ly=true ;
297return true ;
298}299
300}301
302public int compareTo ( Object task2 ) throws ClassCastExcept ion {303i f ( ! ( task2 instanceof Task ) )
304throw new ClassCastExcept ion ( ”A Task ob j e c t expected . ” ) ;
305int task2volgnummer = ( ( Task ) task2 ) . volgnummer ;
306return this . volgnummer − task2volgnummer ;
307}308
309public stat ic Comparator p r i o r i t e i tCompara to r = new Comparator ( ) {310public int compare ( Object task1 , Object task2 ) throws ClassCastExcept ion {311i f ( ! ( ( task1 instanceof Task )&&(task2 instanceof Task ) ) )
312throw new ClassCastExcept ion ( ”Two Task ob j e c t s expected . ” ) ;
313
314int p r i o r i t e i t 1 = ( ( Task ) task1 ) . p r i o r i t e i t ;
315int p r i o r i t e i t 2 = ( ( Task ) task2 ) . p r i o r i t e i t ;
316
317return p r i o r i t e i t 2 −p r i o r i t e i t 1 ;
318}319} ;320
321public stat ic int bepaalMakespan ( ) {322int makespan=−1;
323boolean a l l s c h edu l ed=true ;
324for (Task i : Task . l i j s t ) {325i f ( i . sT==−1){326a l l s c h edu l ed=fa l se ;
327} else i f ( i . sT+i . length−1 > makespan ) {328makespan = i . sT+i . length −1;
329}330}331i f ( a l l s c h edu l ed ) {332return makespan ;
333} else {334return −1;
335}336}337
338public stat ic int zoekMinimaleHorizon ( ) {339int t e l l e r =0;
340do {341t e l l e r ++;
342Task . resetWindows ( ) ;
343Task . zetHor izon ( t e l l e r ) ;
344} while ( ! Task . w i n d ow I n i t i a l i s a t i e ( ) ) ;
345return t e l l e r ;
346}
B.2 Klasse ’Task’ 118
347
348public stat ic void resetWindows ( ) {349for (Task i : Task . l i j s t ) {350i . hL=0;
351i .hU=0;
352i . sL=0;
353i . sU=0;
354}355}356
357public stat ic void r e s e tA l lTask s ( ) {358for (Task i : Task . l i j s t ) {359i . hL=0;
360i .hU=0;
361i . sL=0;
362i . sU=0;
363i . sT=−1;
364i . s chedu l edFeas ib ly=fa l se ;
365i . sTbackup=0;
366i . sLbackup=0;
367i . sUbackup=0;
368i . scheduledFeas ib lyBackup=fa l se ;
369}370}371
372public stat ic void i n i t i a l i s e e r P r i o r i t e i t e n ( ) {373int maxhU=0;
374for (Task i : Task . l i j s t ) {375i f ( i .hU > maxhU) {376maxhU=i .hU;
377}378}379for (Task i : Task . l i j s t ) {380i . p r i o r i t e i t=maxhU−i . hU;
381}382
383Co l l e c t i o n s . s o r t (Task . l i j s t , Task . p r i o r i t e i tCompara to r ) ;
384int t e l l e r=Task . l i j s t . s i z e ( ) ;
385for (Task i : Task . l i j s t ) {386i . p r i o r i t e i t=t e l l e r ;
387t e l l e r −−;
388}389}390
391public stat ic void upda t eP r i o r i t e i t e n ( ) {392int increment =1;
393for (Task i : Task . l i j s t ) {394i f ( i . p r i o r i t e i t > increment ) { increment =i . p r i o r i t e i t ; } ;
395}396
397for (Task i : Task . l i j s t ) {398i f ( ! i . s chedu l edFeas ib ly ) {399i . p r i o r i t e i t+= increment ;
400}401}402Co l l e c t i o n s . s o r t (Task . l i j s t , Task . p r i o r i t e i tCompara to r ) ;
403int t e l l e r=Task . l i j s t . s i z e ( ) ;
404for (Task i : Task . l i j s t ) {405i . p r i o r i t e i t=t e l l e r ;
B.2 Klasse ’Task’ 119
406t e l l e r −−;
407}408
409Random randomGenerator=new Random( ) ;
410
411for (Task i : Task . l i j s t ) {412i f ( i . s chedu l edFeas ib ly ) {413int j= randomGenerator . next Int (10) ;
414i f ( j==0) {415i . p r i o r i t e i t+= 2 ;
416}417}418}419Co l l e c t i o n s . s o r t (Task . l i j s t , Task . p r i o r i t e i tCompara to r ) ;
420t e l l e r=Task . l i j s t . s i z e ( ) ;
421for (Task i : Task . l i j s t ) {422i . p r i o r i t e i t=t e l l e r ;
423t e l l e r −−;
424}425}426
427public stat ic Task lookupVolgnummer ( int nummer) {428for (Task i : Task . l i j s t ) {429i f ( i . volgnummer == nummer) {430return i ;
431}432}433return null ;
434}435
436public stat ic void takeBackup ( ) {437for (Task i : Task . l i j s t ) {438i . sLbackup=i . sL ;
439i . sTbackup=i . sT ;
440i . sUbackup=i . sU ;
441i . scheduledFeas ib lyBackup=i . s chedu l edFeas ib ly ;
442}443for ( Resource i : Resource . l i j s t ) {444i . p r o f i e l . backupLevels ( ) ;
445}446}447
448public stat ic void restoreBackup ( ) {449for (Task i : Task . l i j s t ) {450i . sL=i . sLbackup ;
451i . sT=i . sTbackup ;
452i . sU=i . sUbackup ;
453i . s chedu l edFeas ib ly=i . scheduledFeas iblyBackup ;
454}455for ( Resource i : Resource . l i j s t ) {456i . p r o f i e l . r e s t o r eL e v e l s ( ) ;
457}458
459}460
461public stat ic void r e f i l l G r o e p ( ArrayList<Task> bu l ldozedSet ) {462
463Task . takeBackup ( ) ;
464int maximumShift=in t e rva lE ind ;
B.2 Klasse ’Task’ 120
465
466for ( int i =0; i<Resource . l i j s t . s i z e ( ) ; i++){467Resource . l i j s t . get ( i ) . hu l pP r o f i e l=new UsagePro f i l e (Task . i n t e rva lE ind ) ;
468for (Task j : bu l ldozedSet ) {469for ( int k=j . sT−1 ; k<j . sT+j . length−1 ; k++){470Resource . l i j s t . get ( i ) . hu l pP r o f i e l . g e tLeve l s ( ) [ k]+=j .
resourceGebru ik . get ( i ) ;
471}472}473}474
475for (Task i : bu l ldozedSet ) {476i f ( i . s chedu l edFeas ib ly ) {477i . v e r l a a gP r o f i e l e n ( ) ;
478}479i . sT=−1;
480i . s chedu l edFeas ib ly=fa l se ;
481}482
483for ( Task i : Task . l i j s t ) {484i . sL=i . hL ;
485i . sU=i .hU;
486}487
488ArrayList<Task> Q=(ArrayList<Task>) Task . l i j s t . c l one ( ) ;
489while ( Q. s i z e ( ) != 0 ) {490Task f i r s tTa s k=Q. remove (0 ) ;
491int newEarly ;
492
493for (Lag i : Lag . l i j s t ) {494i f ( f i r s tTa s k == i . getTask1 ( ) ) {495i f ( f i r s tTa s k . sT == −1) {496newEarly= f i r s tTa s k . sL + i . getValue ( ) ;
497} else {498newEarly= f i r s tTa s k . sT + i . getValue ( ) ;
499}500i f ( newEarly > i . getTask2 ( ) . sL ) {501i . getTask2 ( ) . sL= newEarly ;
502Q. add ( i . getTask2 ( ) ) ;
503}504}505}506}507
508Q=(ArrayList<Task>) Task . l i j s t . c l one ( ) ;
509while ( Q. s i z e ( ) != 0 ) {510Task f i r s tTa s k=Q. remove (0 ) ;
511int newLate ;
512
513for (Lag i : Lag . l i j s t ) {514i f ( f i r s tTa s k == i . getTask2 ( ) ) {515i f ( f i r s tTa s k . sT == −1) {516newLate= f i r s tTa s k . sU − i . getValue ( ) ;
517} else {518newLate= f i r s tTa s k . sT − i . getValue ( ) ;
519}520
521i f ( newLate < i . getTask1 ( ) . sU) {522i . getTask1 ( ) . sU=newLate ;
B.2 Klasse ’Task’ 121
523Q. add ( i . getTask1 ( ) ) ;
524}525
526}527}528}529
530for (Task i : bu l ldozedSet ) {531i f ( ( i . sTbackup−i . sL<maximumShift ) ) {532maximumShift=i . sTbackup−i . sL ;
533}534}535
536for ( int m=maximumShift ; m>=0 ; m−−){537i f (m==0){538Task . restoreBackup ( ) ;
539break ;
540}541boolean r e s ou r c eFea s i b l e=true ;
542
543oute r l oop :
544for ( Resource i : Resource . l i j s t ) {545for ( int j=0 ; j<=Task . in te rva lE ind−1−m ; j++){546i f ( i . p r o f i e l . g e tLeve l s ( ) [ j ]+ i . hu l pP r o f i e l . g e tLeve l s ( ) [ j+m]> i .
capac i ty ) {547r e s ou r c eFea s i b l e=fa l se ;
548break oute r l oop ;
549}550}551}552
553i f ( r e s ou r c eFea s i b l e ) {554for (Task i : bu l ldozedSet ) {555i . s t a r t t i j dToew i j z e n ( i . sTbackup−m) ;
556i . v e rhoogPro f i e l en ( ) ;
557i . s chedu l edFeas ib ly=true ;
558}559break ;
560}561}562}563
564public stat ic void r e f i l l I n d i v i d u e e l ( ) {565for (Task i : Task . l i j s t ) {566Task . takeBackup ( ) ;
567i f ( i . sT!=−1){568i f ( i . s chedu l edFeas ib ly ) {569i . v e r l a a gP r o f i e l e n ( ) ;
570}571i . unscheduleMetCycl i ( ) ;
572i f ( ! i . s chedu le ( ) ) {573Task . restoreBackup ( ) ;
574}575}576}577}578
579public boolean scheduleMetBul ldoz ing ( ) {580ArrayList<Task> x= new ArrayList<Task>() ;
B.2 Klasse ’Task’ 122
581x . add ( this ) ;
582Task . takeBackup ( ) ;
583
584boolean r e v e r tT o I n i t i a l=fa l se ;
585
586while ( ! x . isEmpty ( ) ) {587Random randomGenerator = new Random( ) ;
588Task hulp=x . remove ( randomGenerator . next Int ( x . s i z e ( ) ) ) ;
589i f ( hulp . sT !=−1){590i f ( hulp . s chedu l edFeas ib ly=true ) {591hulp . v e r l a a gP r o f i e l e n ( ) ;
592hulp . s chedu l edFeas ib ly=fa l se ;
593}594hulp . unscheduleMetCycl i ( ) ;
595hulp . s chedu l edFeas ib ly=fa l se ;
596}597int hu l p t i j d=−1;
598
599for ( int k=hulp . sL ; k<=hulp .hU ; k++) {600i f ( hulp . checkResourceFeas ib l e ( k ) ) {601hu l p t i j d=k ;
602break ;
603}604}605i f ( hu l p t i j d == −1){606r e v e r tT o I n i t i a l=true ;
607break ;
608} else i f ( hu l p t i j d <=hulp . sU) {609hulp . s t a r t t i j dToew i j z e n ( hu l p t i j d ) ;
610hulp . v e rhoogPro f i e l en ( ) ;
611hulp . s chedu l edFeas ib ly=true ;
612} else {613hulp . s t a r t t i j dToew i j z e n ( hu l p t i j d ) ;
614hulp . v e rhoogPro f i e l en ( ) ;
615hulp . s chedu l edFeas ib ly=true ;
616
617for (Lag m: Lag . l i j s t ) {618i f (m. getTask1 ( )==hulp && m. getTask2 ( ) . sT!=1){619i f ( (m. getTask2 ( ) . sT−hulp . sT)<m. getValue ( ) ) {620i f ( ! x . conta in s (m. getTask2 ( ) ) ) {x . add (m. getTask2 ( ) ) ;}621}622}623i f (m. getTask2 ( )==hulp && m. getTask1 ( ) . sT!=1){624i f ( ( hulp . sT−m. getTask1 ( ) . sT)<m. getValue ( ) ) {625i f ( ! x . conta in s (m. getTask1 ( ) ) ) {x . add (m. getTask1 ( ) ) ;}626}627}628}629}630}631
632i f ( r e v e r tTo I n i t i a l ) {633Task . restoreBackup ( ) ;
634this . s t a r t t i j dToew i j z en ( this . sL ) ;
635// t h i s . v e r h o o g P r o f i e l e n () ;
636this . s chedu l edFeas ib ly=fa l se ;
637return fa l se ;
638} else {639return true ;
B.2 Klasse ’Task’ 123
640}641}642
643public boolean s chedu l eMetBu l l do z ingRe f i l l i n g ( ) {644ArrayList<Task> x= new ArrayList<Task>() ;
645ArrayList<Task> bu l ldozedSet= new ArrayList<Task>() ;
646x . add ( this ) ;
647bu l ldozedSet . add ( this ) ;
648Task . takeBackup ( ) ;
649boolean r e v e r tT o I n i t i a l=fa l se ;
650
651do {652Random randomGenerator = new Random( ) ;
653Task hulp=x . remove ( randomGenerator . next Int ( x . s i z e ( ) ) ) ;
654i f ( hulp . sT !=−1){655i f ( hulp . s chedu l edFeas ib ly ) {656hulp . v e r l a a gP r o f i e l e n ( ) ;
657hulp . s chedu l edFeas ib ly=fa l se ;
658}659hulp . unscheduleMetCycl i ( ) ;
660}661
662int hu l p t i j d=−1;
663
664for ( int k=hulp . sL ; k<=hulp .hU ; k++) {665i f ( hulp . checkResourceFeas ib l e ( k ) ) {666hu l p t i j d=k ;
667break ;
668}669}670
671i f ( hu l p t i j d == −1){672r e v e r tT o I n i t i a l=true ;
673break ;
674} else i f ( hu l p t i j d <=hulp . sU) {675hulp . s t a r t t i j dToew i j z e n ( hu l p t i j d ) ;
676hulp . v e rhoogPro f i e l en ( ) ;
677hulp . s chedu l edFeas ib ly=true ;
678} else {679hulp . s t a r t t i j dToew i j z e n ( hu l p t i j d ) ;
680hulp . v e rhoogPro f i e l en ( ) ;
681hulp . s chedu l edFeas ib ly=true ;
682
683for (Lag m: Lag . l i j s t ) {684i f (m. getTask1 ( )==hulp && m. getTask2 ( ) . sT!=−1){685i f ( (m. getTask2 ( ) . sT−hulp . sT)<m. getValue ( ) ) {686i f ( ! x . conta in s (m. getTask2 ( ) ) ) {x . add (m. getTask2 ( ) ) ;}687i f ( ! bu l ldozedSet . conta in s (m. getTask2 ( ) ) ) {
bu l ldozedSet . add (m. getTask2 ( ) ) ;}688}689}690i f (m. getTask2 ( )==hulp && m. getTask1 ( ) . sT!=−1){691i f ( ( hulp . sT−m. getTask1 ( ) . sT)<m. getValue ( ) ) {692i f ( ! x . conta in s (m. getTask1 ( ) ) ) {x . add (m. getTask1 ( ) ) ;}693i f ( ! bu l ldozedSet . conta in s (m. getTask1 ( ) ) ) {
bu l ldozedSet . add (m. getTask1 ( ) ) ;}694}695}696}
B.3 Klasse ’Lag’ 124
697}698} while ( ! x . isEmpty ( ) ) ;
699
700i f ( r e v e r tTo I n i t i a l ) {701Task . restoreBackup ( ) ;
702this . s t a r t t i j dToew i j z en ( this . sL ) ;
703this . v e rhoogPro f i e l en ( ) ;
704this . s chedu l edFeas ib ly=fa l se ;
705return fa l se ;
706} else {707i f ( bu l ldozedSet . s i z e ( ) > 1) {708Task . r e f i l l G r o e p ( bu l ldozedSet ) ;
709Task . r e f i l l I n d i v i d u e e l ( ) ;
710}711return true ;
712}713}714
715public stat ic double bepaalF2 ( int makespan ) {716int t o t a l S l a c k =0;
717
718for ( int t e l l e r =0; t e l l e r < makespan ; t e l l e r++){719t o t a l S l a c k+=(LaborResource . pointerNaarLabor . capac i ty − LaborResource .
pointerNaarLabor . p r o f i e l . g e tLeve l s ( ) [ t e l l e r ] ) ;
720}721double averageS lack=to t a l S l a c k /( (double ) makespan ) ;
722double F2=0;
723
724for ( int t e l l e r =0; t e l l e r < makespan ; t e l l e r++){725F2+=Math . abs ( ( LaborResource . pointerNaarLabor . capac i ty − LaborResource .
pointerNaarLabor . p r o f i e l . g e tLeve l s ( ) [ t e l l e r ] )−averageS lack ) ;
726}727return F2 ;
728}729
730public stat ic int bepaalF3 ( int makespan ) {731int f 3 =0;
732for ( int t e l l e r =0; t e l l e r < makespan ; t e l l e r++){733int s l a ck=LaborResource . pointerNaarLabor . capac i ty−LaborResource .
pointerNaarLabor . p r o f i e l . g e tLeve l s ( ) [ t e l l e r ] ;
734int f a c t o r =((makespan−t e l l e r −1)∗( LaborResource . pointerNaarLabor . capac i ty+1) )
+1;
735f3+=(s l a ck ∗ f a c t o r ) ;
736}737return f 3 ;
738}739
740}
B.3 Klasse ’Lag’
1/∗∗2∗ Klasse Lag s t o c k e e r t in f e i t e zowel de minimale a l s de maximale ( v ia i n v e r s i e ) l a g s
d ie vo lgen u i t de
3∗ concurrence , precedence en c o n s e c u t i v e c o n t r a i n t s ( deze worden ingevoerd met de
methodes van de k l a s s e ’ c o n s t r a i n t s ’ ) .
4∗ Deze methodes roepen e i g e n l i j k gewoon de c o n s t r u c t o r s op voor de b i j b e h o r e n d e l a g ( s
) .
B.4 Klasse ’Constraints’ 125
5∗ Een maximale l a g ( bvb t a s k 1 moet minstens 3 t i j d s s l o t s na t a s k 2 aanvangen ) i s
6∗ e q u i v a l e n t met een minimumlag in de andere r i c h t i n g ( task2 moet minstens ”−3”
t i j d s s l o t s voor task1 aanpassen ) .
7∗8∗ @author J o r i s Apr i l
9∗ @version 1.0
10∗/11
12import java . u t i l . ArrayList ;
13
14public class Lag
15{16public stat ic ArrayList<Lag> l i j s t=new ArrayList<Lag>() ;
17
18protected Task task1 ;
19protected Task task2 ;
20protected int value ;
21
22public Task getTask1 ( ) {23return task1 ;
24}25
26public Task getTask2 ( ) {27return task2 ;
28}29
30public int getValue ( ) {31return value ;
32}33
34public Lag (Task task1 , Task task2 , int l ag )
35{36this . task1=task1 ;
37this . task2=task2 ;
38this . va lue=lag ;
39l i j s t . add ( this ) ;
40}41
42public stat ic void addCC(Task task1 , Task task2 ) {43new Lag ( task1 , task2 , 0 ) ;
44new Lag ( task2 , task1 , 0 ) ;
45
46}47
48public stat ic void addCS(Task task1 , Task task2 ) {49new Lag ( task1 , task2 , task1 . l ength ) ;
50new Lag ( task2 , task1 ,− task1 . l ength ) ;
51
52}53
54public stat ic void addPD(Task task1 , Task task2 ) {55new Lag ( task1 , task2 , task1 . l ength ) ;
56
57}58}
B.4 Klasse ’Constraints’
B.4 Klasse ’Constraints’ 126
1/∗∗2∗ This c l a s s hasn ’ t go t any f i e l d s / v a r i a b l e s , j u s t methods t h a t c r e a t e l a g s and
d i s j u n c t i v e ’ f i c t i t i o u s ’ re sources based on
3∗ consecut ive , concurrent , d i s j u n c t i v e and precedence c o n s t r a i n t s put in through the
parameter l i s t . I t thus adapts t h e s e f o u t t y p e s o f c o n s t r a i n t s f o r use
4∗ in the RCPSP/max problem .
5∗ The a c t u a l Lags and Resources are c r e a t e s by invok ing the c o n s t r u c t o r s o f c l a s s e s ’
Lag ’ , ’ FictResource ’ , ’ MachineResource ’ .
6∗7∗8∗ @author J o r i s Apr i l
9∗ @version 1.0
10∗/11
12
13public class Const ra in t s
14{15
16
17public stat ic void addCC(Task task1 , Task task2 ) {18new Lag ( task1 , task2 , 0 ) ;
19new Lag ( task2 , task1 , 0 ) ;
20}21
22public stat ic void addCC( int . . . taken ) {23for ( int i=0 ; i<taken . length−1 ; i++){24new Lag (Task . lookupVolgnummer ( taken [ i ] ) , Task . lookupVolgnummer ( taken [ i +1])
, 0 ) ;
25new Lag (Task . lookupVolgnummer ( taken [ i +1]) , Task . lookupVolgnummer ( taken [ i ] )
, 0 ) ;
26}27}28
29public stat ic void addCS(Task task1 , Task task2 ) {30new Lag ( task1 , task2 , task1 . l ength ) ;
31new Lag ( task2 , task1 ,− task1 . l ength ) ;
32}33
34public stat ic void addCS( int . . . taken ) {35for ( int i=0 ; i<taken . length−1 ; i++){36new Lag (Task . lookupVolgnummer ( taken [ i ] ) , Task . lookupVolgnummer ( taken [ i +1]) ,
Task . lookupVolgnummer ( taken [ i ] ) . l ength ) ;
37new Lag (Task . lookupVolgnummer ( taken [ i +1]) , Task . lookupVolgnummer ( taken [ i ] )
,−Task . lookupVolgnummer ( taken [ i ] ) . l ength ) ;
38}39}40
41public stat ic void addPD(Task . . . taken ) {42for ( int i=0 ; i<taken . length−1 ; i++){43new Lag ( taken [ i ] , taken [ i +1] , taken [ i ] . l ength ) ;
44}45}46
47public stat ic void addPD( int . . . taken ) {48for ( int i=0 ; i<taken . length−1 ; i++){49new Lag (Task . lookupVolgnummer ( taken [ i ] ) , Task . lookupVolgnummer ( taken [ i +1]) ,
Task . lookupVolgnummer ( taken [ i ] ) . l ength ) ;
50}51}
B.5 De ’abstracte’ klasse ’Resource’ 127
52
53public stat ic void addDJ( int . . . takennummers ) {54
55Task [ ] taken=new Task [ takennummers . l ength ] ;
56for ( int i =0; i<takennummers . l ength ; i++){57taken [ i ]=Task . lookupVolgnummer ( takennummers [ i ] ) ;
58}59new FictResource ( taken ) ;
60}61
62public stat ic void addDJ(Task . . . taken ) {63new FictResource ( taken ) ;
64}65
66public stat ic void addMachineDisjunction ( int machineNummer ) {67new MachineResource (machineNummer) ;
68}69
70}
B.5 De ’abstracte’ klasse ’Resource’
1/∗∗2∗ Abstrac t c l a s s Resource − Overkoepelende a b s t r a c t c l a s s voor zowel de
3∗ ech te resources ( k l a s s e ’ Labor ’) , de f i c t i e v e resources ingevoerd voor p a i r w i s e
d i s j u n c t i e v e c o n s t r a i n t s ( k l a s s e ’ FictResource ’)
4∗ en machine−d i s j u n c t i e s ( k l a s s e ’ MachineResource ’) .
5∗ Deze a b s t r a c t c l a s s l e g t de ve lden v a s t d ie e l k Resource−o b j e c t van de
implementerende s u b k l a s s e s moet hebben , en l a g t ook een ’ r e s o u r c e l i j s t ’ aan a l s
s t a t i s c h e v a r i a b e l e ,
6∗ d ie a l l e aangemaakte resources beva t ( in hun aanmaakvolgorde ) .
7∗8∗ @author J o r i s Apr i l
9∗ @version 1.0
10∗/11
12import java . u t i l . ArrayList ;
13
14public abstract class Resource
15{16public stat ic ArrayList<Resource> l i j s t=new ArrayList<Resource >() ;
17
18public int capac i ty ;
19public UsagePro f i l e p r o f i e l ;
20public UsagePro f i l e hu l pP r o f i e l ;
21
22public stat ic void updatePro f i l e sForHor i zon ( int a an t a lT i j d s i n t e r v a l l e n ) {23for ( Resource i : Resource . l i j s t ) {24i . p r o f i e l = new UsagePro f i l e ( a a n t a lT i j d s i n t e r v a l l e n ) ;
25}26}27}
B.6 De klasse ’FictResource’ (modelleren van dis-
juncties)
B.7 De klasse ’MachineResource’ (modelleren van machine-disjuncties) 128
1
2/∗∗3∗ FictResource Class maakt , a l s e x t e n s i e van de a b s t r a c t c l a s s Resource ,
4∗ a l l e f i c t i e v e resource−o b j e c t e n aan d ie overeenstemmen met d i s j u n c t i e v e s e t s van
twee o f meer a c t i v i t e i t e n ( ’ Task’− o b j e c t e n ) . Elke gecre e e rde
5∗ f i c t i e v e resource h e e f t een c a p a c i t e i t 1 . Bi j he t aanmaken wordt voor e l k e Task in
de d i s j u n c t i e v e s e t een ’1 ’ b i j g e v o e g d in de l i j s t resourceGebruik
6∗ van d ie Task , voor a l l e andere Tasks woordt b i j d e corresponderende l i j s t een nul
toegevoegd .
7∗8∗ @author J o r i s Apr i l
9∗ @version 1.0
10∗/11
12import java . u t i l . ArrayList ;
13
14public class FictResource extends Resource
15{16
17public FictResource (Task . . . d i s j unc t i v eTask s )
18{19// i n i t i a l i s e ins tance v a r i a b l e s
20this . capac i ty =1;
21for (Task i : Task . l i j s t ) {22int gebru ik =0;
23for ( int j =0; j<d i s junc t i v eTask s . l ength ; j++){24i f ( d i s j unc t i v eTask s [ j ]== i ) {25gebru ik =1;
26}27}28i . resourceGebru ik . add (new I n t eg e r ( gebru ik ) ) ;
29
30}31l i j s t . add ( this ) ;
32this . p r o f i e l=new UsagePro f i l e (Task . i n t e rva lE ind − Task . i n t e rva lBeg in +1 ) ;
33}34}
B.7 De klasse ’MachineResource’ (modelleren van
machine-disjuncties)
1
2/∗∗3∗ Hier vinden we de machines a l s resources t e rug met c a p a c i t e i t 1 , d i t i s met name het
g e v a l voor de machines waarb i j a l l e a c t i v i t e i t e n d i s j u n c t i e f z i j n
4∗ ( dus mutual ly e x c l u s i v e : s l e c h t s aan 1 a c t i v i t e i t t e g e l i j k werken ) . De c a p a c i t e i t
i s dus 1 .
5∗ Als argument b i j de c o n s t r u c t o r wordt e n k e l he t machinenummer ( i n t ) opgegeven ,
v e r v o l g e n s kunnen de t a s k s opgezocht worden d ie
6∗ op deze machine u i t g e v o e r d worden ( e l k e t a s k h e e f t een v e l d t a s k . machinenummers
waarin de machinenummers a l s i n t [ ] ( array van i n t e g e r s ) g e s t o c k e e r d wordt . )
7∗8∗ @author J o r i s Apr i l
9∗ @version 1.0
10∗/11
B.8 De klasse ’LaborResource’ (modelleren van Lmax) 129
12
13public class MachineResource extends Resource
14{15public MachineResource ( int machinenr )
16{17this . capac i ty =1;
18for (Task i : Task . l i j s t ) {19int gebru ik =0;
20for ( int j =0; j<i . machinenummers . l ength ; j++){21i f ( machinenr==i . machinenummers [ j ] ) {22gebru ik =1; break ;
23}24}25i . resourceGebru ik . add (new I n t eg e r ( gebru ik ) ) ;
26}27
28l i j s t . add ( this ) ;
29}30}
B.8 De klasse ’LaborResource’ (modelleren van Lmax)
1/∗∗2∗ LaborResource Class houdt , a l s e x t e n s i e van de a b s t r a c t c l a s s Resource , de
c a p a c i t e i t b i j van de labour en een r e c h t s r e e k s e p o i n t e r naar
3∗ het aangemaakte resource−o b j e c t , om het l a t e r t e kunnen traceren , d i t i s een
ArrayList d i e a l l e t a a k o b j e c t e n beva t . De labor−resource d i e n t a l s a l l e r e e r s t e
4∗ t e worden aangemaakt , omdat de Task−c o n s t r u c t o r in de l i j s t resourceGebruik van
e l k e Task onmidde l i j k he t aanta l benodige werknemers w e g s c h r i j f t . Deze index nul
moet ook de index worden
5∗ van de aangemaakte resource in de Resource . l i j s t −s t o c k e r i n g .
6∗7∗ @author J o r i s Apr i l
8∗ @version 1.0
9∗/10
11
12public class LaborResource extends Resource
13{14
15public stat ic LaborResource pointerNaarLabor ;
16
17public LaborResource ( int capac i ty )
18{19this . capac i ty=capac i ty ;
20l i j s t . add ( this ) ;
21pointerNaarLabor=this ;
22this . p r o f i e l=new UsagePro f i l e (Task . i n t e rva lE ind − Task . i n t e rva lBeg in +1 ) ;
23}24}
B.9 De klasse ’LaborResource’ (modelleren van Lmax)
1/∗∗2∗ LaborResource Class houdt , a l s e x t e n s i e van de a b s t r a c t c l a s s Resource , de
c a p a c i t e i t b i j van de labour en een r e c h t s r e e k s e p o i n t e r naar
B.10 Klasse ’UsageProfile’ 130
3∗ het aangemaakte resource−o b j e c t , om het l a t e r t e kunnen traceren , d i t i s een
ArrayList d i e a l l e t a a k o b j e c t e n beva t . De labor−resource d i e n t a l s a l l e r e e r s t e
4∗ t e worden aangemaakt , omdat de Task−c o n s t r u c t o r in de l i j s t resourceGebruik van
e l k e Task onmidde l i j k he t aanta l benodige werknemers w e g s c h r i j f t . Deze index nul
moet ook de index worden
5∗ van de aangemaakte resource in de Resource . l i j s t −s t o c k e r i n g .
6∗7∗ @author J o r i s Apr i l
8∗ @version 1.0
9∗/10
11
12public class LaborResource extends Resource
13{14
15public stat ic LaborResource pointerNaarLabor ;
16
17public LaborResource ( int capac i ty )
18{19this . capac i ty=capac i ty ;
20l i j s t . add ( this ) ;
21pointerNaarLabor=this ;
22this . p r o f i e l=new UsagePro f i l e (Task . i n t e rva lE ind − Task . i n t e rva lBeg in +1 ) ;
23}24}
B.10 Klasse ’UsageProfile’
1
2/∗∗3∗ Houdt een int−array b i j ( e v e n v e e l elementen a l s er t i j d s s l o t s z i j n in de
g e i n i t i a l i s e e r d e hor izon ) , met het r e s o u r c e g e b r u i k per t i j d d s l o t overeenkomst ig
de toegewezen a c t i v i t e i t e n .
4∗ Ook de backup−v a r i a b e l e om na b u l l d o z i n g t e kunnen backtracken wordt a l s v e l d van
het o b j e c t ’ UsagePro f i l e ’ g e ı n i t i a l i s e e r d . Met e l k ’ Resource ’− o b j e c t stemt
5∗ dan n a t u u r l i j k een ’ UsagePro f i l e ’− o b j e c t overeen .
6∗7∗ @author J o r i s Apr i l
8∗ @version 1.0
9∗/10public class UsagePro f i l e
11{12private int [ ] l e v e l s ;
13private int [ ] l eve l sBackup ;
14
15public UsagePro f i l e ( int aan t a lT i j d I n t e r v a l )
16{17l e v e l s = new int [ a an t a lT i j d I n t e r v a l ] ;
18
19}20
21public int [ ] g e tLeve l s ( ) {22return l e v e l s ;
23}24
25public void backupLevels ( ) {26leve l sBackup=new int [ l e v e l s . l ength ] ;
27for ( int j =0; j< l e v e l s . l ength ; j++){
B.11 Klasse ’IOExcel’ (input-output-stockeren van de oplossingen 131
28leve l sBackup [ j ]= l e v e l s [ j ] ;
29}30}31
32public void r e s t o r eL e v e l s ( ) {33l e v e l s=leve l sBackup ;
34}35}
B.11 Klasse ’IOExcel’ (input-output-stockeren van
de oplossingen
1
2/∗∗3∗ Deze k l a s s e beva t a l l e s t r u c t u r e n waarin t i j d e n s de swo− i t e r a t i e s van het a lgor i tme
, de b e s t e f e a s i b l e s c h e d u l e s d ie gevonden werden
4∗ worden g e s t o c k e e r d . Verder worden een aanta l h u l p v a r i a b e l e n ingevoerd d ie b i j de
input vanui t MS−Excel worden g e ı n i t i e l i s e e r d en hun in format i e dan kunnen
5∗ doorgeven aan de e i g e n l i j k e u i t voer ingsmethodes van het a l gor i tme ( in de k l a s s e ’
Schedu l ingAlgor i tmes ’) .
6∗7∗ Het b e l a n g r i j k s t e z i j n n a t u u r l i j k de methodes leesData , d ie u i t de exce l− f i l e met
prob leemgegevens a l l e nodige date voor het u i t v o e r e n van de i t e r a t i e s z a l halen ,
8∗ n l . de keuze van de procedure , he t aanta l i t e r a t i e s en a l l e taakgegevens en
c o n s t r a i n t s .
9∗10∗ De procedure s c h r i j f D a t a N a a r F i l e ( ) s c h r i j f t dan a l l e g e s t o c k e e r d e f e a s i b l e
s c h e d u l e s naar een nieuw t a b b l a d ’ r e s u l t s ’ dat aangemaakt wordt in de bron−E x c e l f i l e .
11∗12∗ A l l e andere procedures z i j n hu lpprocedures voor het s tockeren van de gegevens
t i j d e n s de i t e r a t i e s . Het e i g e n l i j k e wegschr i j ven naar Exce l g e be u r t dan pas op
het einde van a l l e i t e r a t i e s ,
13∗ en op b a s i s van de in deze k l a s s e g e s t o c k e e r d e schedule−gegevens .
14∗15∗ Het open source java−package ’ JExcelApi ’ maakte het m o g e l i j k t e l e z e n en weg t e
s c h r i j v e n naar Excel . (www. teamdev . com)
16∗17∗ @author J o r i s Apr i l
18∗ @version 1.0
19∗/20
21import java . i o . F i l e ;
22import java . i o . ∗ ;
23import j x l . ∗ ;
24import java . u t i l . ∗ ;
25import j x l . Workbook ;
26import j x l . read . b i f f . ∗ ;
27import j x l . wr i t e . ∗ ;
28public class IOExcel
29{30
31public stat ic St r ing f i l ename ;
32public stat ic ArrayList<Task> weg s ch r i j f v o l g o rd e ;
33public stat ic ArrayList<int [ ]> s t o c k e e r s t a r t t i j d e n=new ArrayList<int [ ] > ( ) ;
34public stat ic ArrayList<Integer> s t o c k e e r f 1=new ArrayList<Integer >() ;
35public stat ic ArrayList<Double> s t o c k e e r f 2=new ArrayList<Double>() ;
B.11 Klasse ’IOExcel’ (input-output-stockeren van de oplossingen 132
36public stat ic ArrayList<Integer> s t o c k e e r f 3=new ArrayList<Integer >() ;
37public stat ic int procedurekeuze ;
38public stat ic int a a n t a l I t e r a t i e s ;
39public stat ic int ondergrens ;
40
41
42
43public stat ic void wisGestockeerdeResu l taten ( ) {44s t o c k e e r s t a r t t i j d e n . c l e a r ( ) ;
45s t o c k e e r f 1 . c l e a r ( ) ;
46s t o c k e e r f 2 . c l e a r ( ) ;
47s t o c k e e r f 3 . c l e a r ( ) ;
48}49
50public stat ic void s t o cke e rSchedu l e f 1 ( int f 1 ) {51
52int [ ] hu lparray=new int [ w e g s ch r i j f v o l g o rd e . s i z e ( ) ] ;
53for ( int i =0; i<hulparray . l ength ; i++){54hulparray [ i ]= weg s ch r i j f v o l g o rd e . get ( i ) . sT ;
55}56boolean reedsGevonden=fa l se ;
57i f ( ! s t o c k e e r s t a r t t i j d e n . isEmpty ( ) ) {58for ( int [ ] i : s t o c k e e r s t a r t t i j d e n ) {59i f ( Arrays . equa l s ( i , hulparray ) ) {60reedsGevonden=true ;
61break ;
62}63}64}65i f ( ! reedsGevonden ) {66s t o c k e e r s t a r t t i j d e n . add ( hulparray ) ;
67s t o c k e e r f 1 . add (new I n t eg e r ( f 1 ) ) ;
68}69}70
71public stat ic void s t o ck e e rS ch edu l e f 1 f 2 ( int f1 , double f 2 ) {72
73
74int [ ] hu lparray=new int [ w e g s ch r i j f v o l g o rd e . s i z e ( ) ] ;
75for ( int i =0; i<hulparray . l ength ; i++){76hulparray [ i ]= weg s ch r i j f v o l g o rd e . get ( i ) . sT ;
77}78boolean reedsGevonden=fa l se ;
79i f ( ! s t o c k e e r s t a r t t i j d e n . isEmpty ( ) ) {80for ( int [ ] i : s t o c k e e r s t a r t t i j d e n ) {81i f ( Arrays . equa l s ( i , hulparray ) ) {82reedsGevonden=true ;
83break ;
84}85}86}87i f ( ! reedsGevonden ) {88s t o c k e e r s t a r t t i j d e n . add ( hulparray ) ;
89s t o c k e e r f 1 . add (new I n t eg e r ( f 1 ) ) ;
90s t o c k e e r f 2 . add (new Double ( f 2 ) ) ;
91}92}93
94public stat ic void s t o c k e e r S ch edu l e f 1 f 2 f 3 ( int f1 , double f2 , int f 3 ) {
B.11 Klasse ’IOExcel’ (input-output-stockeren van de oplossingen 133
95
96int [ ] hu lparray=new int [ w e g s ch r i j f v o l g o rd e . s i z e ( ) ] ;
97for ( int i =0; i<hulparray . l ength ; i++){98hulparray [ i ]= weg s ch r i j f v o l g o rd e . get ( i ) . sT ;
99}100boolean reedsGevonden=fa l se ;
101i f ( ! s t o c k e e r s t a r t t i j d e n . isEmpty ( ) ) {102for ( int [ ] i : s t o c k e e r s t a r t t i j d e n ) {103i f ( Arrays . equa l s ( i , hulparray ) ) {104reedsGevonden=true ;
105break ;
106}107}108}109i f ( ! reedsGevonden ) {110s t o c k e e r s t a r t t i j d e n . add ( hulparray ) ;
111s t o c k e e r f 1 . add (new I n t eg e r ( f 1 ) ) ;
112s t o c k e e r f 2 . add (new Double ( f 2 ) ) ;
113s t o c k e e r f 3 . add (new I n t eg e r ( f 3 ) ) ;
114}115}116
117public stat ic void s t o cke e rWegs ch r i j f vo l go rde ( ) {118weg s ch r i j f v o l g o rd e=(ArrayList<Task>) Task . l i j s t . c l one ( ) ;
119}120
121public stat ic void s ch r i j fDa taNaa rF i l e ( ) {122try
123{124WorkbookSettings ws = new WorkbookSettings ( ) ;
125ws . s e tLoca l e (new Locale ( ”en” , ”EN” ) ) ;
126NumberFormat gehee lGeta l = new NumberFormat ( ”##” ) ;
127WritableCel lFormat ce l lFormatGehee l = new WritableCel lFormat ( gehee lGeta l ) ;
128NumberFormat f2 format = new NumberFormat ( ”#.###” ) ;
129WritableCel lFormat cel lFormatF2 = new WritableCel lFormat ( f2 format ) ;
130
131Workbook workbook = Workbook . getWorkbook (new F i l e ( f i l ename ) ,ws ) ;
132WritableWorkbook copy = Workbook . createWorkbook (new F i l e ( f i l ename ) , workbook ) ;
133
134WritableSheet Resu l t s = copy . c r ea t eShee t ( ” Resu l t s ” , copy . getNumberOfSheets ( ) ) ;
135Resu l t s . addCel l (new Label (0 , 0 , ”Ondergrens op ba s i s van window− i n i t i a l i s a t i e
was ”+ondergrens+” . ” ) ) ;
136Label label = new Label (0 , 2 , ”RESULTATEN VAN DE ITERATIES : ” ) ;
137Resu l t s . addCel l ( label ) ;
138
139i f ( s t o c k e e r f 3 . isEmpty ( ) ) {140i f ( s t o c k e e r f 2 . isEmpty ( ) ) {141Resu l t s . addCel l (new Label (0 , 3 , ”Makespan f1 ” ) ) ;
142for ( int i =0; i<weg s ch r i j f v o l g o rd e . s i z e ( ) ; i++){143Resu l t s . addCel l (new Label ( i +1, 3 , ” sT ”+weg s ch r i j f v o l g o rd e . get ( i ) .
volgnummer ) ) ;
144}145for ( int i =0; i<s t o c k e e r s t a r t t i j d e n . s i z e ( ) ; i++){146Resu l t s . addCel l (new j x l . wr i t e . Number (0 , i +4, s t o c k e e r f 1 . get ( i ) .
intValue ( ) ) ) ;
147Resu l t s . g e tWr i tab l eCe l l (0 , i +4) . setCel lFormat ( ce l lFormatGehee l ) ;
148for ( int j =0; j<weg s ch r i j f v o l g o rd e . s i z e ( ) ; j++){149Resu l t s . addCel l (new j x l . wr i t e . Number( j +1, i +4,
s t o c k e e r s t a r t t i j d e n . get ( i ) [ j ] ) ) ;
B.11 Klasse ’IOExcel’ (input-output-stockeren van de oplossingen 134
150Resu l t s . g e tWr i tab l eCe l l ( j +1, i +4) . setCel lFormat (
ce l lFormatGehee l ) ;
151}152}153
154} else {155Resu l t s . addCel l (new Label (0 , 3 , ”Makespan f1 ” ) ) ;
156Resu l t s . addCel l (new Label (1 , 3 , ”Balans f 2 ” ) ) ;
157for ( int i =0; i<weg s ch r i j f v o l g o rd e . s i z e ( ) ; i++){158Resu l t s . addCel l (new Label ( i +2, 3 , ” sT ”+weg s ch r i j f v o l g o rd e . get ( i ) .
volgnummer ) ) ;
159}160for ( int i =0; i<s t o c k e e r s t a r t t i j d e n . s i z e ( ) ; i++){161Resu l t s . addCel l (new j x l . wr i t e . Number (0 , i +4, s t o c k e e r f 1 . get ( i ) .
intValue ( ) ) ) ;
162Resu l t s . g e tWr i tab l eCe l l (0 , i +4) . setCel lFormat ( ce l lFormatGehee l ) ;
163Resu l t s . addCel l (new j x l . wr i t e . Number (1 , i +4, s t o c k e e r f 2 . get ( i ) .
doubleValue ( ) ) ) ;
164Resu l t s . g e tWr i tab l eCe l l (1 , i +4) . setCel lFormat ( cel lFormatF2 ) ;
165for ( int j =0; j<weg s ch r i j f v o l g o rd e . s i z e ( ) ; j++){166Resu l t s . addCel l (new j x l . wr i t e . Number( j +2, i +4,
s t o c k e e r s t a r t t i j d e n . get ( i ) [ j ] ) ) ;
167Resu l t s . g e tWr i tab l eCe l l ( j +2, i +4) . setCel lFormat (
ce l lFormatGehee l ) ;
168}169
170}171
172}173} else {174Resu l t s . addCel l (new Label (0 , 3 , ”Makespan f1 ” ) ) ;
175Resu l t s . addCel l (new Label (1 , 3 , ” f 2 ” ) ) ;
176Resu l t s . addCel l (new Label (2 , 3 , ” f 3 ” ) ) ;
177for ( int i =0; i<weg s ch r i j f v o l g o rd e . s i z e ( ) ; i++){178Resu l t s . addCel l (new Label ( i +3, 3 , ” sT ”+weg s ch r i j f v o l g o rd e . get ( i ) .
volgnummer ) ) ;
179}180for ( int i =0; i<s t o c k e e r s t a r t t i j d e n . s i z e ( ) ; i++){181Resu l t s . addCel l (new j x l . wr i t e . Number (0 , i +4, s t o c k e e r f 1 . get ( i ) . intValue
( ) ) ) ;
182Resu l t s . g e tWr i tab l eCe l l (0 , i +4) . setCel lFormat ( ce l lFormatGehee l ) ;
183Resu l t s . addCel l (new j x l . wr i t e . Number (1 , i +4, s t o c k e e r f 2 . get ( i ) .
doubleValue ( ) ) ) ;
184Resu l t s . g e tWr i tab l eCe l l (1 , i +4) . setCel lFormat ( cel lFormatF2 ) ;
185Resu l t s . addCel l (new j x l . wr i t e . Number (2 , i +4, s t o c k e e r f 3 . get ( i ) . intValue
( ) ) ) ;
186Resu l t s . g e tWr i tab l eCe l l (0 , i +4) . setCel lFormat ( ce l lFormatGehee l ) ;
187for ( int j =0; j<weg s ch r i j f v o l g o rd e . s i z e ( ) ; j++){188Resu l t s . addCel l (new j x l . wr i t e . Number( j +3, i +4, s t o c k e e r s t a r t t i j d e n .
get ( i ) [ j ] ) ) ;
189Resu l t s . g e tWr i tab l eCe l l ( j +3, i +4) . setCel lFormat ( ce l lFormatGehee l ) ;
190}191}192
193}194
195copy . wr i t e ( ) ;
196copy . c l o s e ( ) ;
197workbook . c l o s e ( ) ;
B.11 Klasse ’IOExcel’ (input-output-stockeren van de oplossingen 135
198
199
200
201}202catch ( WriteException e )
203{204e . pr intStackTrace ( ) ;
205}206catch ( IOException e )
207{208e . pr intStackTrace ( ) ;
209}210catch ( B i f fExcept i on e )
211{212e . pr intStackTrace ( ) ;
213}214
215
216
217}218
219public stat ic void stockeerLowerbound ( int l ) {220IOExcel . ondergrens=l ;
221}222
223
224
225public stat ic void l e e sData ( ) {226
227try
228{229WorkbookSettings ws = new WorkbookSettings ( ) ;
230ws . s e tLoca l e (new Locale ( ”en” , ”EN” ) ) ;
231
232Workbook workbook = Workbook . getWorkbook (
233new F i l e ( f i l ename ) ,ws ) ;
234
235
236Sheet sheetTask = workbook . getSheet ( ”Taken” ) ;
237for ( int i =1; i< sheetTask . getRows ( ) ; i++){238Ce l l [ ] hu id i g eR i j= sheetTask . getRow( i ) ;
239NumberCell volgnummerCell = ( NumberCell ) hu id i g eR i j [ 0 ] ;
240NumberCell l e n g t eCe l l = ( NumberCell ) hu id i g eR i j [ 1 ] ;
241NumberCell l a bo rCe l l = ( NumberCell ) hu id i g eR i j [ 2 ] ;
242NumberCell r e l t C e l l = ( NumberCell ) hu id i g eR i j [ 3 ] ;
243int volgnummer=( int ) volgnummerCell . getValue ( ) ;
244int l e ng t e=( int ) l e n g t eCe l l . getValue ( ) ;
245int l abor=( int ) l abo rCe l l . getValue ( ) ;
246int re leaseTime=( int ) r e l t C e l l . getValue ( ) ;
247int [ ] machinenummers=new int [ hu id i g eR i j . length −4] ;
248for ( int j =4; j<hu id i g eR i j . l ength ; j++){249machinenummers [ j −4]=( int ) ( ( NumberCell ) hu id i g eR i j [ j ] ) . getValue ( ) ;
250}251new Task ( volgnummer , l engte , labor , re leaseTime , machinenummers ) ;
252}253
254Sheet shee tOpt i e s = workbook . getSheet ( ”Opties ” ) ;
255
256NumberCell lmaxCel l = ( NumberCell ) shee tOpt i e s . g e tCe l l ( 1 , 19 ) ;
B.11 Klasse ’IOExcel’ (input-output-stockeren van de oplossingen 136
257new LaborResource ( ( int ) lmaxCel l . getValue ( ) ) ;
258
259i f ( shee tOpt i e s . g e tCe l l ( 1 , 4 ) . getContents ( ) . equa l s ( ”x” ) | | shee tOpt i e s . g e tCe l l ( 1 , 4 ) .
getContents ( ) . equa l s ( ”X” ) ) {260IOExcel . procedurekeuze =1;
261} else i f ( shee tOpt i e s . g e tCe l l ( 1 , 5 ) . getContents ( ) . equa l s ( ”x” ) | | shee tOpt i e s .
g e tCe l l ( 1 , 5 ) . getContents ( ) . equa l s ( ”X” ) ) {262IOExcel . procedurekeuze =2;
263} else i f ( shee tOpt i e s . g e tCe l l ( 1 , 6 ) . getContents ( ) . equa l s ( ”x” ) | | shee tOpt i e s .
g e tCe l l ( 1 , 6 ) . getContents ( ) . equa l s ( ”X” ) ) {264IOExcel . procedurekeuze =3;
265} else i f ( shee tOpt i e s . g e tCe l l ( 1 , 8 ) . getContents ( ) . equa l s ( ”x” ) | | shee tOpt i e s .
g e tCe l l ( 1 , 8 ) . getContents ( ) . equa l s ( ”X” ) ) {266IOExcel . procedurekeuze =4;
267} else i f ( shee tOpt i e s . g e tCe l l ( 1 , 9 ) . getContents ( ) . equa l s ( ”x” ) | | shee tOpt i e s .
g e tCe l l ( 1 , 9 ) . getContents ( ) . equa l s ( ”X” ) ) {268IOExcel . procedurekeuze =5;
269} else i f ( shee tOpt i e s . g e tCe l l ( 1 , 10 ) . getContents ( ) . equa l s ( ”x” ) | | shee tOpt i e s .
g e tCe l l ( 1 , 10 ) . getContents ( ) . equa l s ( ”X” ) ) {270IOExcel . procedurekeuze =6;
271} else i f ( shee tOpt i e s . g e tCe l l ( 1 , 12 ) . getContents ( ) . equa l s ( ”x” ) | | shee tOpt i e s .
g e tCe l l ( 1 , 12 ) . getContents ( ) . equa l s ( ”X” ) ) {272IOExcel . procedurekeuze =7;
273} else i f ( shee tOpt i e s . g e tCe l l ( 1 , 13 ) . getContents ( ) . equa l s ( ”x” ) | | shee tOpt i e s .
g e tCe l l ( 1 , 13 ) . getContents ( ) . equa l s ( ”X” ) ) {274IOExcel . procedurekeuze =8;
275} else i f ( shee tOpt i e s . g e tCe l l ( 1 , 14 ) . getContents ( ) . equa l s ( ”x” ) | | shee tOpt i e s .
g e tCe l l ( 1 , 14 ) . getContents ( ) . equa l s ( ”X” ) ) {276IOExcel . procedurekeuze =9;
277} else {278IOExcel . procedurekeuze =7;
279}280
281IOExcel . a a n t a l I t e r a t i e s =( int ) ( ( NumberCell ) shee tOpt i e s . g e tCe l l ( 1 , 16 ) ) . getValue
( ) ;
282
283Sheet sheetPD = workbook . getSheet ( ”PD” ) ;
284for ( int i =1; i< sheetPD . getRows ( ) ; i++){285Ce l l [ ] hu id i g eR i j= sheetPD . getRow( i ) ;
286int [ ] r i jWaarden=new int [ hu id i g eR i j . l ength ] ;
287for ( int j =0; j< hu id i g eR i j . l ength ; j++){288rijWaarden [ j ]=( int ) ( ( NumberCell ) hu id i g eR i j [ j ] ) . getValue ( ) ;
289}290Const ra in t s . addPD( rijWaarden ) ;
291}292
293Sheet sheetDJ = workbook . getSheet ( ”DJ” ) ;
294
295Ce l l [ ] machDisjRij=sheetDJ . getRow (1) ;
296for ( int i =0; i<machDisjRij . l ength ; i++){297int machinenummer=( int ) ( ( NumberCell ) machDisjRij [ i ] ) . getValue ( ) ;
298Const ra in t s . addMachineDisjunction (machinenummer ) ;
299}300
301for ( int i =4; i< sheetDJ . getRows ( ) ; i++){302Ce l l [ ] hu id i g eR i j= sheetDJ . getRow( i ) ;
303int [ ] r i jWaarden=new int [ hu id i g eR i j . l ength ] ;
304for ( int j =0; j< hu id i g eR i j . l ength ; j++){305rijWaarden [ j ]=( int ) ( ( NumberCell ) hu id i g eR i j [ j ] ) . getValue ( ) ;
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 137
306}307Const ra in t s . addDJ( rijWaarden ) ;
308}309
310Sheet sheetCC = workbook . getSheet ( ”CC” ) ;
311
312for ( int i =1; i< sheetCC . getRows ( ) ; i++){313Ce l l [ ] hu id i g eR i j= sheetCC . getRow( i ) ;
314int [ ] r i jWaarden=new int [ hu id i g eR i j . l ength ] ;
315for ( int j =0; j< hu id i g eR i j . l ength ; j++){316rijWaarden [ j ]=( int ) ( ( NumberCell ) hu id i g eR i j [ j ] ) . getValue ( ) ;
317}318Const ra in t s . addCC( rijWaarden ) ;
319}320
321Sheet sheetCS = workbook . getSheet ( ”CS” ) ;
322
323for ( int i =1; i< sheetCS . getRows ( ) ; i++){324Ce l l [ ] hu id i g eR i j= sheetCS . getRow( i ) ;
325int [ ] r i jWaarden=new int [ hu id i g eR i j . l ength ] ;
326for ( int j =0; j< hu id i g eR i j . l ength ; j++){327rijWaarden [ j ]=( int ) ( ( NumberCell ) hu id i g eR i j [ j ] ) . getValue ( ) ;
328}329Const ra in t s . addCS( rijWaarden ) ;
330}331
332workbook . c l o s e ( ) ;
333
334
335
336}337catch ( IOException e )
338{339e . pr intStackTrace ( ) ;
340}341catch ( B i f fExcept i on e )
342{343e . pr intStackTrace ( ) ;
344}345
346}347
348}
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelen-
de structuur)
1
2/∗∗3∗ Deze k l a s s e beva t de main−methode d ie e i g e n l i j k l a t e r de b a s i s z a l z i j n van waaruit
a l l e s u i t g e v o e r d worden ( d ie dus door de g e b r u i k e r z a l u i t g e v o e r d worden met a l s
argument de f i l ename
4∗ van de Excel− f i l e waarin z i c h a l l e gegevens bevinden ) .
5∗6∗ Verder wordend e negen v e r s i e s van het a l gor i tme a l s aparte methoden besproken .
Deze roepen op hun beur t de nodige methodes op in a l l e andere k l a s s e s .
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 138
7∗8∗ @author J o r i s Apr i l
9∗ @version 1.0
10∗/11import java . u t i l . ArrayList ;
12import java . u t i l . Co l l e c t i o n s ;
13import java . u t i l .Random ;
14
15public class Schedul ingAlgor i tmes
16{17
18
19public stat ic void main ( St r ing [ ] f i l ename ) {20i f ( f i l ename . l ength==0){21System . out . p r i n t l n ( ”Filename van het Excel−bronbestand moet a l s command−l i n e argument
meegegeven worden . Probeer het a . u . b . opnieuw . ” ) ;
22} else {23IOExcel . f i l ename=f i l ename [ 0 ] ;
24IOExcel . l eesData ( ) ;
25switch ( IOExcel . procedurekeuze ) {26case 1 : Schedul ingAlgor i tmes . swo ( IOExcel . a a n t a l I t e r a t i e s ) ; break ;
27case 2 : Schedul ingAlgor i tmes . swoMetBulldozing ( IOExcel . a a n t a l I t e r a t i e s ) ; break ;
28case 3 : Schedul ingAlgor i tmes . swoMetBul ldoz ingRe f i l l i ng ( IOExcel . a a n t a l I t e r a t i e s
) ; break ;
29case 4 : Schedul ingAlgor i tmes . swoMetF2( IOExcel . a a n t a l I t e r a t i e s ) ; break ;
30case 5 : Schedul ingAlgor i tmes . swoMetBulldozingF2 ( IOExcel . a a n t a l I t e r a t i e s ) ;
break ;
31case 6 : Schedul ingAlgor i tmes . swoMetBul ldoz ingRef i l l ingF2 ( IOExcel .
a a n t a l I t e r a t i e s ) ; break ;
32case 7 : Schedul ingAlgor i tmes . swoMetF2F3( IOExcel . a a n t a l I t e r a t i e s ) ; break ;
33case 8 : Schedul ingAlgor i tmes . swoMetBulldozingF2F3 ( IOExcel . a a n t a l I t e r a t i e s ) ;
break ;
34case 9 : Schedul ingAlgor i tmes . swoMetBul ldoz ingRef i l l ingF2F3 ( IOExcel .
a a n t a l I t e r a t i e s ) ; break ;
35}36}37
38}39
40
41public stat ic void swo ( int a a n t a l I t e r a t i e s ) {42int lowerbound=Task . zoekMinimaleHorizon ( ) ;
43int hor i zon=lowerbound ;
44IOExcel . stockeerLowerbound ( lowerbound ) ;
45int besteMakespan = −1;
46ArrayList<Boolean> l a s t 1 0 i t e r a t i o n s = new ArrayList<Boolean>(10) ;
47IOExcel . s t o cke e rWegs ch r i j f vo l go rde ( ) ;
48int t i enp ro c en t=a a n t a l I t e r a t i e s /10 ;
49int t i e n p r o c e n t t e l l e r =0;
50
51System . out . p r i n t l n ( ) ;
52System . out . p r i n t l n ( a a n t a l I t e r a t i e s+” i t e r a t i e s u i t te voeren door bas i s−SWO,
wegschr i jven bes t e f 1 . ” ) ;
53
54Task . i n i t i a l i s e e r P r i o r i t e i t e n ( ) ;
55
56for ( int i=0 ; i<a a n t a l I t e r a t i e s ; i++) {57
58i f ( i>( t i e n p r o c e n t t e l l e r ∗ t i enp ro c en t ) ) {
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 139
59System . out . p r i n t l n ( ” Voortgang ”+( t i e n p r o c e n t t e l l e r ∗10)+”%” ) ;
60t i e n p r o c e n t t e l l e r++;
61}62boolean f e a s i b l e=true ;
63Task . zetHor izon ( hor i zon ) ;
64Task . r e s e tA l lTask s ( ) ;
65Task . resetWindows ( ) ;
66Task . w i n d ow I n i t i a l i s a t i e ( ) ;
67
68for (Task j : Task . l i j s t ) {69i f ( ! j . s chedu le ( ) ) {70f e a s i b l e=fa l se ;
71}72}73
74i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )==10){75l a s t 1 0 i t e r a t i o n s . remove (0 ) ;
76}77l a s t 1 0 i t e r a t i o n s . add (new Boolean ( f e a s i b l e ) ) ;
78
79i f ( f e a s i b l e ) {80int hu id ig=Task . bepaalMakespan ( ) ;
81i f ( huidig<besteMakespan | | besteMakespan==−1){82besteMakespan=huid ig ;
83IOExcel . w i sGestockeerdeResu l taten ( ) ;
84IOExcel . s t o cke e rSchedu l e f 1 ( hu id ig ) ;
85} else i f ( hu id ig==besteMakespan ) {86IOExcel . s t o cke e rSchedu l e f 1 ( hu id ig ) ;
87}88}89
90boolean l a s t 1 0 un f e a s i b l e=true ;
91i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )<10){92l a s t 1 0 un f e a s i b l e=fa l se ;
93} else {94for ( Boolean k : l a s t 1 0 i t e r a t i o n s ) {95
96i f ( k . booleanValue ( ) ) {97l a s t 1 0 un f e a s i b l e=fa l se ;
98}99}100}101
102
103i f ( l a s t 1 0 u n f e a s i b l e ) {104hor i zon++;
105l a s t 1 0 i t e r a t i o n s . c l e a r ( ) ;
106}107
108Task . upda t eP r i o r i t e i t e n ( ) ;
109}110IOExcel . s ch r i j fDa taNaa rF i l e ( ) ;
111System . out . p r i n t l n ( ) ;
112System . out . p r i n t l n ( ”Best b e r e i k t e makespan : ”+besteMakespan ) ;
113System . out . p r i n t l n ( ) ;
114System . out . p r i n t l n ( IOExcel . s t o c k e e r s t a r t t i j d e n . s i z e ( )+” schedu l e s geschreven in
shee t ’ Resu l t s ’ van f i l e ’ ”+IOExcel . f i l ename+” ’ . ” ) ;
115System . out . p r i n t l n ( ) ;
116
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 140
117}118
119public stat ic void swoMetBulldozing ( int a a n t a l I t e r a t i e s ) {120int besteMakespan = −1;
121int lowerbound=Task . zoekMinimaleHorizon ( ) ;
122IOExcel . stockeerLowerbound ( lowerbound ) ;
123int hor i zon=lowerbound ;
124ArrayList<Boolean> l a s t 1 0 i t e r a t i o n s = new ArrayList<Boolean>(10) ;
125IOExcel . s t o cke e rWegs ch r i j f vo l go rde ( ) ;
126int t i enp ro c en t=a a n t a l I t e r a t i e s /10 ;
127int t i e n p r o c e n t t e l l e r =0;
128
129System . out . p r i n t l n ( ) ;
130System . out . p r i n t l n ( a a n t a l I t e r a t i e s+” i t e r a t i e s u i t te voeren door SWO met
bu l ldoz ing , wegschr i jven bes t e f 1 . ” ) ;
131
132Task . i n i t i a l i s e e r P r i o r i t e i t e n ( ) ;
133
134for ( int i=0 ; i<a a n t a l I t e r a t i e s ; i++) {135
136i f ( i>( t i e n p r o c e n t t e l l e r ∗ t i enp ro c en t ) ) {137System . out . p r i n t l n ( ” Voortgang ”+( t i e n p r o c e n t t e l l e r ∗10)+”%” ) ;
138t i e n p r o c e n t t e l l e r++;
139}140
141boolean f e a s i b l e=true ;
142Task . zetHor izon ( hor i zon ) ;
143Task . r e s e tA l lTask s ( ) ;
144Task . resetWindows ( ) ;
145Task . w i n d ow I n i t i a l i s a t i e ( ) ;
146
147for (Task j : Task . l i j s t ) {148i f ( ! j . scheduleMetBul ldoz ing ( ) ) {149f e a s i b l e=fa l se ;
150}151}152
153
154i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )==10){155l a s t 1 0 i t e r a t i o n s . remove (0 ) ;
156}157l a s t 1 0 i t e r a t i o n s . add (new Boolean ( f e a s i b l e ) ) ;
158
159i f ( f e a s i b l e ) {160int hu id ig=Task . bepaalMakespan ( ) ;
161i f ( huidig<besteMakespan | | besteMakespan==−1){162besteMakespan=huid ig ;
163IOExcel . w i sGestockeerdeResu l taten ( ) ;
164IOExcel . s t o cke e rSchedu l e f 1 ( hu id ig ) ;
165} else i f ( hu id ig==besteMakespan ) {166IOExcel . s t o cke e rSchedu l e f 1 ( hu id ig ) ;
167}168}169
170boolean l a s t 1 0 un f e a s i b l e=true ;
171i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )<10){172l a s t 1 0 un f e a s i b l e=fa l se ;
173} else {174for ( Boolean k : l a s t 1 0 i t e r a t i o n s ) {
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 141
175
176i f ( k . booleanValue ( ) ) {177l a s t 1 0 un f e a s i b l e=fa l se ;
178}179}180}181
182
183i f ( l a s t 1 0 un f e a s i b l e ) {184hor i zon++;
185l a s t 1 0 i t e r a t i o n s . c l e a r ( ) ;
186}187
188Task . upda t eP r i o r i t e i t e n ( ) ;
189}190
191IOExcel . s ch r i j fDa taNaa rF i l e ( ) ;
192System . out . p r i n t l n ( ) ;
193System . out . p r i n t l n ( ”Best b e r e i k t e makespan : ”+besteMakespan ) ;
194System . out . p r i n t l n ( ) ;
195System . out . p r i n t l n ( IOExcel . s t o c k e e r s t a r t t i j d e n . s i z e ( )+” schedu l e s geschreven in
shee t ’ Resu l t s ’ van f i l e ’ ”+IOExcel . f i l ename+” ’ . ” ) ;
196System . out . p r i n t l n ( ) ;
197
198}199
200public stat ic void swoMetBu l ldoz ingRe f i l l i ng ( int a a n t a l I t e r a t i e s ) {201int besteMakespan = −1;
202int lowerbound=Task . zoekMinimaleHorizon ( ) ;
203int hor i zon=lowerbound ;
204IOExcel . stockeerLowerbound ( lowerbound ) ;
205ArrayList<Boolean> l a s t 1 0 i t e r a t i o n s = new ArrayList<Boolean>(10) ;
206IOExcel . s t o cke e rWegs ch r i j f vo l go rde ( ) ;
207
208int t i enp ro c en t=a a n t a l I t e r a t i e s /10 ;
209int t i e n p r o c e n t t e l l e r =0;
210
211System . out . p r i n t l n ( ) ;
212System . out . p r i n t l n ( a a n t a l I t e r a t i e s+” i t e r a t i e s u i t te voeren door SWO met
bu l l doz ing en r e f i l l i n g , wegschr i jven bes t e f 1 . ” ) ;
213
214
215Task . i n i t i a l i s e e r P r i o r i t e i t e n ( ) ;
216
217for ( int i=0 ; i<a a n t a l I t e r a t i e s ; i++) {218
219i f ( i>( t i e n p r o c e n t t e l l e r ∗ t i enp ro c en t ) ) {220System . out . p r i n t l n ( ” Voortgang ”+( t i e n p r o c e n t t e l l e r ∗10)+”%” ) ;
221t i e n p r o c e n t t e l l e r++;
222}223
224boolean f e a s i b l e=true ;
225Task . zetHor izon ( hor i zon ) ;
226Task . r e s e tA l lTask s ( ) ;
227Task . resetWindows ( ) ;
228Task . w i n d ow I n i t i a l i s a t i e ( ) ;
229
230for (Task j : Task . l i j s t ) {231i f ( ! j . s chedu l eMetBu l l doz ingRe f i l l i ng ( ) ) {
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 142
232f e a s i b l e=fa l se ;
233}234}235
236i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )==10){237l a s t 1 0 i t e r a t i o n s . remove (0 ) ;
238}239l a s t 1 0 i t e r a t i o n s . add (new Boolean ( f e a s i b l e ) ) ;
240
241i f ( f e a s i b l e ) {242int hu id ig=Task . bepaalMakespan ( ) ;
243i f ( huidig<besteMakespan | | besteMakespan==−1){244besteMakespan=huid ig ;
245IOExcel . w i sGestockeerdeResu l taten ( ) ;
246IOExcel . s t o cke e rSchedu l e f 1 ( hu id ig ) ;
247} else i f ( hu id ig==besteMakespan ) {248IOExcel . s t o cke e rSchedu l e f 1 ( hu id ig ) ;
249}250}251
252boolean l a s t 1 0 un f e a s i b l e=true ;
253i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )<10){254l a s t 1 0 un f e a s i b l e=fa l se ;
255} else {256for ( Boolean k : l a s t 1 0 i t e r a t i o n s ) {257
258i f ( k . booleanValue ( ) ) {259l a s t 1 0 un f e a s i b l e=fa l se ;
260}261}262}263
264
265i f ( l a s t 1 0 u n f e a s i b l e ) {266hor i zon++;
267l a s t 1 0 i t e r a t i o n s . c l e a r ( ) ;
268}269
270Task . upda t eP r i o r i t e i t e n ( ) ;
271}272
273IOExcel . s ch r i j fDa taNaa rF i l e ( ) ;
274System . out . p r i n t l n ( ) ;
275System . out . p r i n t l n ( ”Best b e r e i k t e makespan : ”+besteMakespan ) ;
276System . out . p r i n t l n ( ) ;
277System . out . p r i n t l n ( IOExcel . s t o c k e e r s t a r t t i j d e n . s i z e ( )+” schedu l e s geschreven in
shee t ’ Resu l t s ’ van f i l e ’ ”+IOExcel . f i l ename+” ’ . ” ) ;
278System . out . p r i n t l n ( ) ;
279
280}281
282public stat ic void swoMetF2( int a a n t a l I t e r a t i e s ) {283int lowerbound=Task . zoekMinimaleHorizon ( ) ;
284int hor i zon=lowerbound ;
285IOExcel . stockeerLowerbound ( lowerbound ) ;
286int besteMakespan = −1;
287double besteF2=−1;
288ArrayList<Boolean> l a s t 1 0 i t e r a t i o n s = new ArrayList<Boolean>(10) ;
289IOExcel . s t o cke e rWegs ch r i j f vo l go rde ( ) ;
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 143
290
291int t i enp ro c en t=a a n t a l I t e r a t i e s /10 ;
292int t i e n p r o c e n t t e l l e r =0;
293
294System . out . p r i n t l n ( ) ;
295System . out . p r i n t l n ( a a n t a l I t e r a t i e s+” i t e r a t i e s u i t te voeren door bas i s−SWO,
wegschr i jven bes t e f1>f 2 . ” ) ;
296
297Task . i n i t i a l i s e e r P r i o r i t e i t e n ( ) ;
298
299for ( int i=0 ; i<a a n t a l I t e r a t i e s ; i++) {300
301i f ( i>( t i e n p r o c e n t t e l l e r ∗ t i enp ro c en t ) ) {302System . out . p r i n t l n ( ” Voortgang ”+( t i e n p r o c e n t t e l l e r ∗10)+”%” ) ;
303t i e n p r o c e n t t e l l e r++;
304}305
306boolean f e a s i b l e=true ;
307Task . zetHor izon ( hor i zon ) ;
308Task . r e s e tA l lTask s ( ) ;
309Task . resetWindows ( ) ;
310Task . w i n d ow I n i t i a l i s a t i e ( ) ;
311
312for (Task j : Task . l i j s t ) {313i f ( ! j . s chedu le ( ) ) {314f e a s i b l e=fa l se ;
315}316}317
318i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )==10){319l a s t 1 0 i t e r a t i o n s . remove (0 ) ;
320}321l a s t 1 0 i t e r a t i o n s . add (new Boolean ( f e a s i b l e ) ) ;
322
323
324i f ( f e a s i b l e ) {325int huidigeMakespan=Task . bepaalMakespan ( ) ;
326double huidigeF2=Task . bepaalF2 ( huidigeMakespan ) ;
327i f ( huidigeMakespan<besteMakespan | | besteMakespan==−1){328besteMakespan=huidigeMakespan ;
329besteF2=huidigeF2 ;
330IOExcel . w i sGestockeerdeResu l taten ( ) ;
331IOExcel . s t o ck e e rS ch edu l e f 1 f 2 ( huidigeMakespan , huidigeF2 ) ;
332} else i f ( huidigeMakespan==besteMakespan ) {333i f ( huidigeF2<besteF2 ) {334IOExcel . w i sGestockeerdeResu l taten ( ) ;
335IOExcel . s t o ck e e rS ch edu l e f 1 f 2 ( huidigeMakespan , huidigeF2 ) ;
336} else i f ( huidigeF2==besteF2 ) {337IOExcel . s t o ck e e rS ch edu l e f 1 f 2 ( huidigeMakespan , huidigeF2 ) ;
338}339
340}341}342
343boolean l a s t 1 0 un f e a s i b l e=true ;
344i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )<10){345l a s t 1 0 un f e a s i b l e=fa l se ;
346} else {347for ( Boolean k : l a s t 1 0 i t e r a t i o n s ) {
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 144
348
349i f ( k . booleanValue ( ) ) {350l a s t 1 0 un f e a s i b l e=fa l se ;
351}352}353}354
355
356i f ( l a s t 1 0 un f e a s i b l e ) {357hor i zon++;
358l a s t 1 0 i t e r a t i o n s . c l e a r ( ) ;
359}360
361Task . upda t eP r i o r i t e i t e n ( ) ;
362}363
364IOExcel . s ch r i j fDa taNaa rF i l e ( ) ;
365System . out . p r i n t l n ( ) ;
366System . out . p r i n t l n ( ”Best b e r e i k t e makespan : ”+besteMakespan ) ;
367System . out . p r i n t l n ( ”Best b e r e i k t e f 2 ( ba lance ) : ”+besteF2 ) ;
368System . out . p r i n t l n ( ) ;
369System . out . p r i n t l n ( IOExcel . s t o c k e e r s t a r t t i j d e n . s i z e ( )+” schedu l e s geschreven in
shee t ’ Resu l t s ’ van f i l e ’ ”+IOExcel . f i l ename+” ’ . ” ) ;
370System . out . p r i n t l n ( ) ;
371
372}373
374public stat ic void swoMetBulldozingF2 ( int a a n t a l I t e r a t i e s ) {375int lowerbound=Task . zoekMinimaleHorizon ( ) ;
376int hor i zon=lowerbound ;
377IOExcel . stockeerLowerbound ( lowerbound ) ;
378int besteMakespan = −1;
379double besteF2=−1;
380ArrayList<Boolean> l a s t 1 0 i t e r a t i o n s = new ArrayList<Boolean>(10) ;
381IOExcel . s t o cke e rWegs ch r i j f vo l go rde ( ) ;
382
383int t i enp ro c en t=a a n t a l I t e r a t i e s /10 ;
384int t i e n p r o c e n t t e l l e r =0;
385
386System . out . p r i n t l n ( ) ;
387System . out . p r i n t l n ( a a n t a l I t e r a t i e s+” i t e r a t i e s u i t te voeren door SWO met
bu l ldoz ing , wegschr i jven bes t e f1>f 2 . ” ) ;
388
389Task . i n i t i a l i s e e r P r i o r i t e i t e n ( ) ;
390
391for ( int i=0 ; i<a a n t a l I t e r a t i e s ; i++) {392
393i f ( i>( t i e n p r o c e n t t e l l e r ∗ t i enp ro c en t ) ) {394System . out . p r i n t l n ( ” Voortgang ”+( t i e n p r o c e n t t e l l e r ∗10)+”%” ) ;
395t i e n p r o c e n t t e l l e r++;
396}397
398boolean f e a s i b l e=true ;
399Task . zetHor izon ( hor i zon ) ;
400Task . r e s e tA l lTask s ( ) ;
401Task . resetWindows ( ) ;
402Task . w i n d ow I n i t i a l i s a t i e ( ) ;
403
404for (Task j : Task . l i j s t ) {
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 145
405i f ( ! j . scheduleMetBul ldoz ing ( ) ) {406f e a s i b l e=fa l se ;
407}408}409
410
411i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )==10){412l a s t 1 0 i t e r a t i o n s . remove (0 ) ;
413}414l a s t 1 0 i t e r a t i o n s . add (new Boolean ( f e a s i b l e ) ) ;
415
416i f ( f e a s i b l e ) {417int huidigeMakespan=Task . bepaalMakespan ( ) ;
418double huidigeF2=Task . bepaalF2 ( huidigeMakespan ) ;
419i f ( huidigeMakespan<besteMakespan | | besteMakespan==−1){420besteMakespan=huidigeMakespan ;
421besteF2=huidigeF2 ;
422IOExcel . w i sGestockeerdeResu l taten ( ) ;
423IOExcel . s t o ck e e rS ch edu l e f 1 f 2 ( huidigeMakespan , huidigeF2 ) ;
424} else i f ( huidigeMakespan==besteMakespan ) {425i f ( huidigeF2<besteF2 ) {426IOExcel . w i sGestockeerdeResu l taten ( ) ;
427IOExcel . s t o ck e e rS ch edu l e f 1 f 2 ( huidigeMakespan , huidigeF2 ) ;
428} else i f ( huidigeF2==besteF2 ) {429IOExcel . s t o ck e e rS ch edu l e f 1 f 2 ( huidigeMakespan , huidigeF2 ) ;
430}431
432}433}434
435boolean l a s t 1 0 un f e a s i b l e=true ;
436i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )<10){437l a s t 1 0 un f e a s i b l e=fa l se ;
438} else {439for ( Boolean k : l a s t 1 0 i t e r a t i o n s ) {440
441i f ( k . booleanValue ( ) ) {442l a s t 1 0 un f e a s i b l e=fa l se ;
443}444}445}446
447
448i f ( l a s t 1 0 u n f e a s i b l e ) {449hor i zon++;
450l a s t 1 0 i t e r a t i o n s . c l e a r ( ) ;
451}452
453Task . upda t eP r i o r i t e i t e n ( ) ;
454}455
456IOExcel . s ch r i j fDa taNaa rF i l e ( ) ;
457System . out . p r i n t l n ( ) ;
458System . out . p r i n t l n ( ”Best b e r e i k t e makespan : ”+besteMakespan ) ;
459System . out . p r i n t l n ( ”Best b e r e i k t e f 2 ( ba lance ) : ”+besteF2 ) ;
460System . out . p r i n t l n ( ) ;
461System . out . p r i n t l n ( IOExcel . s t o c k e e r s t a r t t i j d e n . s i z e ( )+” schedu l e s geschreven in
shee t ’ Resu l t s ’ van f i l e ’ ”+IOExcel . f i l ename+” ’ . ” ) ;
462System . out . p r i n t l n ( ) ;
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 146
463
464}465
466public stat ic void swoMetBul ldoz ingRef i l l ingF2 ( int a a n t a l I t e r a t i e s ) {467int lowerbound=Task . zoekMinimaleHorizon ( ) ;
468int hor i zon=lowerbound ;
469IOExcel . stockeerLowerbound ( lowerbound ) ;
470int besteMakespan = −1;
471double besteF2=−1;
472ArrayList<Boolean> l a s t 1 0 i t e r a t i o n s = new ArrayList<Boolean>(10) ;
473IOExcel . s t o cke e rWegs ch r i j f vo l go rde ( ) ;
474
475int t i enp ro c en t=a a n t a l I t e r a t i e s /10 ;
476int t i e n p r o c e n t t e l l e r =0;
477
478System . out . p r i n t l n ( ) ;
479System . out . p r i n t l n ( a a n t a l I t e r a t i e s+” i t e r a t i e s u i t te voeren door SWO met
bu l l doz ing en r e f i l l i n g , wegschr i jven bes t e f1>f 2 . ” ) ;
480
481
482Task . i n i t i a l i s e e r P r i o r i t e i t e n ( ) ;
483
484for ( int i=0 ; i<a a n t a l I t e r a t i e s ; i++) {485
486i f ( i>( t i e n p r o c e n t t e l l e r ∗ t i enp ro c en t ) ) {487System . out . p r i n t l n ( ” Voortgang ”+( t i e n p r o c e n t t e l l e r ∗10)+”%” ) ;
488t i e n p r o c e n t t e l l e r++;
489}490
491boolean f e a s i b l e=true ;
492Task . zetHor izon ( hor i zon ) ;
493Task . r e s e tA l lTask s ( ) ;
494Task . resetWindows ( ) ;
495Task . w i n d ow I n i t i a l i s a t i e ( ) ;
496
497for (Task j : Task . l i j s t ) {498i f ( ! j . s chedu l eMetBu l l doz ingRe f i l l i ng ( ) ) {499f e a s i b l e=fa l se ;
500}501}502
503i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )==10){504l a s t 1 0 i t e r a t i o n s . remove (0 ) ;
505}506l a s t 1 0 i t e r a t i o n s . add (new Boolean ( f e a s i b l e ) ) ;
507
508i f ( f e a s i b l e ) {509int huidigeMakespan=Task . bepaalMakespan ( ) ;
510double huidigeF2=Task . bepaalF2 ( huidigeMakespan ) ;
511i f ( huidigeMakespan<besteMakespan | | besteMakespan==−1){512besteMakespan=huidigeMakespan ;
513besteF2=huidigeF2 ;
514IOExcel . w i sGestockeerdeResu l taten ( ) ;
515IOExcel . s t o ck e e rS ch edu l e f 1 f 2 ( huidigeMakespan , huidigeF2 ) ;
516} else i f ( huidigeMakespan==besteMakespan ) {517i f ( huidigeF2<besteF2 ) {518IOExcel . w i sGestockeerdeResu l taten ( ) ;
519IOExcel . s t o ck e e rS ch edu l e f 1 f 2 ( huidigeMakespan , huidigeF2 ) ;
520} else i f ( huidigeF2==besteF2 ) {
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 147
521IOExcel . s t o ck e e rS ch edu l e f 1 f 2 ( huidigeMakespan , huidigeF2 ) ;
522}523
524}525}526
527boolean l a s t 1 0 un f e a s i b l e=true ;
528i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )<10){529l a s t 1 0 un f e a s i b l e=fa l se ;
530} else {531for ( Boolean k : l a s t 1 0 i t e r a t i o n s ) {532
533i f ( k . booleanValue ( ) ) {534l a s t 1 0 un f e a s i b l e=fa l se ;
535}536}537}538
539
540i f ( l a s t 1 0 u n f e a s i b l e ) {541hor i zon++;
542l a s t 1 0 i t e r a t i o n s . c l e a r ( ) ;
543}544
545Task . upda t eP r i o r i t e i t e n ( ) ;
546}547
548IOExcel . s ch r i j fDa taNaa rF i l e ( ) ;
549System . out . p r i n t l n ( ) ;
550System . out . p r i n t l n ( ”Best b e r e i k t e makespan : ”+besteMakespan ) ;
551System . out . p r i n t l n ( ”Best b e r e i k t e f 2 ( ba lance ) : ”+besteF2 ) ;
552System . out . p r i n t l n ( ) ;
553System . out . p r i n t l n ( IOExcel . s t o c k e e r s t a r t t i j d e n . s i z e ( )+” schedu l e s geschreven in
shee t ’ Resu l t s ’ van f i l e ’ ”+IOExcel . f i l ename+” ’ . ” ) ;
554System . out . p r i n t l n ( ) ;
555
556}557
558
559public stat ic void swoMetF2F3( int a a n t a l I t e r a t i e s ) {560int lowerbound=Task . zoekMinimaleHorizon ( ) ;
561int hor i zon=lowerbound ;
562IOExcel . stockeerLowerbound ( lowerbound ) ;
563int besteMakespan = −1;
564double besteF2=−1;
565int besteF3=−1;
566ArrayList<Boolean> l a s t 1 0 i t e r a t i o n s = new ArrayList<Boolean>(10) ;
567IOExcel . s t o cke e rWegs ch r i j f vo l go rde ( ) ;
568
569int t i enp ro c en t=a a n t a l I t e r a t i e s /10 ;
570int t i e n p r o c e n t t e l l e r =0;
571
572System . out . p r i n t l n ( ) ;
573System . out . p r i n t l n ( a a n t a l I t e r a t i e s+” i t e r a t i e s u i t te voeren door bas i s−SWO,
wegschr i jven bes t e f1>f2>f 3 . ” ) ;
574
575Task . i n i t i a l i s e e r P r i o r i t e i t e n ( ) ;
576
577for ( int i=0 ; i<a a n t a l I t e r a t i e s ; i++) {
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 148
578
579i f ( i>( t i e n p r o c e n t t e l l e r ∗ t i enp ro c en t ) ) {580System . out . p r i n t l n ( ” Voortgang ”+( t i e n p r o c e n t t e l l e r ∗10)+”%” ) ;
581t i e n p r o c e n t t e l l e r++;
582}583
584boolean f e a s i b l e=true ;
585Task . zetHor izon ( hor i zon ) ;
586Task . r e s e tA l lTask s ( ) ;
587Task . resetWindows ( ) ;
588Task . w i n d ow I n i t i a l i s a t i e ( ) ;
589
590for (Task j : Task . l i j s t ) {591i f ( ! j . s chedu le ( ) ) {592f e a s i b l e=fa l se ;
593}594}595
596i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )==10){597l a s t 1 0 i t e r a t i o n s . remove (0 ) ;
598}599l a s t 1 0 i t e r a t i o n s . add (new Boolean ( f e a s i b l e ) ) ;
600
601
602i f ( f e a s i b l e ) {603int huidigeMakespan=Task . bepaalMakespan ( ) ;
604double huidigeF2=Task . bepaalF2 ( huidigeMakespan ) ;
605int huidigeF3=Task . bepaalF3 ( huidigeMakespan ) ;
606
607i f ( huidigeMakespan<besteMakespan | | besteMakespan==−1){608besteMakespan=huidigeMakespan ;
609besteF2=huidigeF2 ;
610besteF3=huidigeF3 ;
611IOExcel . w i sGestockeerdeResu l taten ( ) ;
612IOExcel . s t o c k e e r S ch edu l e f 1 f 2 f 3 ( huidigeMakespan , huidigeF2 , huidigeF3 ) ;
613} else i f ( huidigeMakespan==besteMakespan ) {614i f ( huidigeF2<besteF2 ) {615besteF2=huidigeF2 ;
616besteF3=huidigeF3 ;
617IOExcel . w i sGestockeerdeResu l taten ( ) ;
618IOExcel . s t o c k e e r S ch edu l e f 1 f 2 f 3 ( huidigeMakespan , huidigeF2 , huidigeF3
) ;
619} else i f ( huidigeF2==besteF2 ) {620i f ( huidigeF3<besteF3 ) {621besteF3=huidigeF3 ;
622IOExcel . w i sGestockeerdeResu l taten ( ) ;
623IOExcel . s t o c k e e r S ch edu l e f 1 f 2 f 3 ( huidigeMakespan , huidigeF2 ,
huidigeF3 ) ;
624} else i f ( huidigeF3==besteF3 ) {625IOExcel . s t o c k e e r S ch edu l e f 1 f 2 f 3 ( huidigeMakespan , huidigeF2 ,
huidigeF3 ) ;
626}627
628
629}630
631}632}633boolean l a s t 1 0 un f e a s i b l e=true ;
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 149
634i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )<10){635l a s t 1 0 un f e a s i b l e=fa l se ;
636} else {637for ( Boolean k : l a s t 1 0 i t e r a t i o n s ) {638
639i f ( k . booleanValue ( ) ) {640l a s t 1 0 un f e a s i b l e=fa l se ;
641}642}643}644
645
646i f ( l a s t 1 0 un f e a s i b l e ) {647hor i zon++;
648l a s t 1 0 i t e r a t i o n s . c l e a r ( ) ;
649}650
651Task . upda t eP r i o r i t e i t e n ( ) ;
652}653
654IOExcel . s ch r i j fDa taNaa rF i l e ( ) ;
655System . out . p r i n t l n ( ) ;
656System . out . p r i n t l n ( ”Best b e r e i k t e makespan : ”+besteMakespan ) ;
657System . out . p r i n t l n ( ”Best b e r e i k t e f 2 ( ba lance ) : ”+besteF2 ) ;
658System . out . p r i n t l n ( ”Best b e r e i k t e f 3 ( s l a ck nr e inde ) : ”+besteF3 ) ;
659System . out . p r i n t l n ( ) ;
660System . out . p r i n t l n ( IOExcel . s t o c k e e r s t a r t t i j d e n . s i z e ( )+” schedu l e s geschreven in
shee t ’ Resu l t s ’ van f i l e ’ ”+IOExcel . f i l ename+” ’ . ” ) ;
661System . out . p r i n t l n ( ) ;
662
663}664
665public stat ic void swoMetBulldozingF2F3 ( int a a n t a l I t e r a t i e s ) {666int lowerbound=Task . zoekMinimaleHorizon ( ) ;
667int hor i zon=lowerbound ;
668IOExcel . stockeerLowerbound ( lowerbound ) ;
669int besteMakespan = −1;
670double besteF2=−1;
671int besteF3=−1;
672ArrayList<Boolean> l a s t 1 0 i t e r a t i o n s = new ArrayList<Boolean>(10) ;
673IOExcel . s t o cke e rWegs ch r i j f vo l go rde ( ) ;
674
675int t i enp ro c en t=a a n t a l I t e r a t i e s /10 ;
676int t i e n p r o c e n t t e l l e r =0;
677
678System . out . p r i n t l n ( ) ;
679System . out . p r i n t l n ( a a n t a l I t e r a t i e s+” i t e r a t i e s u i t te voeren door SWO met
bu l ldoz ing , wegschr i jven bes t e f1>f2>f 3 . ” ) ;
680
681Task . i n i t i a l i s e e r P r i o r i t e i t e n ( ) ;
682
683for ( int i=0 ; i<a a n t a l I t e r a t i e s ; i++) {684
685i f ( i>( t i e n p r o c e n t t e l l e r ∗ t i enp ro c en t ) ) {686System . out . p r i n t l n ( ” Voortgang ”+( t i e n p r o c e n t t e l l e r ∗10)+”%” ) ;
687t i e n p r o c e n t t e l l e r++;
688}689
690boolean f e a s i b l e=true ;
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 150
691Task . zetHor izon ( hor i zon ) ;
692Task . r e s e tA l lTask s ( ) ;
693Task . resetWindows ( ) ;
694Task . w i n d ow I n i t i a l i s a t i e ( ) ;
695
696for (Task j : Task . l i j s t ) {697i f ( ! j . scheduleMetBul ldoz ing ( ) ) {698f e a s i b l e=fa l se ;
699}700}701
702
703i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )==10){704l a s t 1 0 i t e r a t i o n s . remove (0 ) ;
705}706l a s t 1 0 i t e r a t i o n s . add (new Boolean ( f e a s i b l e ) ) ;
707
708i f ( f e a s i b l e ) {709int huidigeMakespan=Task . bepaalMakespan ( ) ;
710double huidigeF2=Task . bepaalF2 ( huidigeMakespan ) ;
711int huidigeF3=Task . bepaalF3 ( huidigeMakespan ) ;
712
713i f ( huidigeMakespan<besteMakespan | | besteMakespan==−1){714besteMakespan=huidigeMakespan ;
715besteF2=huidigeF2 ;
716besteF3=huidigeF3 ;
717IOExcel . w i sGestockeerdeResu l taten ( ) ;
718IOExcel . s t o c k e e r S ch edu l e f 1 f 2 f 3 ( huidigeMakespan , huidigeF2 , huidigeF3 ) ;
719} else i f ( huidigeMakespan==besteMakespan ) {720i f ( huidigeF2<besteF2 ) {721besteF2=huidigeF2 ;
722besteF3=huidigeF3 ;
723IOExcel . w i sGestockeerdeResu l taten ( ) ;
724IOExcel . s t o c k e e r S ch edu l e f 1 f 2 f 3 ( huidigeMakespan , huidigeF2 , huidigeF3
) ;
725} else i f ( huidigeF2==besteF2 ) {726i f ( huidigeF3<besteF3 ) {727besteF3=huidigeF3 ;
728IOExcel . w i sGestockeerdeResu l taten ( ) ;
729IOExcel . s t o c k e e r S ch edu l e f 1 f 2 f 3 ( huidigeMakespan , huidigeF2 ,
huidigeF3 ) ;
730} else i f ( huidigeF3==besteF3 ) {731IOExcel . s t o c k e e r S ch edu l e f 1 f 2 f 3 ( huidigeMakespan , huidigeF2 ,
huidigeF3 ) ;
732}733
734
735}736
737}738}739
740boolean l a s t 1 0 un f e a s i b l e=true ;
741i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )<10){742l a s t 1 0 un f e a s i b l e=fa l se ;
743} else {744for ( Boolean k : l a s t 1 0 i t e r a t i o n s ) {745
746i f ( k . booleanValue ( ) ) {
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 151
747l a s t 1 0 un f e a s i b l e=fa l se ;
748}749}750}751
752
753i f ( l a s t 1 0 un f e a s i b l e ) {754hor i zon++;
755l a s t 1 0 i t e r a t i o n s . c l e a r ( ) ;
756}757
758Task . upda t eP r i o r i t e i t e n ( ) ;
759}760
761IOExcel . s ch r i j fDa taNaa rF i l e ( ) ;
762System . out . p r i n t l n ( ) ;
763System . out . p r i n t l n ( ”Best b e r e i k t e makespan : ”+besteMakespan ) ;
764System . out . p r i n t l n ( ”Best b e r e i k t e f 2 ( ba lance ) : ”+besteF2 ) ;
765System . out . p r i n t l n ( ”Best b e r e i k t e f 3 ( s l a ck nr e inde ) : ”+besteF3 ) ;
766System . out . p r i n t l n ( ) ;
767System . out . p r i n t l n ( IOExcel . s t o c k e e r s t a r t t i j d e n . s i z e ( )+” schedu l e s geschreven in
shee t ’ Resu l t s ’ van f i l e ’ ”+IOExcel . f i l ename+” ’ . ” ) ;
768System . out . p r i n t l n ( ) ;
769
770}771
772public stat ic void swoMetBul ldoz ingRef i l l ingF2F3 ( int a a n t a l I t e r a t i e s ) {773int lowerbound=Task . zoekMinimaleHorizon ( ) ;
774int hor i zon=lowerbound ;
775IOExcel . stockeerLowerbound ( lowerbound ) ;
776int besteMakespan = −1;
777double besteF2=−1;
778int besteF3=−1;
779ArrayList<Boolean> l a s t 1 0 i t e r a t i o n s = new ArrayList<Boolean>(10) ;
780IOExcel . s t o cke e rWegs ch r i j f vo l go rde ( ) ;
781
782int t i enp ro c en t=a a n t a l I t e r a t i e s /10 ;
783int t i e n p r o c e n t t e l l e r =0;
784
785System . out . p r i n t l n ( ) ;
786System . out . p r i n t l n ( a a n t a l I t e r a t i e s+” i t e r a t i e s u i t te voeren door SWO met
bu l l doz ing en r e f i l l i n g , wegschr i jven bes t e f1>f2>f 3 . ” ) ;
787
788
789Task . i n i t i a l i s e e r P r i o r i t e i t e n ( ) ;
790
791for ( int i=0 ; i<a a n t a l I t e r a t i e s ; i++) {792
793i f ( i>( t i e n p r o c e n t t e l l e r ∗ t i enp ro c en t ) ) {794System . out . p r i n t l n ( ” Voortgang ”+( t i e n p r o c e n t t e l l e r ∗10)+”%” ) ;
795t i e n p r o c e n t t e l l e r++;
796}797
798boolean f e a s i b l e=true ;
799Task . zetHor izon ( hor i zon ) ;
800Task . r e s e tA l lTask s ( ) ;
801Task . resetWindows ( ) ;
802Task . w i n d ow I n i t i a l i s a t i e ( ) ;
803
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 152
804for (Task j : Task . l i j s t ) {805i f ( ! j . s chedu l eMetBu l l doz ingRe f i l l i ng ( ) ) {806f e a s i b l e=fa l se ;
807}808}809
810i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )==10){811l a s t 1 0 i t e r a t i o n s . remove (0 ) ;
812}813l a s t 1 0 i t e r a t i o n s . add (new Boolean ( f e a s i b l e ) ) ;
814
815i f ( f e a s i b l e ) {816int huidigeMakespan=Task . bepaalMakespan ( ) ;
817double huidigeF2=Task . bepaalF2 ( huidigeMakespan ) ;
818int huidigeF3=Task . bepaalF3 ( huidigeMakespan ) ;
819
820i f ( huidigeMakespan<besteMakespan | | besteMakespan==−1){821besteMakespan=huidigeMakespan ;
822besteF2=huidigeF2 ;
823besteF3=huidigeF3 ;
824IOExcel . w i sGestockeerdeResu l taten ( ) ;
825IOExcel . s t o c k e e r S ch edu l e f 1 f 2 f 3 ( huidigeMakespan , huidigeF2 , huidigeF3 ) ;
826} else i f ( huidigeMakespan==besteMakespan ) {827i f ( huidigeF2<besteF2 ) {828besteF2=huidigeF2 ;
829besteF3=huidigeF3 ;
830IOExcel . w i sGestockeerdeResu l taten ( ) ;
831IOExcel . s t o c k e e r S ch edu l e f 1 f 2 f 3 ( huidigeMakespan , huidigeF2 , huidigeF3
) ;
832} else i f ( huidigeF2==besteF2 ) {833i f ( huidigeF3<besteF3 ) {834besteF3=huidigeF3 ;
835IOExcel . w i sGestockeerdeResu l taten ( ) ;
836IOExcel . s t o c k e e r S ch edu l e f 1 f 2 f 3 ( huidigeMakespan , huidigeF2 ,
huidigeF3 ) ;
837} else i f ( huidigeF3==besteF3 ) {838IOExcel . s t o c k e e r S ch edu l e f 1 f 2 f 3 ( huidigeMakespan , huidigeF2 ,
huidigeF3 ) ;
839}840
841
842}843
844}845}846
847boolean l a s t 1 0 un f e a s i b l e=true ;
848i f ( l a s t 1 0 i t e r a t i o n s . s i z e ( )<10){849l a s t 1 0 un f e a s i b l e=fa l se ;
850} else {851for ( Boolean k : l a s t 1 0 i t e r a t i o n s ) {852
853i f ( k . booleanValue ( ) ) {854l a s t 1 0 un f e a s i b l e=fa l se ;
855}856}857}858
859
B.12 Klasse ’SchedulingAlgoritmes’ (Overkoepelende structuur) 153
860i f ( l a s t 1 0 un f e a s i b l e ) {861hor i zon++;
862l a s t 1 0 i t e r a t i o n s . c l e a r ( ) ;
863}864
865Task . upda t eP r i o r i t e i t e n ( ) ;
866}867
868IOExcel . s ch r i j fDa taNaa rF i l e ( ) ;
869System . out . p r i n t l n ( ) ;
870System . out . p r i n t l n ( ”Best b e r e i k t e makespan : ”+besteMakespan ) ;
871System . out . p r i n t l n ( ”Best b e r e i k t e f 2 ( ba lance ) : ”+besteF2 ) ;
872System . out . p r i n t l n ( ”Best b e r e i k t e f 3 ( s l a ck nr e inde ) : ”+besteF3 ) ;
873System . out . p r i n t l n ( ) ;
874System . out . p r i n t l n ( IOExcel . s t o c k e e r s t a r t t i j d e n . s i z e ( )+” schedu l e s geschreven in
shee t ’ Resu l t s ’ van f i l e ’ ”+IOExcel . f i l ename+” ’ . ” ) ;
875System . out . p r i n t l n ( ) ;
876}877}
BIBLIOGRAFIE 154
Bibliografie
M. Bartusch, R. Mohring & F. Radermacher (1988). Scheduling project networks with
resource constraints and time windows. Annals of Operations research, 16:201–240.
J. Blazewicz, J. Lenstra & A. R. Kan (1983). Scheduling subject to resource constraints:
Classification and complexity. Discrete Applied Mathematics, 5:11–24.
K. Brinkmann & K. Neumann (1996). Heuristic procedures for resource-constrained
project scheduling with minimal and maximal time lags: the minimum project-
duration and resource-levelling problem. Journal of Decision Systems, 5:129–156.
P. Brucker, A. Drexl, R. Mohring, K. Neumann & E. Pesch (1999). Resource-
constrained project scheduling: Notation, classification, models, and methods. Eu-
ropean journal of operational research, 112:3–41.
P. Brucker, S. Knust, A. Schoo & O.Thiele (1998). A branch and bound algorithm for
the resource-constrained project scheduling problem. European journal of operational
research, 107(2):272–288.
A. Cesta, A. Oddi & S. F. Smith (2002). A constraint-based method for project
scheduling with time windows. Journal of Heuristics, 8:109–136.
E. Davis (1978). Project scheduling under resource constraints: Historical review and
categorization of procedures. AIIE Transactions, 5-4:297–313.
B. De Reyck & W. Herroelen (1997). A branch-and-bound procedure for the resource-
constrained project scheduling problem with generalized precedence constraints.
Operations Research, 45(2):201–212.
B. De Reyck & W. Herroelen (1999). The multi-mode resource-constrained project
scheduling problem with generalized precedence relations. European Journal of Ope-
rational Research, 119:538–556.
M. Dorigo, V. Maniezzo & A. Colorni (1996). The ant system: optimization by a
colony of cooperating agents. IEEE Transactions on Systems, Man and Cybernetics,
Part B, 26:29–41.
BIBLIOGRAFIE 155
S. Elmaghraby (1977). Activity networks: Project planning and control by network
models. Wiley, New York.
S. Elmaghraby (1994). Activity nets: A guided tour of some recent development.
European journal of operational research, 82:383–408.
B. Franck & K. Neumann (1996). Priority-rule methods for the resource-constrained
project scheduling problem with minimal and maximal time lags: an empirical ana-
lysis. Proceedings of the Fifth International Workshop on Project Management and
Scheduling, April 11-13, Poznan, pp. 88–91.
B. Franck, K. Neumann & C. Schwindt (2001). Truncated branch-and-bound, schedule-
construction and schedule-improvement procedures for resourc-econstrained project
scheduling. OR spektrum, 23:297–324.
F. Glover (1989a). Tabu search - part i. ORSA journal on computing, 1:190–260.
F. Glover (1989b). Tabu search - part ii. ORSA journal on computing, 2:4–32.
E. Goldratt & J. Cox (1984). The goal. Great Barrington, MA, North River Press
Publishing Corporation.
S. Hartmann & R. Kolisch (2000). Experimental evaluation of state-of-the-art heuris-
tics for the resource-constrained project scheduling problem. European Journal of
Operational Research, 127:394–407.
W. Herroelen (1972). Resource-constrained project scheduling: The state of the art.
Journal of the Operational Research Society, 23:261–275.
W. Herroelen, B. D. Reyck & E. Demeulemeester (1998). Resource-constrained project
scheduling: A survey of recent developments. Computers and Operations Research,
25(4):279–302.
H. Holland (1975). Adaptation in natural and artificial systems. University of Michigan
Press, Ann Arbor.
O. Icemeli, S. Erengul & C. Zappe (1993). Project scheduling problems: a survey.
Journal of the Operational Research Society, 13:80–91.
S. Kirkpatrick, C. Gelatt & M. Vecchi (1983). Optimization by simulated annealing.
Science, 220:671–680.
R. Kolisch (1996a). Efficient priority rules for the resource-constrained project sche-
duling problem. Journal of Operations Management, 14:179–192.
BIBLIOGRAFIE 156
R. Kolisch (1996b). Serial and parallel resource-constrained project scheduling methods
revisited: Theory and computation,. European Journal of Operational Research,
90:320–333.
R. Kolisch & S. Hartmann (1999). Heuristic algorithms for solving the resource-
constrained project scheduling problem: Classification and computational analysis.
In J. Weglarz, editor, Project Scheduling: Recent Models, algorithms and applicati-
ons, pp. 147–178. Kluwer academic publishers.
R. Kolisch & S. Hartmann (2006). Experimental investigation of heuristics for the
resource-constrained project scheduling: An update. European Journal of Operatio-
nal Research, 174:23–37.
H. Mausser & S. Lawrence (1998). Exploiting block structures to improve resource-
constrained project schedules. Metaheuristics.
D. Merkle, M. Middendorf & H. Schmeck (2002). Ant colony optimization for resource-
constrained project scheduling. IEEE Transactions on Evolutionary Computations,
6:333–346.
K. Neumann, & J. Zimmerman (1999a). Methods for resource-constrained project
scheduling with regular and non-regular objective functions and schedule-dependent
time windows. In J. Weglarz, editor, Project Scheduling: Recent Models, algorithms
and applications, pp. 147–178. Kluwer academic publishers.
K. Neumann, & J. Zimmerman (1999b). Procedures for resource levelling and net
present value problems in project scheduling with general temproal and resource
constraints. European journal of operational research, 127:425–443.
K. Neumann, & J. Zimmerman (1999c). Resource levelling for projects with schedule-
dependent time windows. European journal of operational research, 117:591–605.
K. Neumann, C. Schwindt & J. Zimmerman (2002). Recent results on resource-
constrained project scheduling with time windows: Models, solution methods and
applications. Central European Journal of Operations Research, 10(2):113–149.
K. Neumann, C. Schwindt & J. Zimmermann (2003). Project Scheduling with Time
Windows and Scarce Resources. Springer-Verlag Berlin and Heidelberg GmbH and
Co. K.
K. Neumann & J. Zhan (1995). Heuristics for the minimum project-duration problem
with minimal and maximal time lags under fixed resource constraints. Journal of
intelligent manufacturing, 6:145–154.
BIBLIOGRAFIE 157
O. Oguz & H. Bala (1994). A comparative study of computational procedures for the
resource-constrained project scheduling problem. European journal of operational
research, 72(2):406–416.
A. B. Pritsker, L. J. Watters & P. M. Wolfe (2000). Multiproject scheduling with limited
resources: A zero-one programming approach. Management Science, 16(1):93–108.
S. Sampson & E. Weiss (1993). Local search techniques for the generalized resource
constrained project scheduling problem. Naval Research Logistics, 40:665–675.
C. Schwindt (1998). Verfahren zur losung des ressourcenbeschrankten projectdauermi-
nimierungsproblems mit planungsabhangingen zeitfenstern. Shaker-Verlag, Aachen.
C. Schwindt & K. Neumann (1996). A new branch-and-boundbased heuristic for
resource-constrained project scheduling with minimal and maximal time lags. Pro-
ceedings of the Fifth International Workshop on Project Management and Scheduling,
April 11-13, Poznan, pp. 212–215.
T. Selle & J. Zimmermann (2000). A bidirectional heuristic for maximizing the net
present value of large-scale projects subject to limited resources. Report WIOR-599,
University of Karlsruhe.
S. Shingo (1985). A revolution in Manufacturing: the SMED system. Cambridge, MA,
Productivity Press.
L. Shixin & W. Mengguang (2000). An object-oriented methodology for solving the rc-
psps with heuristics and metaheuristics. Production planning and Control, 11(5):434–
442.
T. Smith (2004). Window-based Project Scheduling Algorithms. Ph.D. thesis, University
of Oregon.
A. Sprecher, R. Kolisch & A. Drexl (1995). Semi-active, active, and non-delay sche-
dules for the resource-constrained project scheduling problem. European Journal of
Operational Research, 80:94–102.
S. K. T. Baar, P. Brucker (1997). Tabu-search algorithms for the resource-constrained
project scheduling problem. Technical Report, Universitat Osnabruck.
D. Van Goubergen (2000). Set-up reduction as an organization-wide problem. IIE
Solutions 2000, Cleveland, OH., USA, Institute of Industrial Engineers.
D. Van Goubergen (2001). Een methodologie voor omsteltijdreductie van multi-machine
productielijnen. Ph.D. thesis, Universiteit Gent.
BIBLIOGRAFIE 158
R. Willis (1985). Critical path analysis and resource-constrained project scheduling -
theory and practice. European journal of Operations Research, 21.
L. Ozdamar & G. Ulusoy (1995). A survey on the resource-constrained project sche-
duling problem. IIE Transactions, 27(5):574–586.
J. Zhan (1994). Heuristics for scheduling resource-constrained projects in mpm net-
works. European Journal of Operational Research, 76:192–205.
LIJST VAN FIGUREN 159
Lijst van figuren
1.1 Overzicht van de SMED-methode . . . . . . . . . . . . . . . . . . . . . 5
1.2 Multi-machineschema naar Van Goubergen (2001) . . . . . . . . . . . . 6
1.3 Multi-persoonschema naar Van Goubergen (2001) . . . . . . . . . . . . 7
1.4 (N,M)-omstellingen: reductiemethode (Van Goubergen, 2001) . . . . . 8
1.5 Multi-machineschema bij ontkoppelde machines (naar Van Goubergen
(2001)) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1 Flowchart van algoritme A1 (naar Van Goubergen (2001)) . . . . . . . 20
2.2 Flowchart van algoritme A2 (naar Van Goubergen (2001)) . . . . . . . 23
4.1 Voorbeeld van een constraint graph met minimum-lags . . . . . . . . . 48
4.2 Eenvoudige constraint-graph . . . . . . . . . . . . . . . . . . . . . . . . 51
4.3 Voorbeeld: Zelf-constrainende soft-windows . . . . . . . . . . . . . . . . 56
4.4 Voorbeeld: Profiel van resource k met Tmax = 5 . . . . . . . . . . . . . 58
4.5 Voorbeeld: nut van refilling-mechanisme . . . . . . . . . . . . . . . . . 69
4.6 Voorbeeld: Swo-basisalgoritme vindt feasible schedule na 3 iteraties . . 70
4.7 Voorbeeld: Swo-Met-Bulldozing vindt feasible maar niet-optimaal
schedule na 1 iteratie . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.8 Voorbeeld: Swo-Met-Bulldozing-Refilling kan het laatste sche-
dule uit fig. 4.7 verbeteren . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.1 De sheet opties van de input-template case 1 . . . . . . . . . . . . . . . 79
5.2 De sheet taken van input Case 1 . . . . . . . . . . . . . . . . . . . . . . 79
5.3 De sheet PD van input Case 1 . . . . . . . . . . . . . . . . . . . . . . . 80
5.4 De sheet DJ van input Case 1 . . . . . . . . . . . . . . . . . . . . . . . 80
5.5 Geımplementeerde Java-classes . . . . . . . . . . . . . . . . . . . . . . 81
6.1 Multi-machine schema case 1-4 . . . . . . . . . . . . . . . . . . . . . . 89
6.2 Multi-machine schema case 2-1 . . . . . . . . . . . . . . . . . . . . . . 91
6.3 Multi-machine schema Case 2-1 . . . . . . . . . . . . . . . . . . . . . . 92
A.1 Precedence-relaties case 1 (Van Goubergen, 2001) . . . . . . . . . . . . 99
LIJST VAN FIGUREN 160
A.2 Precedence-relaties case 2 (Van Goubergen, 2001) . . . . . . . . . . . . 104
A.3 Precedence-relaties case 3 (Van Goubergen, 2001) . . . . . . . . . . . . 108
B.1 Overzicht van de klasse-structuur . . . . . . . . . . . . . . . . . . . . . 111
LIJST VAN TABELLEN 161
Lijst van tabellen
2.1 Resultaten van Van Goubergen (2001) voor case 1-1 . . . . . . . . . . . 24
2.2 Resultaten van Van Goubergen (2001) voor case 1-2 . . . . . . . . . . . 25
2.3 Resultaten van Van Goubergen (2001) voor case 1-3 . . . . . . . . . . . 26
2.4 Resultaten van Van Goubergen (2001) voor case 1-4 . . . . . . . . . . . 26
2.5 Resultaten van Van Goubergen (2001) voor case 2-1 . . . . . . . . . . . 27
2.6 Resultaten van Van Goubergen (2001) voor case 2-2 . . . . . . . . . . . 27
2.7 Resultaten van Van Goubergen (2001) voor case 3 . . . . . . . . . . . . 28
6.1 Resultaten heuristiek voor case 1-4 . . . . . . . . . . . . . . . . . . . . 88
6.2 Resultaten heuristiek voor case 2-1 . . . . . . . . . . . . . . . . . . . . 90
6.3 Resultaten heuristiek voor case 2-2 . . . . . . . . . . . . . . . . . . . . 92
6.4 Resultaten heuristiek voor case 3 . . . . . . . . . . . . . . . . . . . . . 93
A.1 Gegevens activiteiten van case 1 voor SMED-toepassing . . . . . . . . . 99
A.2 Precedence-relaties van case 1 voor SMED-toepassing . . . . . . . . . . 100
A.3 Machine-disjuncties van case 1 voor SMED-toepassing . . . . . . . . . . 100
A.4 Gegevens activiteiten van case 1 na SMED-toepassing . . . . . . . . . . 101
A.5 Gegevens activiteiten van case 1 na SMED, met gewijzigde Relt(m) . . 102
A.6 Gegevens activiteiten van case 2 na SMED-1 . . . . . . . . . . . . . . . 104
A.7 Precedence-relaties van case 2 na SMED-1 . . . . . . . . . . . . . . . . 105
A.8 Machine-disjuncties van case 2 na SMED-1 . . . . . . . . . . . . . . . . 105
A.9 CS-set van case 2 na SMED-1 . . . . . . . . . . . . . . . . . . . . . . . 105
A.10 Gegevens activiteiten van case 2 na SMED 2-3 . . . . . . . . . . . . . . 106
A.11 Gegevens activiteiten van case 3 . . . . . . . . . . . . . . . . . . . . . . 107
A.12 Precedence-relaties van case 1 voor SMED-toepassing . . . . . . . . . . 109
A.13 Machine-disjuncties van case 3 na SMED-1 . . . . . . . . . . . . . . . . 109
A.14 Disjuncties (andere dan machinedisjuncties) van case 3 na SMED-1 . . 110
Top Related