tpaviot / ProcessScheduler

A Python package for automatic and optimized resource scheduling
https://processscheduler.github.io/
GNU General Public License v3.0
58 stars 17 forks source link

Define time spans periodically for ResourceUnavailable #141

Closed jbdyn closed 5 months ago

jbdyn commented 5 months ago

Hi!

I successfully started using your library in a self-made project visualizer. Super exciting! My inputs are the start date of a project phase, a config with worker availabilities (working days per week, holidays) and a handcrafted table with a task, its assignee, task dependencies and the estimated total time to completion on each row.
The BreakableTask also came in very handy here to represent continuous tasks with pause slots (weekends, non-working days etc.) in between.

My goal with that is now to get an estimate for the end date of the project phase with reasonably ordered tasks.

My problem now are the individual availabilities in my team: I need to roughly know in advance how long the project phase will take to have all the time spans in ResourceUnavailable defined in the whole (or most of the) time range the solver sees during calculation.
However, this adds a fair amount of constraints and thus often makes the solution fail or quite unstable. I am talking 3 people with weekly constraints (part-time working, the most part) and also irregular constraints (holidays, only few) being assigned to about 30 (breakable) tasks in total. I tried also with regular (not breakable) tasks, but the problem persists.

Since the unavailabilities occur periodically for the most part, I wondered whether it is possible to have periodic ResourceUnavailable constraints. These would still carry all the information to the solver with far less definitions.

Would that be possible?

tpaviot commented 5 months ago

@jbdyn thank you for your interesting feedback.

First of all, I realize that the BreakableTask was actually never merged into the master branch. How did you do to use it? Is it something I should add to the master branch?

Let me express your question using my words, and let me know if I'm right:

jbdyn commented 5 months ago

Ah, yes. I read the issue and PR discussion at that time and copied the respective Python code into my script to test it right away.

It was a nice shortcut for me.
My motivation is the following:

Another approach I could think of is to redefine my tasks such that they are all unary in the first place. This would avoid BreakableTasks and be nice for the solver, but a lot harder for me: It kind of distorts the time estimation and I would get many more task definitions which are hard to track by eye (Does the set of individual tasks really reflect the actual result I want to achieve? Did I forget something? etc.).
So instead of me formulating unary tasks by myself I would love to have a BreakableTask in master which does that for me.

Yes, you are correct. That is exactly my case.

tpaviot commented 5 months ago

ok, thank you. I see two ways to proceed:

The first solution is the BreakableTask, I think the second solution is more elegant. what to you think?

jbdyn commented 5 months ago

I like the idea of a "rubber-band" task very much. This would then base VariableDurationTask, maybe?

However, I would not add an additional parameter to add_required_resource and instead take the busy intervals from the given Resource object W1 directly.

tpaviot commented 5 months ago

I'm not sure it is possible to start from the busy intervals of the Resource.

The "rubber-band" task (I like the metaphor) applies to a specific kind of task: a task that can be paused, for a short/long time, or interrupted. If ever the task can be interrupted, then this rubber-band strategy can be applied (ie the task can overlap resource unavailabilities, its completion time is just delayed). Otherwise the task can not be paused and the current behaviour is ok (the task is scheduled between resource unavailabilities).