Optaplanner内置硬约束连续规划



目前我正在做连续计划,我有两个实体,一个是机器,另一个是订单。该机器包含一个规划列表变量,而订单有一个指向该机器的逆阴影变量。我想添加一个内置的硬约束来限制特定订单可以进入哪些机器,但是我不能在机器实体中使用ValueRangeProvider来过滤订单列表,因为它不能在实体中使用。还有别的办法吗?提前感谢

事实上,依赖于实体的值范围不适用于规划列表变量。在不久的将来没有计划支持它。

您仍然可以通过使用过滤移动选择来实现所需的内置硬约束。

您通常需要三个SelectionFilter实现,每个移动类型一个。我假设您想使用构建启发式阶段,其中包含ListAssignMove,并且您希望在本地搜索阶段同时包含ListChangeMoveListSwapMove

然后,你需要一个高级的求解器配置来应用这些过滤器。

我在TaskAssignment示例中尝试了这种方法,以取代TaskAssigningConstraintProvider中的noMissingSkills约束,并使用移动过滤使其成为内置的硬约束。这就是我最后的结果:

过滤器如果您只是将Employee更改为Machine,Task更改为Order并重命名isTaskAllowed()以更好地适合您的域,这些也应该适用于您的情况。

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()));
}
}

Employee上的新isTaskAllowed()方法

这实现了硬约束。替换逻辑以拒绝不能分配给给定MachineOrder

@PlanningEntity
public class Employee extends AbstractPersistable implements Labeled {
...
public boolean isTaskAllowed(Task task) {
return skillSet.containsAll(task.getTaskType().getRequiredSkillList());
}
...
}

解算器配置

基本上是复制粘贴。只要改变variableName属性值(我猜是"orders")和过滤器的类名。

<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>

相关内容

  • 没有找到相关文章

最新更新