首页 > 解决方案 > 提前到达访问时减少停机时间(空闲时间)

问题描述

Optaplanner 被用于规划车队的路线,我正在优化路线时间。

我有一个场景,我在早上有一次访问时间窗口,而第二次访问是在下午有时间窗口。然而,车辆在时间窗口打开时离开,进行第一次交付并前往第二次访问。由于第二次访问有下午的时间窗口,车辆必须等待本次访问的时间窗口打开,从而引入停机时间。这种停机时间(空闲时间)可以通过稍后离开仓库来减少。所以我想问一下:有没有什么规则可以让 q 回溯到仓库或上一次访问,等待更长的时间继续,从而减少第二次访问的停机时间或等待时间?

我尝试了不同的变体:

1-我实施了一个约束来惩罚如果提前访问并惩罚客户 - > customer.getReadyTime() - customer.getArrivalTime()。这可能会优化,但不会回滚到达时间。

2- 修改我的监听器(ArrivalTimeUpdatingVariableListener, updateArrivalTime 方法)。计算到达时间时,如果有空闲时间,我就去上一次访问,减去空闲时间。但是,在某些情况下,它不会正确递归地更新所有以前的访问,而在其他情况下,它会给我一个“VariableListener 损坏”。我对这个变体也没有成功。

是否有任何规则可以等待或回滚并再次更新所有访问?

我附上我的约束和监听器以获得更好的上下文。

ArrivalTimeUpdatingVariableListener.class:

   protected void updateArrivalTime(ScoreDirector scoreDirector, TimeWindowedVisit sourceCustomer) {
        Standstill previousStandstill = sourceCustomer.getPreviousStandstill();
        Long departureTime = previousStandstill == null ? null
                : (previousStandstill instanceof TimeWindowedVisit)
                ? ((TimeWindowedVisit) previousStandstill).getArrivalTime() + ((TimeWindowedVisit) previousStandstill).getServiceDuration()
                : ((PlanningVehicle) previousStandstill).getDepot() != null
                ? ((TimeWindowedDepot) ((PlanningVehicle) previousStandstill).getDepot()).getReadyTime()
                : 0;
        TimeWindowedVisit shadowCustomer = sourceCustomer;
        Long arrivalTime = calculateArrivalTime(shadowCustomer, departureTime);

        while (shadowCustomer != null && !Objects.equals(shadowCustomer.getArrivalTime(), arrivalTime)) {
            scoreDirector.beforeVariableChanged(shadowCustomer, "arrivalTime");
            shadowCustomer.setArrivalTime(arrivalTime);
            scoreDirector.afterVariableChanged(shadowCustomer, "arrivalTime");
            departureTime = shadowCustomer.getDepartureTime();
            shadowCustomer = shadowCustomer.getNextVisit();
            arrivalTime = calculateArrivalTime(shadowCustomer, departureTime);
        }
    }

    private Long calculateArrivalTime(TimeWindowedVisit customer, Long previousDepartureTime) {
        long arrivalTime = 0;
        if (customer == null || customer.getPreviousStandstill() == null) {
            return null;
        }
        if (customer.getPreviousStandstill() instanceof PlanningVehicle) {
             arrivalTime = Math.max(customer.getReadyTime(),
                    previousDepartureTime + customer.distanceFromPreviousStandstill());
        } else {
            arrivalTime = previousDepartureTime + customer.distanceFromPreviousStandstill();
            
             // to reach backwards and (attempt to) shift the previous arrival time.
            Standstill previousStandstill = customer.getPreviousStandstill();
            long idle = customer.getReadyTime() - arrivalTime;
            if (previousStandstill != null && idle > 0) {
                arrivalTime += idle;

                if (previousStandstill instanceof TimeWindowedVisit) {
                    long previousArrival = ((TimeWindowedVisit) previousStandstill).getArrivalTime() + idle;
                    if (previousArrival >  ((TimeWindowedVisit) previousStandstill).getDueTime()){
                        System.out.println("Arrival es mayor que el duetime");
                        previousArrival = ((TimeWindowedVisit) previousStandstill).getDueTime() - ((TimeWindowedVisit) previousStandstill).getServiceDuration();
                    }
                   ((TimeWindowedVisit) previousStandstill).setArrivalTime(previousArrival);
                }
            }
        }
         
        // breaks

        return arrivalTime;
    }

约束提供者.class:

    private Constraint arrivalEarly(ConstraintFactory constraintFactory) {
        return constraintFactory.from(TimeWindowedVisit.class)
                .filter((customer) -> !customer.getVehicle().isGhost() && customer.getArrivalTime() < customer.getReadyTime())
                .penalizeConfigurableLong(
                        VehicleRoutingConstraintConfiguration.MINIMIZE_IDLE_TIME,
                        customer -> customer.getReadyTime() - customer.getArrivalTime());

    }

标签: optaplanner

解决方案


推荐阅读