Closed tpaviot closed 10 months ago
@tpaviot thank you for taking a go at this, it looks great.
From what I can surmise from the code (processscheduler/task.py), you're diving the task into unitary subtasks (each with a duration of 1 unit) and also adding a precedence constraint as well.
Do you think there is a way to ensure that the task will not be interrupted by another task? Somehow we need to say that no other task can be scheduled between the start and the end of breakable task although the lunch is also defined as a task.
In a similar attempt with Google OR Tools, I didn't break the task but instead used connecting variables and calculated the total task duration as the sum of task duration itself plus any resource breaks that fall between the task start and stop times. It is rather convoluted and not well documented at the moment.
I think there's an issue with the semantics of the "breakable task". You cannot represent a task that can be achieved in several time slots and, simultaneously, force the "breakable task" not to be "broken". There's something weird. Maybe it's because I don't have the use case. Another way would be to add a parameter that forces the BreakableTask to be broken over close time slots, for example, a task with a duration of 10 cannot exceed 15 between the start and the end.
Yes, it is a unique use case. It only come into use if the task being scheduled might be longer than the maximum shift duration. e.g. resources are available for 8 hours a day and we need to schedule a task that is 12 hours. Or a previous task ends at a time that cannot accommodate the next task and results in an unused capacity.
Thank you for implementing the breakable tasks. I think that one would be useful as well.
Patch coverage: 86.07
% and project coverage change: -0.12
:warning:
Comparison is base (
2572cd3
) 95.29% compared to head (4af8658
) 95.17%.
:exclamation: Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more.
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Do you have feedback about the report comment? Let us know in this issue.
This PR is a work in progress related to issues #117 and #124. A new class
BreakableFixedDurationTask
is created that can represent a task where time slots are not necessarily contiguous. The task with duration=n is split into n unitary tasks (unitary means duration is 1). For example:from processscheduler import * problem = SchedulingProblem("ShiftBreaks", horizon=10) worker = Worker("Worker") task = BreakableFixedDurationTask("Task", 5) task.add_required_resource(worker) # Lunch break lunch = FixedDurationTask("Lunch", duration=1) lunch.add_required_resource(worker) TaskStartAt(lunch, 4) solver = SchedulingSolver(problem) solution = solver.solve() solution.render_gantt_matplotlib()
results in the following Gant diagram
@itopaloglu83 and @asoral any feedback? would it fit your needs?
This makes a lot of sense now. I think this was the missing link. Splitting the task into unitary sub-tasks and arranging these subtasks on the horizon based on constraints was really what I wanted.
I will test this PR and update the status
@tpaviot thank you for taking a go at this, it looks great.
From what I can surmise from the code (processscheduler/task.py), you're diving the task into unitary subtasks (each with a duration of 1 unit) and also adding a precedence constraint as well.
Do you think there is a way to ensure that the task will not be interrupted by another task? Somehow we need to say that no other task can be scheduled between the start and the end of breakable task although the lunch is also defined as a task.
In a similar attempt with Google OR Tools, I didn't break the task but instead used connecting variables and calculated the total task duration as the sum of task duration itself plus any resource breaks that fall between the task start and stop times. It is rather convoluted and not well documented at the moment.
I have a scenario that I can think of, let me know if the below scenario is what you are referring to too-
@asoral your example would work okay and Task A would complete over the course of 3 working days and then the Task B would start.
However, imagine there was no dependency between Task A and B. And also due to some other constraint, Task B can only start one day after Task A. In that instance, the source might work on Task A first for one day, switch to Task B and work it to completion, and switch back to Task A. Which might not be okay under certain cases like manufacturing because switching between tasks sometimes require setup times etc. Depending on the task type, this can be very useful though.
Another approach to solving the same problem of task spanning multiple shifts would be to extend the apparent duration of the task until the work time of the resource is equal to task duration. e.g. this task takes 24 hours to complete but due to recourse breaks, it will start on Monday at 8am and end at Wednesday 5pm, which means it needs to stay on the schedule for 57 hours even though the work itself is 24 hours.
I tried it with 100 tasks with an average duration of 6hrs and it fails to give the output. It gives the below error and the process terminates
100 changes in 300 seconds. Saving... 18:19:17 redis_queue.1 | 48760:M 29 Jun 2023 18:19:17.049 * Background saving started by pid 50060 18:19:17 redis_queue.1 | 50060:C 29 Jun 2023 18:19:17.080 * DB saved on disk 18:19:17 redis_queue.1 | 50060:C 29 Jun 2023 18:19:17.081 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB 18:19:17 redis_queue.1 | 48760:M 29 Jun 2023 18:19:17.150 * Background saving terminated with success
@asoral I must be able to duplicate the issue in order to deeply study what is going on and provide a fix, your report does not contain enough information
This PR is a work in progress related to issues #117 and #124. A new class
BreakableFixedDurationTask
is created that can represent a task where time slots are not necessarily contiguous. The task with duration=n is split into n unitary tasks (unitary means duration is 1). For example:results in the following Gant diagram![breakable_task](https://github.com/tpaviot/ProcessScheduler/assets/660130/f411d9d4-34ef-4b74-ac5b-576af61c2840)
@itopaloglu83 and @asoral any feedback? would it fit your needs?