producer_consumer
producer_consumer |
Purpose
A Producer Consumer Scheduling constraint. More formally the constraint ensures that:
productionsj · durationsj = prodsizesj for all j in Tasks
consumptionsj · durationsj = consosizesj for all j in Tasks
∑j ∈ R | t ∈ [UB(startj)..LB(endj)] (productionsj - consumptionsj) ≤ Ct for all t in Times
Synopsis
function producer_consumer(starts:array(range) of cpvar, ends:array(range) of cpvar, durations:array(range) of cpvar, productions:array(range) of cpvar, prod_sizes:array(range) of cpvar, consumptions:array(range) of cpvar, conso_sizes:array(range) of cpvar, C:array(range) of integer) : cpctr
Arguments
|
starts
|
array of starting times
|
|
ends
|
array of ending times
|
|
durations
|
array of durations
|
|
productions
|
array of tasks' requirements
|
|
prod_sizes
|
array of tasks' productions
|
|
consumptions
|
array of tasks' provisions
|
|
conso_sizes
|
array of tasks' consumptions
|
|
C
|
initial resource capacity array indexed by time
|
Example
The following example shows how to use the producer_consumer constraint for the problem of planning the construction of a house (an example of resource-constrained project scheduling).
model "Cumulative Scheduling"
uses "kalis"
setparam("KALIS_DEFAULT_LB",0)
setparam("KALIS_DEFAULT_UB",100)
declarations
! Task indices
Masonry = 1; Carpentry= 2; Roofing = 3; Windows = 4
Facade = 5; Garden = 6; Plumbing = 7; Ceiling = 8
Painting= 9; MovingIn =10; InitialPayment=11; SecondPayment=12
BUILDTASKS = 1..10
PAYMENTS = 11..12
TASKS = BUILDTASKS+PAYMENTS
TNAMES: array(TASKS) of string
obj:cpvar ! Objective variable
starts : array(TASKS) of cpvar ! Start times variables
ends : array(TASKS) of cpvar ! Completion times
durations: array(TASKS) of cpvar ! Durations of tasks
consos : dynamic array(TASKS) of cpvar ! Res. consumptions
sizes : dynamic array(TASKS) of cpvar ! Consumption sizes
prods : dynamic array(TASKS) of cpvar ! Res. production
sizep : dynamic array(TASKS) of cpvar ! Production sizes
Strategy : cpbranching ! Branching strategy
end-declarations
TNAMES:: (1..12)["Masonry", "Carpentry", "Roofing", "Windows",
"Facade", "Garden", "Plumbing", "Ceiling", "Painting",
"MovingIn", "InitialPayment", "SecondPayment"]
! Setting the names of the variables
forall(j in TASKS) do
starts(j).name := TNAMES(j)+".start"
ends(j).name := TNAMES(j)+".end"
durations(j).name := TNAMES(j)+".duration"
end-do
! Creating consumption variables
forall(j in BUILDTASKS) do
create(sizes(j))
sizes(j).name := TNAMES(j)+".size"
create(consos(j))
consos(j).name := TNAMES(j)+".conso"
end-do
! Setting durations of building tasks
durations(Masonry) =7; durations(Carpentry)=3; durations(Roofing) =1
durations(Windows) =1; durations(Facade) =2; durations(Garden) =1
durations(Plumbing)=8; durations(Ceiling) =3; durations(Painting)=2
durations(MovingIn)=1
! Precedence constraints among building tasks
starts(Carpentry) >= ends(Masonry)
starts(Roofing) >= ends(Carpentry)
starts(Windows) >= ends(Roofing)
starts(Facade) >= ends(Roofing)
starts(Garden) >= ends(Roofing)
starts(Plumbing) >= ends(Masonry)
starts(Ceiling) >= ends(Masonry)
starts(Painting) >= ends(Ceiling)
starts(MovingIn) >= ends(Windows)
starts(MovingIn) >= ends(Facade)
starts(MovingIn) >= ends(Garden)
starts(MovingIn) >= ends(Painting)
! Setting task consumptions
consos(Masonry) = 7; consos(Carpentry) = 3; consos(Roofing) = 1
consos(Windows) = 1; consos(Facade) = 2; consos(Garden) = 1
consos(Plumbing) = 8; consos(Ceiling) = 3; consos(Painting) = 2
consos(MovingIn) = 1
! Production (amount) of payment tasks
forall(j in PAYMENTS) do
create(prods(j))
prods(j).name := TNAMES(j)+".prod"
create(sizep(j))
sizep(j).name := TNAMES(j)+".sizep"
end-do
! Payment data
prods(InitialPayment) = 20; prods(SecondPayment) = 9
durations(InitialPayment) = 1; durations(SecondPayment) = 1
starts(InitialPayment) = 0; starts(SecondPayment) = 15
! Objective: makespan of the schedule
obj = maximum({ ends(Masonry) , ends(Carpentry), ends(Roofing),
ends(Windows), ends(Facade), ends(Garden), ends(Plumbing),
ends(Ceiling), ends(Painting), ends(MovingIn)})
! Posting the producer_consumer constraint
producer_consumer(starts,ends,durations,prods,sizep,consos,sizes)
! Setting the search strategy
Strategy:= assign_var(KALIS_SMALLEST_MIN, KALIS_MIN_TO_MAX, starts)
cp_set_branching(Strategy)
! Find the optimal solution
if cp_minimize(obj) then
writeln("Minimum makespan: ", obj.sol)
forall(j in BUILDTASKS)
writeln(TNAMES(j), ": ", starts(j).sol, " - ", ends(j).sol)
else
writeln("No solution found")
end-if
end-model
Related topics
