我正在使用车辆路线的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,而是计算但不受硬约束计算的影响。知道要改变什么吗?
答案 0 :(得分: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");
会返回错误。
你知道为什么吗?
答案 1 :(得分:0)
调整ArrivalTimeUpdatingVariableListener以调整Vehicle
returnHomeTime
Customer
getNextCustomer()
null
的{{1}}。
如果scoreDirector
被Vehicle
的{{1}}更改了returnHomeTime
,则会相应地更新规则{/ p>}。