Search code examples
pythonoptaplanneroptapy

Optapy How to deal with contraints with planning variable as a list


We are try to use EmployeeSchedule algorithm for n-n shift-employee schedule. But the algorithm assigns only one employee per shift. For this case we find that we need to use planning_variable_list decorator (as shown as in the vehicle algorihm) and with this decorator we update our domain class. But our constraints are not working after we do this updates and we couldn't find any example to use constraints like situation that we are in.

our constraint example:

def one_shift_per_day(constraint_factory: ConstraintFactory):
return constraint_factory \
    .for_each_unique_pair(Shift,
                          Joiners.equal(lambda shift: shift.employees),
                          Joiners.equal(lambda shift: shift.start.date())
                          ) \
    .penalize("Max one shift per day", HardSoftScore.ONE_HARD)

After we run the solition we are getting this error:

RuntimeError: An error occurred during solving. This can occur when functions take the wrong number of parameters (ex: a setter that does not take exactly one parameter) or by a function returning an incompatible return type (ex: returning a str in a filter, which expects a bool). This can also occur when an exception is raised when evaluating constraints/getters/setters.

If you may tell us that in the EmployeeSchedule how to do that we can manage to make it in our project


Solution

  • In Python, list is not hashable, meaning it cannot be used in Joiners (which require their arguments to be hashable). Additionally, the @planning_variable_list will probably not do what you expect it to do, since if you use it, each Employee can only be assigned one Shift (which is probably not what you want). If you know how many employees a Shift requires, you can solve the issue by creating N Shift instance for a shift that requires N employees.