我尝试使用jsprit来解决具有多个TimeWindows
的VRP。因此,我创建了一个新的Constraint类,其中包含一个将"TimeWindowsNotAvailable"类与服务相关联的Map。
"TimeWindowsNotAvailable"类包含无法完成服务的TimeWindows
列表(例如,客户不在家等)。主要问题是,newAct.getArrTime()
总是0.0,尽管您可以在VRP的解决方案中看到arrTime
不是0.0。
有人知道我如何解决这个问题吗?或者多个TimeWindows
更难实现吗?
public class TimeConstraint implements HardActivityStateLevelConstraint {
private Map<Service, TimeWindowsNotAvailable> notAvailableMap;
private RouteAndActivityStateGetter states;
private VehicleRoutingTransportCosts routingCosts;
public TimeConstraint() {
super();
}
public boolean checkDepTime(Service service, Double depTime){
TimeWindowsNotAvailable timeWindowsNotAvailable = notAvailableMap.get(service);
if(timeWindowsNotAvailable == null) return true;
System.out.println(depTime);
return timeWindowsNotAvailable.isAvailable(depTime);
}
public void setNotAvailableMap(Map<Service, TimeWindowsNotAvailable> notAvailableMap){
this.notAvailableMap = notAvailableMap;
}
@Override
public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
Service currentService = (Service)iFacts.getJob();
if(checkDepTime(currentService, **newAct.getArrTime()**)) return ConstraintsStatus.FULFILLED;
return ConstraintsStatus.NOT_FULFILLED;
}
}
您还不能开箱即用地对多个时间窗口进行建模,但它即将实现。目前,您可以实现自己的。例如,假设服务有以下两个时间窗口:(e1,l1),(e2,l2),其中e表示最早的操作开始,l表示最晚的操作开始。如果l1<e2,实现起来比较"容易"。看看我是如何实现单个硬时间窗口的。看看哪个是TimeWindowConstraint,哪个是实用的时间窗口状态更新程序。您可能只需要对这些类进行微小的修改,所以只需复制它们并添加多个时间窗口,然后将这两个新类添加到State和ConstraintManager中(不要忘记停用默认的时间窗口constraints/stateUpdater)。
newAct没有任何arrTime,因为它尚未插入到路由中,最佳插入位置仍有待确定(通过检查约束条件和计算边际插入成本)。但你可以很容易地计算如下:
double newActArrTime = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime,iFacts.getNewDriver(),iFacts.getNewVehicle);