javaoptaplannertimefold

Problems when using SelectionFilter in multiple PlanningVariable scenarios


Now I create a solution A, a planning entity B and multiple planning variables(planning date and C).

@PlanningSolution
class A{
 @PlanningEntityCollectionProperty
  private List<B> bList;
}

@PlanningEntity
class B{
  @PlanningVariable(allowsUnassigned = true, valueRangeProviderRefs = "dateRange")
  private LocalDate planningDate;
  @PlanningVariable(allowsUnassigned = true, valueRangeProviderRefs = "cRange")
  private C c;

  @ValueRangeProvider(id = "cRange")
  private List<C> cList;

  @ValueRangeProvider(id = "dateRange")
  private List<LocalDate> availableDates
}

I hope that for a Planning Entity, when moving C, I can filter the value of planning date from a fixed date set with some fields of C, and when moving planning date, I can filter the value of C.

I saw SelectionFilter in the documentation, but the parameters passed in are the class of Solution and Planning Variable. I wonder if it can be adapted to this scenario?

And when Using SelectionFilter, a situation may occur: when the planning date set corresponding to C1 and the planning date set corresponding to C2 have no intersection, for a single planning entity, there is no way to switch from C1 to C2. I don't know if my understanding is correct.

Perhaps, should I use the Filtered move selection? Or any other better suggestions?

Are there any answers or suggestions? Looking forward to your reply.


Solution

  • I think you are taking a wrong turn in your thinking here. Value ranges are expected to be constant - you can not change them when something in the entity changes. Therefore you cannot make dateRange react to changes in c, nor can you make cRange react to changes in planningDate.

    You want those value ranges to be reasonable for all cases - and if some values don't make sense in a particular situation, use selection filtering to get rid of them.

    The interface of SelectionFilter is actually this:

    public interface SelectionFilter<Solution_, T> {
    
        boolean accept(ScoreDirector<Solution_> scoreDirector, T selection);
    
    }
    

    T can be anything - a move, an entity, a value. Based on where you're using the selection filter. The documentation gives examples of all three.