Search code examples
optaplanner

Optaplanner, use of @ValueRangeProvider


I need some help on the use of @ValueRangeProvider inside a @PlanningEntity

I have used the nursingShift example principle, where the Plannningsolution is instantiated by a rest service call, it then gets all the data, fact, ect via Hibernate and creates a solution.

SolverJob<MySolution, Long> res = solverManager.solveAndListen(MySolutionRepository.SINGLETON_SOLUTION_TABLE_ID,
                mySolutionRepository::findById,
                mySolutionRepository::save
                );

This solution then gets all the facts, data, etc. and start the solver. But once inside a class, I need to restrict the possible employees that can be assigned to a meeting by accessing the PlanningSolution, which has the list of Employees and filter it. I'm trying to solve it with 4.3.5.2.3. the @ValueRangeProvider inside the @PlanningEntity depending on the type of employee, but not sure how to get a ref, back to the original list that has all the original employees? Also should there be the @ValueRangeProvider in both the planningentity and planningsolution or only the first.

        @PlanningSolution
        public class MySolution {
            ...
            @ValueRangeProvider
            @ProblemFactCollectionProperty
            private List<Employee> employeeList;
    
            @PlanningEntityCollectionProperty
            private List<Meeting> MeetingList;
        ...

}

    @PlanningEntity
    public class Meeting{
        ...
        @PlanningVariable (nullable = true)
        private Employee employee;
        ...
         @ValueRangeProvider
        public List<Employee> getFilteredEmployeeList() {
            
            "Get the original list from MySolution by some reference or build in auto-detection in optaplaner and filter it, based on the employees type"
            
            return employeeList;
        }
    }   

Solution

  • The best solution will depend on the type of limitation you want to implement:

    • If any employee can be assigned to any meeting just keep valueRangeProvider at PlanningSolution level
    • If there is some meeting specific limitation start with implementing it as constraint
    • Only if constraint does not work well for you, should you create PlanningEntity level value provider. The easiest way will be precalculate List of possible values at problem generation time and simply return it as valueRangeProvide. In this case you do not need ValueRangeProvider at PlanningSolution level