我在本地搜索阶段的“附近”选择中遇到了奇怪的行为。
我已经实现了一个基于技能、工作量和假期的任务分配调度程序。该求解器在 2K 任务标记下发挥最佳性能。所以我决定在我的代码中引入附近的选择。我按照 OptaPlanner 网站上的指南进行操作,但是在本地搜索开始后,它在第一次迭代后就出错了。
假设我们有 10 个资源和 100 个任务。
对于 Task-0(起点),目的地是正确的,在 10 个资源之间迭代。但对于 Task-1,目的地是 Task-0,导致此异常
class org.digimark.planner.domain.tasks.Task cannot be cast to class org.digimark.planner.domain.resources.Risorsa (org.digimark.planner.domain.tasks.Task and org.digimark.planner.domain.resources.Risorsa are in unnamed module of loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @181e72d3)
我哪里做错了?有什么想法吗?
规划实体:
Risorsa(在 List
package org.digimark.planner.domain.scheduler;
import org.digimark.planner.domain.resources.Competenze;
import org.digimark.planner.domain.resources.Reparto;
import org.digimark.planner.domain.resources.Risorsa;
import org.digimark.planner.domain.tasks.Task;
import org.optaplanner.core.impl.heuristic.selector.common.nearby.NearbyDistanceMeter;
import java.util.List;
import java.util.Objects;
public class TaskNerbyDistanceMeter implements NearbyDistanceMeter<Task, Risorsa> {
@Override
public double getNearbyDistance(Task origin, Risorsa destination) {
String originReparto = origin.getRepartoRichiesto();
List<Reparto> destinationListaReparti = destination.getListaReparti();
List<Competenze> originCompetenze = origin.getCompetenzaRichiesta();
List<Competenze> destinationCompetenze = destination.getCompetenze();
if (originReparto != null &&
destinationListaReparti != null &&
originCompetenze != null &&
destinationCompetenze != null) {
boolean repartoMatch = false;
boolean competenzeMatch = false;
for (Reparto r : destinationListaReparti) {
if (Objects.equals(r.getNomeReparto(), originReparto)) {
repartoMatch = true;
break;
}
}
for (Competenze c : originCompetenze) {
for (Competenze d : destinationCompetenze) {
if (Objects.equals(c.getNomeCompetenza(), d.getNomeCompetenza())) {
competenzeMatch = true;
break;
}
}
}
if (repartoMatch && competenzeMatch) {
return 0.0;
}
else {
return Double.MAX_VALUE;
}
}
else {
return Double.MAX_VALUE;
}
}
}
解决配置(来自文档):
<unionMoveSelector>
<listChangeMoveSelector>
<valueSelector id="valueSelector1"/>
<destinationSelector>
<nearbySelection>
<originValueSelector mimicSelectorRef="valueSelector1"/>
<nearbyDistanceMeterClass>org.optaplanner.examples.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
<parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
</nearbySelection>
</destinationSelector>
</listChangeMoveSelector>
<listSwapMoveSelector>
<valueSelector id="valueSelector2"/>
<secondaryValueSelector>
<nearbySelection>
<originValueSelector mimicSelectorRef="valueSelector2"/>
<nearbyDistanceMeterClass>org.optaplanner.examples.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
<parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
</nearbySelection>
</secondaryValueSelector>
</listSwapMoveSelector>
<subListChangeMoveSelector>
<selectReversingMoveToo>true</selectReversingMoveToo>
<subListSelector id="subListSelector3"/>
<destinationSelector>
<nearbySelection>
<originSubListSelector mimicSelectorRef="subListSelector3"/>
<nearbyDistanceMeterClass>org.optaplanner.examples.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
<parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
</nearbySelection>
</destinationSelector>
</subListChangeMoveSelector>
<subListSwapMoveSelector>
<selectReversingMoveToo>true</selectReversingMoveToo>
<subListSelector id="subListSelector4"/>
<secondarySubListSelector>
<nearbySelection>
<originSubListSelector mimicSelectorRef="subListSelector4"/>
<nearbyDistanceMeterClass>org.optaplanner.examples.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
<parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
</nearbySelection>
</secondarySubListSelector>
</subListSwapMoveSelector>
</unionMoveSelector>
我使用了文档中描述的配置设置,但在迭代“目标”组时出现错误
激活起来确实很复杂。因此,我们在 Timefold Solver Enterprise 中添加了 单行激活功能 以供附近选择:
<solver xmlns="https://timefold.ai/xsd/solver">
...
<nearbyDistanceMeterClass>org.acme.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
...
</solver>
不幸的是,附近的选择是极少数不属于 Timefold Solver 社区的功能之一。