![](/img/trans.png)
[英]Using OptaPlanner to solve a Vehicle Routing Problem with Time Windows
[英]Using OptaPlanner to solve a Vehicle Routing Problem with Capacities
向所有 optaplanner 人員問好。 我是使用 optaplanner 的新手,在這里我有一些關於規划具有重量和體積容量的車輛路線的問題。 感謝您的幫助,我感謝您的任何建議。
我正在實施具有容量的 VRP,但要求按重量和體積確定容量。 我遵循的路徑是以optaplanner為例,在體積和重量上重構車輛容量,在重量和體積上也重構了訪問的需求。 然后我修改了 Constraint Provider,它使用數量處理容量,處理重量,然后我實現了另一個非常相似但處理體積的 Constraint Provider。 從現在開始,我還將需要其他尺寸的車輛容量和訪客(客戶)的負載。
1-由於我是新手,我想知道我的假設是否正確,我是否走在正確的道路上?
2- 我想知道與每個維度的約束提供程序一起工作是否正確,或者我是否應該加入一個約束提供程序中的所有重量和體積或其他計算。 如果可能,我該怎么做?
3-如果我有一輛只有重量的車輛和另一輛只有體積的車輛,但我有訪問(客戶)的需求需要同時覆蓋重量和體積,因此我永遠不會獲得可行的路線,因為只有一輛車經過同一次訪問。 我怎么解決這個問題?
4- 我如何管理當訪問(客戶)的需求超過車輛的容量時,車輛對同一個訪問進行更多的旅行,直到它覆蓋訪問(客戶)的總需求?
在這里,我分享我的修改以獲得更好的上下文。 謝謝!
重構車輛容量:
public class PlanningVehicle implements Standstill {
@PlanningId
private long id;
private int weightCapacity;
private int volumeCapacity;
...
}
重構了訪問的需求:
@PlanningEntity(difficultyWeightFactoryClass = DepotAngleVisitDifficultyWeightFactory.class)
public class PlanningVisit implements Standstill {
@PlanningId
private long id;
private PlanningLocation location;
private int weightDemand;
private int volumeDemand;
...
}
我實施了兩個硬分,每個維度(重量和體積)一個:
@ConstraintConfiguration(constraintPackage = "com.router.solver")
public class VehicleRoutingConstraintConfiguration {
...
public static final String VEHICLE_WEIGHT_CAPACITY = "Vehicle capacity in weight";
public static final String VEHICLE_VOLUME_CAPACITY = "Vehicle capacity in volume";
...
@ConstraintWeight(VEHICLE_WEIGHT_CAPACITY)
private HardSoftLongScore vehicleWeightCapacity = HardSoftLongScore.ONE_HARD;
@ConstraintWeight(VEHICLE_VOLUME_CAPACITY)
private HardSoftLongScore vehicleVolumeCapacity = HardSoftLongScore.ONE_HARD;
}
我實現了兩個單獨的約束:
public class FirstConstraintProvider implements ConstraintProvider {
...
protected Constraint vehicleWeightCapacity(ConstraintFactory constraintFactory) {
return constraintFactory.from(TimeWindowedVisit.class)
.groupBy(PlanningVisit::getVehicle, sum(PlanningVisit::getWeightDemand))
.filter((vehicle, demand) -> demand > vehicle.getWeightCapacity())
.penalizeConfigurableLong(
VEHICLE_WEIGHT_CAPACITY,
(vehicle, demand) -> demand - vehicle.getWeightCapacity());
}
protected Constraint vehicleVolumeCapacity(ConstraintFactory constraintFactory) {
return constraintFactory.from(TimeWindowedVisit.class)
.groupBy(PlanningVisit::getVehicle, sum(PlanningVisit::getVolumeDemand))
.filter((vehicle, demand) -> demand > vehicle.getVolumeCapacity())
.penalizeConfigurableLong(
VEHICLE_VOLUME_CAPACITY,
(vehicle, demand) -> demand - vehicle.getVolumeCapacity());
}
...
}
斜讀:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.