跟踪容量MultiTrip CVRPTW并在超过容量时返回仓库

时间:2018-06-05 17:14:58

标签: optaplanner

我在使用时间窗(CVRPTW)的Capcity车辆路径问题中跟踪车辆的正常运行能力时遇到了问题。

我试图让车辆在达到车辆的最大容量时返回车站。

根据我在这里得到的回复https://groups.google.com/forum/#!topic/optaplanner-dev/IMG_7D1JvmQ我目前正在尝试实施每日n次旅行设计。

我试图在Vehicle上使用阴影变量并在其上使用变量监听器。

我按如下方式修改了车辆类:

@XStreamAlias("VrpVehicle")
    public class Vehicle extends AbstractPersistable implements Standstill {

        ...planning entities


        ...other shadow variables


        protected Integer currentDemand;


        @CustomShadowVariable(sources = {@PlanningVariableReference(variableName = "previousStandstill")})
        public Integer getCurrentDemand() { return currentDemand; }

    }
}

My Variable Listener如下:

public class VehicleCapacityReuseVariableListener implements VariableListener<Customer> {
    @Override
    public void afterEntityAdded(ScoreDirector scoreDirector,Customer customer)     {
        if (customer instanceof TimeWindowedCustomer) {
            updateVehicleDemandTotal(scoreDirector, (TimeWindowedCustomer) customer);
       }
    }

    @Override
    public void afterVariableChanged(ScoreDirector scoreDirector, Customer customer) {
        if (customer instanceof TimeWindowedCustomer) {
            updateVehicleDemandTotal(scoreDirector, (TimeWindowedCustomer) customer);
        }
    }

    ...

    protected void updateVehicleDemandTotal(ScoreDirector scoreDirector, Customer sourceCustomer) {
        Standstill previousStandstill = sourceCustomer.getPreviousStandstill();
        Vehicle vehicle = previousStandstill == null ? null : previousStandstill.getVehicle();
        TimeWindowedCustomer shadowCustomer = (TimeWindowedCustomer) sourceCustomer;
        Integer currentDemand = shadowCustomer.getDemand();

        Vehicle currentVehicle = shadowCustomer.getVehicle();
        Vehicle nextVehicle = currentVehicle;
        while (shadowCustomer != null) {
            scoreDirector.beforeVariableChanged(shadowCustomer, "vehicle");

            currentVehicle = shadowCustomer.getVehicle();

            scoreDirector.afterVariableChanged(shadowCustomer, "vehicle");

            shadowCustomer = shadowCustomer.getNextCustomer();
            if (shadowCustomer != null) {
                nextVehicle = shadowCustomer.getVehicle();
                if (!currentVehicle.equals(nextVehicle)){
                    nextVehicle.setCurrentDemand(currentDemand);
                    currentVehicle.setCurrentDemand(currentVehicle.getCurrentDemand() - currentDemand);
                    currentDemand = nextVehicle.getCurrentDemand();
                }
                currentDemand += shadowCustomer.getDemand();
                nextVehicle.setCurrentDemand(currentDemand);
            }
        }
    }
}

如果有人可以帮助我跟踪容量,那就太棒了。

我认为解决方案(回到仓库)是将下一个客户设置为&#34;仓库&#34;顾客。

PS。还有其他与此相关的stackoverflow问题,我试过它们无济于事。为了完整起见:

感谢您抽出时间考虑这一点,非常感谢任何回复的人。

1 个答案:

答案 0 :(得分:0)

我无法完全回答您的问题,但我确实在您的侦听器实施中发现了问题。行

scoreDirector.beforeVariableChanged(shadowCustomer, "vehicle");
scoreDirector.afterVariableChanged(shadowCustomer, "vehicle");

必须包围修改计划变量的任何行,例如:

 nextVehicle.setCurrentDemand(currentDemand);

我认为杰夫建议的是,如果你的容量达到0你的车辆.getDistanceToPreviousStandstill函数会将到库的距离加到计算中。 (这只是我的猜测,我没有读过Geoff的设计评论太多)。