java - OptaPlanner:使规划实体链接起来并且可以为空

标签 java optaplanner

亲爱的 OptaPlanner 社区

对于 OptaPlanner 框架的特定用例,我想使用链式数据结构,因为它在车辆路由示例中使用。我们案例中的问题是,有很多客户,但在特定的计划周期内无法为所有客户提供服务。因此,我认为使用可为空的计划变量可能很有用,因此不需要分配所有任务,同时仍然具有有效的供应商链。 我的问题是,我该如何解决这个问题?有一条额外的链未分配任务吗?还有其他方法可以绕过这个问题吗? 问候 拉斐尔

最佳答案

我遇到了类似的问题,我需要允许跳过某些客户并尽量减少使用的车辆数量。我通过使用“Ghost”车辆改编了标准 Optaplanner (7.12.0) VRP 示例,如下所示:

@XStreamAlias("VrpGhostVehicle")
public class GhostVehicle extends Vehicle {
    @Override
    public Depot getDepot() {
        return null;
    }

    @Override
    public Long getId() {
        return Long.valueOf(0);
    }

    @Override
    public boolean isGhost() {
        return true;
    }

    @Override
    public int getCapacity() {
        return Integer.MAX_VALUE;
    }
}

为了对无法跳过的客户进行建模,我向 Customer.java 添加了一个“不可跳过” boolean 字段。然后,在您的 VehicleRoutingScoreRules.drl 中,我调整并添加了如下约束:

rule "vehicleCapacity"
    when
        $vehicle : Vehicle(ghost == false, $capacity : capacity)
        accumulate(
            Customer(
                vehicle == $vehicle,
                $demand : demand);
            $demandTotal : sum($demand);
            $demandTotal > $capacity
        )
    then
        scoreHolder.addHardConstraintMatch(kcontext, $capacity - $demandTotal);
end

// ############################################################################
// Soft distance constraints
// ############################################################################

rule "distanceToPreviousStandstill"
    when
        $vehicle : Vehicle(ghost == false)
        $customer : Customer(previousStandstill != null, vehicle == $vehicle, $distanceFromPreviousStandstill : distanceFromPreviousStandstill)
    then
        scoreHolder.addSoftConstraintMatch(kcontext, - $distanceFromPreviousStandstill);
end

rule "distanceFromLastCustomerToDepot"
    when
        $vehicle : Vehicle(ghost == false)
        $customer : Customer(previousStandstill != null, vehicle == $vehicle)
        not Customer(previousStandstill == $customer)
    then
        Vehicle vehicle = $customer.getVehicle();
        scoreHolder.addSoftConstraintMatch(kcontext, - $customer.getDistanceTo(vehicle));
end


// ############################################################################
// Time window constraints 
// ############################################################################

rule "arrivalAfterDueTime"
    when
        $vehicle : Vehicle(ghost == false)
        TimeWindowedCustomer(dueTime < arrivalTime, vehicle == $vehicle, $dueTime : dueTime, $arrivalTime : arrivalTime)
    then
        scoreHolder.addSoftConstraintMatch(kcontext, -1000 * Math.abs($dueTime - $arrivalTime.longValue()));
end

rule "arrivalBeforeReadyTime"
    when
        $vehicle : Vehicle(ghost == false)
        TimeWindowedCustomer(readyTime > arrivalTime, vehicle == $vehicle, $readyTime : readyTime, $arrivalTime : arrivalTime)
    then
        scoreHolder.addSoftConstraintMatch(kcontext, -1000 * Math.abs($readyTime - $arrivalTime.longValue()));
end


// ############################################################################
// Constraints pertaining to station skipping and vehicle usage
// ############################################################################

rule "skippedCustomer"
    when
        $vehicle : Vehicle(ghost == true)
        $customer : Customer(vehicle == $vehicle, $unskippable : unskippable, $demand : demand)
    then
        if ($unskippable) {
            scoreHolder.addHardConstraintMatch(kcontext, -10000 * $demand);
        } else {
            scoreHolder.addSoftConstraintMatch(kcontext, -10000 * $demand);
        }
end

rule "usedTooManyVehicles"
    when
        $vehicle : Vehicle(nextCustomer != null, ghost == false)
    then
        scoreHolder.addSoftConstraintMatch(kcontext, -500000);
end

下面的三个规则是我添加到示例中的约束,并且我在仅适用于真实车辆的规则中添加了对 Ghost==false 的进一步检查。请注意,对于不可跳过的客户,我们设置了硬约束,而对于可跳过的客户,我们设置了软约束。跳过客户或使用车辆的相对权重当然是特定于应用程序的。

关于java - OptaPlanner:使规划实体链接起来并且可以为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51240290/

相关文章:

OptaPlanner 对数求解器相变

java - OptaPlanner 具有链式变量的多个实体类

java - 在损坏的 JVM 上自动链接多个测试

java - 倾斜缓冲图像 java

optaplanner - 如何使用 OptaPlanner 基准蓝图指定 simulatedAnnealingStartingTemperature

optimization - Google 优化工具是否支持软约束?

java - 如何根据名称长度在名称前添加零

java - Tomcat 中的第三方库最佳实践

java - 是否有任何 "portable"Java SQL 包?

java - 为什么我们在 Optaplanner 中使用 XStream 注释