Task Constraints¶
The ProcessScheduler framework provides a powerful set of predefined temporal task constraints to facilitate the expression of common scheduling rules efficiently. These constraints empower you to articulate task-related regulations, such as fixed start times, synchronized endings, precedence relationships, and more.
The TaskConstraint
class is a specialized extension of the generic Constraint
class, forming the foundation for expressing task-related scheduling rules.
classDiagram
Constraint <|-- TaskConstraint
Note
Constraint names that start with Task*
apply to a single task, while those starting with Tasks***
apply to two or more task instances.
Note
All Task constraints can be defined as either mandatory or optional. By default, constraints are mandatory (parameter optional=False). If you set the optional attribute to True, the constraint becomes optional and may or may not apply based on the solver's discretion. You can force the schedule to adhere to an optional constraint using the task.applied attribute:
Groups¶
Ordered task group¶
Unordered task group¶
Single task temporal constraints¶
These constraints apply to individual tasks.
classDiagram
TaskConstraint <|-- TaskStartAt
TaskConstraint <|-- TaskStartAfter
TaskConstraint <|-- TaskEndAt
TaskConstraint <|-- TaskEndBefore
class TaskStartAt{
+Task task
+int value
}
class TaskStartAfter{
+Task task
+int value
+str kind
}
class TaskEndAt{
+Task task
+int value
}
class TaskEndBefore{
+Task task
+int value
+str kind
}
Type | Math | Description |
---|---|---|
TaskStartAt | \(task.start = value\) | starts exactly at the instant value |
TaskStartAfter | \(task.start >= value\) | task must start after a given time instant |
TaskEndAt | \(task.end = value\) | task ends exactly at the specified time instant. |
TaskEndBefore | \(task.end <= value\) | task ends before or at a given time instant |
TaskStart/End/After/Before
constraint can be strict (\(>\),\(<\)) or lax (\(>=\),\(<=\)) whether the kind
argument is set to 'lax'
or 'strict'
. The default value is 'lax'
.
Example:
task1 = FixedDurationTask(name="Task1", duration=10)
TaskStarAfter(task= task1, value=7, kind="strict")
Two tasks temporal constraints¶
These constraints apply to sets of two tasks.
classDiagram
TaskConstraint <|-- TaskPrecedence
TaskConstraint <|-- TasksStartSynced
TaskConstraint <|-- TasksEndSynced
TaskConstraint <|-- TasksDontOverlap
class TaskPrecedence{
+Task task_before
+Task task_after
+str kind
+int offset
}
TaskPrecedence¶
Ensures that one task is scheduled before another. The precedence can be either 'lax,' 'strict,' or 'tight,' and an optional offset can be applied.
The TaskPrecedence
class takes two parameters task_1
and task_2
and constraints task_2
to be scheduled after task_1
is completed. The precedence type can either be :const:'lax'
(default, task_2.start
>= task_1.end
)), :const:'strict'
(task_2.start
>= task_1.end
)) or :const:'tight'
(task_2.start
>= task_1.end
, task_2 starts immediately after task_1 is completed). An optional parameter offset
can be additionally set.
task_1 = ps.FixedDurationTask(name='Task1', duration=3)
task_2 = ps.FixedVariableTask(name='Task2')
pc = TaskPrecedence(task_before=task1,
task_after=task2,
kind='tight',
offset=2)
TasksStartSynced¶
Specify that two tasks must start at the same time.
TasksStartSynced
takes two parameters task_1
and task_2
such as the schedule must satisfy the constraint :math:task_1.start = task_2.start
TasksEndSynced¶
Specify that two tasks must end at the same time.
TasksEndSynced
takes two parameters task_1
and task_2
such as the schedule must satisfy the constraint :math:task_1.end = task_2.end
TasksDontOverlap¶
Ensures that two tasks should not overlap in time.
TasksDontOverlap
takes two parameters task_1
and task_2
such as the task_1 ends before the task_2 is started or the opposite (task_2 ends before task_1 is started)
Multiple tasks temporal constraints¶
TasksContiguous¶
Forces a set of tasks to be scheduled contiguously.
TasksContiguous
takes a liste of tasks, force the schedule so that tasks are contiguous.
UnorderedTaskGroup¶
An UnorderedTaskGroup represents a collection of tasks that can be scheduled in any order. This means that the tasks within this group do not have a strict temporal sequence.
OrderedTaskGroup¶
A set of tasks that can be scheduled in any order, with time bounds
Advanced tasks constraints¶
ScheduleNTasksInTimeIntervals¶
Schedules a specific number of tasks within defined time intervals.
Given a list of :math:m
tasks, and a list of time intervals, ScheduleNTasksInTimeIntervals
schedule :math:N
tasks among :math:m
in this time interval.
ResourceTasksDistance¶
Defines constraints on the temporal distance between tasks using a shared resource.
ResourceTasksDistance
takes a mandatory attribute distance
(integer), an optional time_periods
(list of couples of integers e.g. [[0, 1], [5, 19]]). All tasks, that use the given resource, scheduled within the time_periods
must have a maximal distance of distance
(distance being considered as the time between two consecutive tasks).
Note
If the task(s) is (are) optional(s), all these constraints apply only if the task is scheduled. If the solver does not schedule the task, these constraints does not apply.
Optional task constraints¶
OptionalTaskForceSchedule¶
Force an optional task to be (un)scheduled.
OptionalTaskConditionSchedule¶
Creates a constraint that schedules a task based on a specified Boolean condition.
OptionalTaskConditionSchedule
creates a constraint that adds a condition for the task to be scheduled. The condition is a z3 BoolRef
OptionalTasksDependency¶
OptionalTasksDependency
takes two optional tasks task_1
and task_2
, and ensures that if task_1 is scheduled then that task_2 is forced to be scheduled as well.
ForceScheduleNOptionalTasks¶
Forces the scheduling of a specified number of optional tasks out of a larger set of optional tasks.
ForceScheduleNOptionalTasks
forces :math:m
optional tasks among :math:n
to be scheduled, with :math:m \leq n
.