Vasco Ferreira
Vasco Ferreira

Reputation: 43

Optaplanner built-in hard constraints continuous planning

Currently I'm doing continuous planning, and I have two entities, one is the machine and the other one is the order. The machine contains a planning list variable and the order has an inverse shadow variable pointing to the machine. I want to add a built-in hard constraint to limit to what machines a certain order can go, however I cannot use the ValueRangeProvider in the machine entity to filter out the orders list because it cannot be used inside an entity. Is there another way to do this? Thanks in advance

Upvotes: 1

Views: 209

Answers (1)

yurloc
yurloc

Reputation: 2358

Indeed, entity-dependent value ranges do not work with planning list variables. There is no plan to support that in the near future.

You can still achieve the desired built-in hard constraint by using filtered move selection.

You'll typically need three SelectionFilter implementations, one for each move type. I assume you want to use the Construction Heuristic phase, which has the ListAssignMove and you want to have both ListChangeMove and ListSwapMove in your Local Search phase.

Then, you'll need an advanced solver configuration to apply those filter.

I've tried this approach on the TaskAssignment example to replace the noMissingSkills constraint in the TaskAssigningConstraintProvider and make it a built-in hard constraint using move filtering. This is what I ended up with:

Filters

These should also work in your case if you just change Employee to Machine, Task to Order and rename the isTaskAllowed() to better fit your domain.

public class TaskAssignMoveFilter implements SelectionFilter<TaskAssignment, ListAssignMove<TaskAssignment>> {

    @Override
    public boolean accept(ScoreDirector<TaskAssignment> scoreDirector, ListAssignMove<TaskAssignment> move) {
        return ((Employee) move.getDestinationEntity()).isTaskAllowed(((Task) move.getMovedValue()));
    }
}
public class TaskChangeMoveFilter implements SelectionFilter<TaskAssignment, ListChangeMove<TaskAssignment>> {

    @Override
    public boolean accept(ScoreDirector<TaskAssignment> scoreDirector, ListChangeMove<TaskAssignment> move) {
        return ((Employee) move.getDestinationEntity()).isTaskAllowed(((Task) move.getMovedValue()));
    }
}
public class TaskSwapMoveFilter implements SelectionFilter<TaskAssignment, ListSwapMove<TaskAssignment>> {

    @Override
    public boolean accept(ScoreDirector<TaskAssignment> scoreDirector, ListSwapMove<TaskAssignment> move) {
        return ((Employee) move.getLeftEntity()).isTaskAllowed(((Task) move.getRightValue())) &&
                ((Employee) move.getRightEntity()).isTaskAllowed(((Task) move.getLeftValue()));
    }
}

The new isTaskAllowed() method on Employee

This implements the hard constraint. Replace the logic to reject Orders that must not be assigned to the given Machine.

@PlanningEntity
public class Employee extends AbstractPersistable implements Labeled {

    ...

    public boolean isTaskAllowed(Task task) {
        return skillSet.containsAll(task.getTaskType().getRequiredSkillList());
    }

    ...
}

Solver config

Pretty much copy-paste this. Just change the variableName attribute value (I guess to "orders") and the filters' class names.

  <constructionHeuristic>
    <queuedValuePlacer>
      <valueSelector id="1" variableName="tasks"/>
      <changeMoveSelector>
        <filterClass>org.optaplanner.examples.taskassigning.domain.solver.TaskAssignMoveFilter</filterClass>
        <valueSelector mimicSelectorRef="1"/>
      </changeMoveSelector>
    </queuedValuePlacer>
  </constructionHeuristic>
  <localSearch>
    <unionMoveSelector>
      <changeMoveSelector>
        <filterClass>org.optaplanner.examples.taskassigning.domain.solver.TaskChangeMoveFilter</filterClass>
      </changeMoveSelector>
      <swapMoveSelector>
        <filterClass>org.optaplanner.examples.taskassigning.domain.solver.TaskSwapMoveFilter</filterClass>
      </swapMoveSelector>
    </unionMoveSelector>
  </localSearch>

Upvotes: 1

Related Questions