1

我正在使用车辆路线的 TimeWindowed 版本,并向车辆添加了 endOfShift 时间。我想计算返回仓库的时间并使其成为硬约束。returnToDepotTime 是在 ArrivalTimeUpdatingVariableListener 中计算的,我还更改了我添加的 drl 文件

rule "returnToDepotBeforeEndOfShift"
when
    Vehicle(endOfShift < returnToDepotTime, $endOfShift : endOfShift, $returnToDepotTime : returnToDepotTime)
then
    scoreHolder.addHardConstraintMatch(kcontext, $endOfShift - $returnToDepotTime.intValue());  end

问题是 OptaPlanner 没有考虑 returnToDepotTime 并且它被计算但没有被硬约束计算考虑。知道要改变什么吗?

4

2 回答 2

2

嗨@Snukra 非常感谢你,我用一种解决方法解决了这个问题,我将所有东西都保存在最后一个客户中。但我想知道我的问题出在哪里:) 所以这里是车辆对象的重要部分:

@PlanningEntity(difficultyComparatorClass = VehicleDifficultyComparator.class)
@XStreamAlias("Vehicle")
public class Vehicle extends AbstractPersistable implements Standstill {

Integer returnToDepotTime;

@CustomShadowVariable(variableListenerClass = ArrivalTimeUpdatingVariableListener.class, sources = { @CustomShadowVariable.Source(variableName = "returnToDepotTime") })

public Integer getReturnToDepotTime() {
    return returnToDepotTime;
}

public void setReturnToDepotTime(Integer returnToDepotTime) {
    this.returnToDepotTime = returnToDepotTime;
}   

}

这是 ArrivalTimeUpdatingVariableListener:

public class ArrivalTimeUpdatingVariableListener implements
    VariableListener<Customer> {

public void beforeEntityAdded(ScoreDirector scoreDirector,
        Customer customer) {
    // Do nothing
}

public void afterEntityAdded(ScoreDirector scoreDirector,
        Customer customer) {
    updateVehicle(scoreDirector, customer);
}

public void beforeVariableChanged(ScoreDirector scoreDirector,
        Customer customer) {
    // Do nothing
}

public void afterVariableChanged(ScoreDirector scoreDirector,
        Customer customer) {
    updateVehicle(scoreDirector, customer);
}

public void beforeEntityRemoved(ScoreDirector scoreDirector,
        Customer customer) {
    // Do nothing
}

public void afterEntityRemoved(ScoreDirector scoreDirector,
        Customer customer) {
    // Do nothing
}

protected void updateVehicle(ScoreDirector scoreDirector,
        Customer sourceCustomer) {
    Standstill previousStandstill = sourceCustomer.getPreviousStandstill();
    Integer departureTime = null;
    Customer shadowCustomer = sourceCustomer;
    Integer arrivalTime = 0;

    Vehicle vehicle = null;
    vehicle = sourceCustomer.getVehicle();

    // here the start times are used
    if (previousStandstill instanceof Customer) {
        departureTime = ((Customer) previousStandstill).getDepartureTime();

        arrivalTime = calculateArrivalTime(sourceCustomer, departureTime);
    } else if (previousStandstill instanceof Vehicle) {
        vehicle = (Vehicle) previousStandstill;
        arrivalTime = calculateArrivalTimeFirstCustomer(sourceCustomer,
                vehicle);
    }

    while (shadowCustomer != null
            && ObjectUtils.notEqual(shadowCustomer.getArrivalTime(),
                    arrivalTime)) {
        scoreDirector.beforeVariableChanged(shadowCustomer, "arrivalTime");
        shadowCustomer.setArrivalTime(arrivalTime);     
        scoreDirector.afterVariableChanged(shadowCustomer, "arrivalTime");

        departureTime = shadowCustomer.getDepartureTime();
        if (shadowCustomer.getNextCustomer() == null) {
            scoreDirector.beforeVariableChanged(shadowCustomer,
                    "returnTimeToDepotIfLastOnTour");
            //scoreDirector.beforeVariableChanged(vehicle,
            //      "returnToDepotTime");

            int returnTimeToDepot = shadowCustomer.getArrivalTime()
                    + shadowCustomer.getServiceDuration()
                    + shadowCustomer.getTravelTimeTo(vehicle.getDepot());
            vehicle.setReturnToDepotTime(returnTimeToDepot);
            shadowCustomer
                    .setReturnTimeToDepotIfLastOnTour(returnTimeToDepot);
            shadowCustomer.setEndOfShiftOfVehicle(vehicle.getEndOfShift());

            scoreDirector.afterVariableChanged(shadowCustomer,
                    "returnTimeToDepotIfLastOnTour");
            //scoreDirector.afterVariableChanged(vehicle,
            //      "returnToDepotTime");
        }

        shadowCustomer = shadowCustomer.getNextCustomer();
        arrivalTime = calculateArrivalTime(shadowCustomer, departureTime);
    }
}

private Integer calculateArrivalTimeFirstCustomer(Customer customer,
        Vehicle vehicle) {
    // calculate the earliest possible arrival time for this customer and
    // this vehicle
    int arrivalTime = vehicle.getStartOfShift()
            + customer.getLocation().getTravelTime(
                    vehicle.getStartLocation());

    // if the time is before the redy time of a conatiner we take the ready
    // time of a customer
    if (customer.getReadyTime() > arrivalTime) {
        arrivalTime = customer.getReadyTime();
    }
    return arrivalTime;
}

private Integer calculateArrivalTime(Customer customer,
        Integer previousDepartureTime) {
    if (customer == null) {
        return null;
    }
    if (previousDepartureTime == null) {
        // PreviousStandstill is the Vehicle, so we leave from the Depot
        // at
        // the best suitable time
        int maxTime = Math.max(customer.getReadyTime(),
                customer.getTravelTimeToPreviousStandstill());
        return maxTime;
    }
    int arrivalTime = previousDepartureTime
            + customer.getTravelTimeToPreviousStandstill();
    return arrivalTime;

}

}

评论scoreDirector.beforeVariableChanged(vehicle, "returnToDepotTime");scoreDirector.afterVariableChanged(vehicle, "returnToDepotTime");返回错误。你知道为什么吗?

于 2014-11-04T11:41:43.007 回答
0

调整 ArrivalTimeUpdatingVariableListener 以同时调整where is的Vehicle's returnHomeTimeCustomergetNextCustomer()null

如果scoreDirector被正确通知(before/afterVarChanged 方法)Vehicle'已returnHomeTime更改,则规则将相应更新。

于 2014-10-31T16:14:25.993 回答