[英]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.我想添加一个内置的硬约束来限制某个订单可以去哪些机器,但是我不能使用机器实体中的 ValueRangeProvider 来过滤掉订单列表,因为它不能在实体内部使用。 Is there another way to do this?还有另一种方法可以做到这一点吗? Thanks in advance提前致谢
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.您通常需要三个SelectionFilter
实现,每个移动类型一个。 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.我假设您想使用具有ListAssignMove
的构造启发式阶段,并且您希望在本地搜索阶段同时拥有ListChangeMove
和ListSwapMove
。
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.我已经在 TaskAssignment 示例中尝试了这种方法来替换TaskAssigningConstraintProvider
中的noMissingSkills
约束,并使用移动过滤使其成为内置的硬约束。 This is what I ended up with:这就是我最终的结果:
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.如果您只是将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()));
}
}
isTaskAllowed()
method on Employee
Employee
上的新isTaskAllowed()
方法This implements the hard constraint.这实现了硬约束。 Replace the logic to reject Order
s that must not be assigned to the given Machine
.替换逻辑以拒绝不能分配给给定Machine
的Order
。
@PlanningEntity
public class Employee extends AbstractPersistable implements Labeled {
...
public boolean isTaskAllowed(Task task) {
return skillSet.containsAll(task.getTaskType().getRequiredSkillList());
}
...
}
Pretty much copy-paste this.几乎复制粘贴这个。 Just change the variableName
attribute value (I guess to "orders"
) and the filters' class names.只需更改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.