使用标准配置进行附近选择无法选择正确的目的地

问题描述 投票:0回答:1

我在本地搜索阶段的“附近”选择中遇到了奇怪的行为。

我已经实现了一个基于技能、工作量和假期的任务分配调度程序。该求解器在 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 任务上使用 @PlanningListVariable), 任务(使用 @InverseRelationShadowVariable(sourceVariableName = "tasks")

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>

我使用了文档中描述的配置设置,但在迭代“目标”组时出现错误

optaplanner
1个回答
0
投票

激活起来确实很复杂。因此,我们在 Timefold Solver Enterprise 中添加了 单行激活功能 以供附近选择:

<solver xmlns="https://timefold.ai/xsd/solver">
    ...
    <nearbyDistanceMeterClass>org.acme.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
    ...
</solver>

不幸的是,附近的选择是极少数不属于 Timefold Solver 社区的功能之一。

© www.soinside.com 2019 - 2024. All rights reserved.