或工具-VRP-处理找不到最佳解决方案的情况

问题描述

我正在基于Google的ORTools为车辆路径问题构建求解器。

对于简单的问题或大容量的问题,它可以很好地工作,但是对于大多数“真实”数据集,我最终都会获得无限期运行或超时的解决方案。

经过一些思考,我意识到并不是所有现实世界的问题都可以解决或达到最佳。例如。我可能希望大多数车辆每天行驶不超过500公里。但是,如果我必须将货物运送给600公里以外的人,则整个解决方案将失败。

如何处理这些情况?现在看来,这是二进制的通过或失败。对于某些情况被忽略或返回次优解决方案,我感到非常高兴。

这是我的解决方案的代码

public List<OptimisedVehicleRoute> Start(Location depot,List<Location> locations,int numVehicles = 1,float maxDistanceKmPerVehicle = 1000f,float maxDistanceKmSlack = 5f)
{
    // Create Routing Index Manager
    var depotIndex = locations.IndexOf(depot);
    var manager = new RoutingIndexManager(locations.Count,numVehicles,depotIndex);
    Console.WriteLine($"Depot at {depot.Postcode}");

    var routing = new RoutingModel(manager);

    var numCalls = 0l;

    int transitCallbackIndex = routing.RegisterTransitCallback((long fromIndex,long toIndex) =>
    {
        numCalls++;

        // Convert from routing variable Index to distance matrix NodeIndex.
        var fromNode = manager.IndexToNode(fromIndex);
        var toNode = manager.IndexToNode(toIndex);

        var fromLocation = locations[fromNode];
        var toLocation = locations[toNode];

        var mDistance = fromLocation.DistanceTo(toLocation);

        return mDistance;
    });

    // The arc cost evaluator tells the solver how to calculate the cost of travel between any two locations
    routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);

    long maxVehicleDistanceSlack = (long)Math.Round(maxDistanceKmSlack * 1000); // slack per day
    long maxVehicleDistance = (long)Math.Round(maxDistanceKmPerVehicle * 1000); // 1000km max distance per day

    routing.AddDimension(transitCallbackIndex,maxVehicleDistanceSlack,maxVehicleDistance,true,"Distance");
    RoutingDimension distanceDimension = routing.GetMutableDimension("Distance");
    distanceDimension.SetGlobalSpanCostCoefficient(100);

    var searchParameters = operations_research_constraint_solver.DefaultRoutingSearchParameters();
    searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;

    var timer = new Stopwatch();
    timer.Start();
    searchParameters.LogSearch = true;
    var solution = routing.SolveWithParameters(searchParameters);
    timer.Stop();
    Console.WriteLine(timer.Elapsed.TotalSeconds);

    var optimisedVehicleRoutes = this.CreateOptimisedVehicleLocations(locations,routing,manager,solution);

    this.OptimisedDistanceKm = optimisedVehicleRoutes.Sum(r => r.TotalDistanceKm);

    routing.Dispose();

    return optimisedVehicleRoutes;
} 

P.s。如果有人可以帮助我了解“ Slack”实际上是用于什么的,我将不胜感激。我最初假设这是每辆车的公差(即10 km的松弛度可使该车辆在其最大路线距离上行驶10 km)。但是现在我不确定

解决方法

如果您的位置在600公里,最大允许距离为500公里,那么您的问题基本上是不可行的...

但是您可以使用AddDisjunction()允许求解器放置该位置,从而使问题变得可行...

请在文档站点上查看我们的示例:https://developers.google.com/optimization/routing/penalties

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...