0

对于车辆路径问题的这种设置,我很乐意提出任何意见。

首先,这是我使用这个工具的第一步,所以如果我完全超出范围,请原谅我:-) 我已经制作了一个没有 optaplanner 的算法,以测试基本规则设置。它适用于单个车辆,但 optaplanner 看起来与我最初的想法非常相似,即为每个满意的规则分配分数,然后选择得分最高的车辆。它也是可配置的,而且肯定比我之前做的要好。

让我们开始

查看文档和一些视频,似乎当所有拾取点都已经在输入到Solver.

实时为每个请求找到一个车辆,如果没有车辆可以满足约束,拒绝它呢?考虑到对外部(付费)地图服务的调用,这会使过程变慢,并且有成本。最好避免这些调用中的冗余。

取件请求可以在任何未来日期完成,但不能在当天完成。

计划实体 - 取货请求

@PlanningEntity
public class FindBestVehicleRequest
{

  @PlanningId
  private Long id;

  // Shadow variable candidate
  private Double requiredSpace;

  // Shadow variable candidate
  private int requiredAutonomy;

  private String pickupAddress;

 // Shadow variable candidate
 private LatLng pickupPosition;

 private LocalDateTime pickupDateTime;

 @PlanningVariable(valueRangeProviderRefs = "vehicle")
 private Vehicle vehicle;

 ...

}

每个请求中涉及的计算

我已经阅读了有关影子变量的文档,但我仍然远未理解如何定义它们,但我认为这对我来说很有用:如前所述,对于每个请求我需要调用地图服务(谷歌, OpenStreetMaps, ...)以计算从车辆所在位置到取货地址的距离。

获取车辆原点位置,逻辑的一些伪代码:

if (vehicle.hasOrdersBefore(pickupDateTime) {

   LatLng  origin      = vehicle.lastOrderBefore(pickupDateTime).getPosition();
   String  destination = pickupAddress;
   Integer distance    = mapsServer.getDistance(origin, destination);

   return distance;
}

像这样的计算还有很多,但没必要一一列举,大同小异。

我正在研究所有可用的算法类型,以找到更适合此问题的算法类型。

约束提供者实现

public class BestVehicleConstraintProvider implements ConstraintProvider {
    @Override public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
        return new Constraint[]{
                vehicleHasAutonomy(constraintFactory)
        };
    }

    // One HARD constraint
    private Constraint vehicleHasAutonomy(ConstraintFactory constraintFactory) {
        return constraintFactory.from(FindBestVehicleRequest.class)
                .groupBy(FindBestVehicleRequest::getVehicle, sum(FindBestVehicleRequest::getRequiredAutonomy))
                .filter((vehicle, requiredAutonomy) -> requiredAutonomy > vehicle.getVehicleTypeProperties().getMaxKmAutonomy())
                .penalize("vehicleHasAutonomy", HardSoftScore.ONE_HARD,
                          ((vehicle, requiredSpace) -> vehicle.getVehicleTypeProperties().getMaxKmAutonomy() - requiredSpace));

    }


}

最后一部分,

解决方案类

@PlanningSolution
public class FindBestVehicleSolution
{

  @PlanningEntityCollectionProperty
  private List<FindBestVehicleRequest> processes;

  @ProblemFactCollectionProperty
  @ValueRangeProvider(id = "vehicle")
  private List<Vehicle> vehicles;       // <----- I'm fetching a list of active Vehicles in
                                        //        the requested pickupDate, and passing it here

  @ProblemFactProperty
  private String pickupAddress;

  // private LatLng pickupAddressPosition;    //  shadow variable ? how to call the map server 
                                              //                    and populate this field ?


  @PlanningScore
  private HardSoftScore score;

...
}

好的,所以我认为所有的代码都在这里。我正在寻找有关正确方法的建议: - 调用地图服务器以有效的方式获取距离 - 避免重复相同的计算 - (重要!)如果车辆满足某些规则,例如它没有分配的订单选定日期,直接结束评估过程(找到车辆!)

是的,我可能要求太多了,但是文档有点难以适应这种情况,我认为随着时间的推移我会变得更好,但我想很快用 Optaplanner Workbench 进行一些模拟:-)

感谢任何会提出任何建议的人!

4

0 回答 0