Buffer
A Buffer
is an object where tasks can load or unload a finite number of items. A Buffer
can be used to represent a tank, or a temporary buffer of a workshop where manufactured parts are temporarily stored.
A NonConcurrentBuffer
is a specific buffers where tasks cannot load and/or unload at the same time. In other words, only one task can access the buffer at a given time.
A NonConcurrentBuffer`
has three main attributes:
the
initial_level
, i.e. the number of items in the buffer for time t=0,the
lower_bound
, an optional parameter that sets the minimum number of items in the buffer during the schedule. If ever the solver cannot find a solution where the buffer level is always greater than thelower_bound
, it will report an unsatisfiable problem,the
upper_bound
, an optional parameter that sets the maximum number of items in the buffer during the schedule (in other words, the buffer capacity). If ever the solver cannot find a solution where the buffer level is always lower than theupper_bound
, it will report an unsatisfiable problem.
Both initial_level
, lower_bound
and upper_bound
are optional parameters. A NonConcurrentBuffer
can be created as follows:
buff1 = ps.NonConcurrentBuffer("Buffer1")
buff2 = ps.NonConcurrentBuffer("Buffer2", initial_state=10)
buff3 = ps.NonConcurrentBuffer("Buffer3", lower_bound=0)
buff4 = ps.NonConcurrentBuffer("Buffer4", upper_bound=20)
buff5 = ps.NonConcurrentBuffer("Buffer5",
initial_state=3,
lower_bound=0,
upper_bound=10)
Buffer constraints
Buffers are loaded/unloaded by tasks. As a consequence, special tasks constraints are used to connect tasks to buffers: TaskUnloadBuffer
and TaskLoadBuffer
. Both classes take the task instance, the target buffer, and a quantity
. Load/Unload constraints can be created as follows:
c1 = ps.TaskUnloadBuffer(task_1, buffer, quantity=3)
c2 = ps.TaskUnloadBuffer(task_2, buffer, quantity=6)
# etc.
Note
There is no limitation on the number of buffers and/or buffer constraints.
Example
Let’s take an example where a task T1
uses a machine M1
to manufacture a part (duration time for this task is 4). It takes one part in a Buffer1
and loads the Buffer2
.
machine_1 = ps.Worker('M1')
task_1 = ps.FixedDurationTask('T1', duration=4)
task_1.add_required_resource(machine_1)
# the create buffers
buffer_1 = ps.NonConcurrentBuffer("Buffer1", initial_state=5)
buffer_2 = ps.NonConcurrentBuffer("Buffer2", initial_state=0)
# buffer constraints
c1 = ps.TaskUnloadBuffer(task_1, buffer_1, quantity=1)
c2 = ps.TaskLoadBuffer(task_1, buffer_2, quantity=1)
The graphical output shows the Gantt chart and the evolution of the buffer states along the time line.