我试图尽可能减少车辆的等待时间,但到目前为止,我的方法都没有一点效果。我尝试了以下方法:
- 使用
setCostPerWaitingTime
- 实施一个
HardActivityConstraint
强制司机在时间窗口开始后到达交货点。 - 实施一个
SoftActivityConstraint
惩罚等待时间的方法。
下面是我的实现HardActivityConstraint
:
public class WaitingTimeConstraint implements HardActivityConstraint {
private final VehicleRoutingTransportCosts transportCosts;
public WaitingTimeConstraint(VehicleRoutingTransportCosts transportCosts) {
this.transportCosts = transportCosts;
}
@Override
public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
if (prevAct instanceof Start && nextAct instanceof End) {
return ConstraintsStatus.FULFILLED;
}
Vehicle vehicle = getVehicle(iFacts);
Driver driver = iFacts.getRoute().getDriver();
if (isArrivalTimeBeforeTimeSlotStart(prevAct) || isArrivalTimeBeforeTimeSlotStart(nextAct)) {
return ConstraintsStatus.NOT_FULFILLED_BREAK;
}
double newActArrTime = prevActDepTime + transportCosts.getTransportTime(prevAct.getLocation(), newAct.getLocation(), prevActDepTime, driver, vehicle);
if (newActArrTime < newAct.getTheoreticalEarliestOperationStartTime()) {
return ConstraintsStatus.NOT_FULFILLED;
}
return ConstraintsStatus.FULFILLED;
}
private boolean isArrivalTimeBeforeTimeSlotStart(TourActivity activity) {
return activity.getArrTime() < activity.getTheoreticalEarliestOperationStartTime();
}
private Vehicle getVehicle(JobInsertionContext iFacts) {
if (iFacts.getRoute().getActivities().isEmpty()) {
return iFacts.getNewVehicle();
}
return iFacts.getRoute().getVehicle();
}
}
这是我的实现SoftActivityConstraint
public class WaitingTimeConstraint implements SoftActivityConstraint {
private final VehicleRoutingTransportCosts transportCosts;
public WaitingTimeConstraint(VehicleRoutingTransportCosts transportCosts) {
this.transportCosts = transportCosts;
}
@Override
public double getCosts(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
Driver driver = iFacts.getRoute().getDriver();
if(isArrivalTimeBeforeTimeSlotStart(prevAct) || isArrivalTimeBeforeTimeSlotStart(nextAct)){
return 1e10;
}
double newActArrivalTime = prevActDepTime + transportCosts.getTransportTime(prevAct.getLocation(), newAct.getLocation(), prevActDepTime, driver, getVehicle(iFacts));
return (newAct.getTheoreticalEarliestOperationStartTime() - newActArrivalTime) * 1e10;
}
private boolean isArrivalTimeBeforeTimeSlotStart(TourActivity activity) {
return activity.getArrTime() < activity.getTheoreticalEarliestOperationStartTime();
}
private Vehicle getVehicle(JobInsertionContext iFacts) {
if (iFacts.getRoute().getActivities().isEmpty()) {
return iFacts.getNewVehicle();
}
return iFacts.getRoute().getVehicle();
}
}
据说此功能之前已实现,并且可以在此链接中找到它的示例,但此链接不再存在。对此问题的任何帮助将不胜感激,因为这是我最后的手段。