timefold.ai partial pinning

82 views Asked by At

I'm currently performing some tests with timefold.ai optimization java framework.

I have the following scenario: I have tasks that need to be executed on a specific time. However they are optional, they don't have to be scheduled. But if they are scheduled they have to start at a specific time.

Additionally there are other tasks (same type of tasks, so they are in the same collection) and representated by the same PlanningEntity that are completely flexibile, both in starting time and also whether they are scheduled at all.

Afaik regular pinning doesn't work as it pins the entire planning entity. My simplified setup looks something like this (Not including additional not relevant constraints).

@PlanningEntity
public class Task {

    @PlanningVariable(valueRangeProviderRefs = ["myValueRangeProvider"], nullable = true)
    private BigDecimal start;
  
    @PlanningPin
    private boolean pinned;

}
@PlanningSolution
class PlanningProblem {

    @ValueRangeProvider(id = "myValueRangeProvider")
    private CountableValueRange<BigDecimal> possibleStarts;

    @PlanningEntityCollectionProperty
    private List<Task> tasks;

}

Does someone have an idea how to nicely model it? Is there some way to partially pin variables? I also thought about having two planning variables, one isScheduled and another one start and somehow using a specific value range provider per entity, but I can only provide one per entity type I assume?

Thanks!

2

There are 2 answers

2
Geoffrey De Smet On

I would use a hard constraint.

In task assignment and vehicle routing, it's common to see minStart and maxStart:

class Task {
    LocalDateTime minStart;
    LocalDateTime maxStart;
    
    @PlanningVariable(allowsUnassigned=true)
    LocalDateTime start; // 15 minute granularity (time grain pattern)
}

If minStart and maxStart are both non-null and equal, it effectively pins the task to that time, or doesn't assign it all

enter image description here

0
Guillermo On

For completeness: The first solution I implemented that actually works is having a different range providers entity and to make the planning variable optional. Then you can also introduce a medium score level to incentivize that those tasks are scheduled at all. Basically combining these two: