繁体   English   中英

Optaplanner 内置硬约束连续规划

[英]Optaplanner built-in hard constraints continuous planning

目前我正在做持续计划,我有两个实体,一个是机器,另一个是订单。 机器包含一个计划列表变量,订单有一个指向机器的逆阴影变量。 我想添加一个内置的硬约束来限制某个订单可以去哪些机器,但是我不能使用机器实体中的 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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM