車両の待ち時間をできるだけ少なくしようとしていますが、これまでのところ、私のアプローチはどれも少しも効果的ではありません. 私は次のアプローチを試しました:
- 使用する
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();
}
}
おそらく、この機能は以前に実装されており、その例はこのリンクにありますが、このリンクはもう存在しません。これが私の最後の手段であるため、この問題に関する助けをいただければ幸いです。