微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决或工具-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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。