Google Or-Tools 路由 - 解决方案为空

Posted

技术标签:

【中文标题】Google Or-Tools 路由 - 解决方案为空【英文标题】:Google Or-Tools Routing - Solution is null 【发布时间】:2020-07-06 10:44:31 【问题描述】:

我正在尝试实现 Google OR-Tools 的 VRPTW。但我面临一个问题。当我传递动态时间矩阵时,解决方案对象为空,但是当我传递示例中给出的时间矩阵时,它就起作用了。

这是我的代码

 public class DataModel
    
        public long[,] DistanceMatrix  get; set; 
        public long[,] TimeMatrix = 
            //commented matrix is dynamic generated
  // 0,5,20,10,0,5,  
  //5,0,25,10,5,5,
  //20,25,0,30,20,20,
  //10,10,30,0,10,15,
  //0,5,20,10,0,5,
  //5,5,20,15,5,0,
    0, 6, 9, 8, 7, 3,
  6, 0, 8, 3, 2, 6,
  9, 8, 0, 11, 10, 6,
  8, 3, 11, 0, 1, 7,
  7, 2, 10, 1, 0, 6,
  3, 6, 6, 7, 6, 0,
;
        public long[,] TimeWindows = 
  0, 5,    // depot
  7, 12,   // 1
  10, 15,  // 2
  16, 18,  // 3
  10, 13,  // 4
  0, 5,    // 5
;
        public int VehicleNumber = 3;
        public int Depot = 0;
    ;

这里是主要功能代码

DataModel data = new DataModel();
            // data.TimeMatrix = TimeMatrix;
            // Create Routing Index Manager
            RoutingIndexManager manager = new RoutingIndexManager(
                data.TimeMatrix.GetLength(0),
                data.VehicleNumber,
                data.Depot);

            // Create a Routing Model.
            RoutingModel routing = new RoutingModel(manager);

            // Create and register a transit callback.
            int transitCallbackIndex = routing.RegisterTransitCallback(
                (long fromIndex, long toIndex) =>
                
                    // Convert from routing variable Index to distance matrix NodeIndex.
                    var fromNode = manager.IndexToNode(fromIndex);
                    var toNode = manager.IndexToNode(toIndex);
                    return data.TimeMatrix[fromNode, toNode];
                
                );

            // Define the cost of each arc.
            routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);

            // Add Distance constraint.
            routing.AddDimension(
                transitCallbackIndex, // transit callback
                30, // allow waiting time
                30, // vehicle maximum capacities
                false,  // start cumul to zero
                "Time");
            RoutingDimension timeDimension = routing.GetMutableDimension("Time");
            // Add time window constraints for each location except depot.
            for (int i = 1; i < data.TimeWindows.GetLength(0); ++i)
            
                long index = manager.NodeToIndex(i);
                timeDimension.CumulVar(index).SetRange(
                    data.TimeWindows[i, 0],
                    data.TimeWindows[i, 1]);
            
            // Add time window constraints for each vehicle start node.
            for (int i = 0; i < data.VehicleNumber; ++i)
            
                long index = routing.Start(i);
                timeDimension.CumulVar(index).SetRange(
                    data.TimeWindows[0, 0],
                    data.TimeWindows[0, 1]);
            

            // Instantiate route start and end times to produce feasible times.
            for (int i = 0; i < data.VehicleNumber; ++i)
            
                routing.AddVariableMinimizedByFinalizer(
                    timeDimension.CumulVar(routing.Start(i)));
                routing.AddVariableMinimizedByFinalizer(
                    timeDimension.CumulVar(routing.End(i)));
            

            // Setting first solution heuristic.
            RoutingSearchParameters searchParameters =
              operations_research_constraint_solver.DefaultRoutingSearchParameters();
            searchParameters.FirstSolutionStrategy =
              FirstSolutionStrategy.Types.Value.PathCheapestArc;

            // Solve the problem.
            Assignment solution = routing.SolveWithParameters(searchParameters);  //it is null when dynamic time matrix is used, but it is not null when time matrix mentioned in example is used.

问题似乎出在 AddDimension 方法中。我对此感到震惊,但找不到任何解决方案。请提出任何解决方案。

【问题讨论】:

【参考方案1】:

Solution 为 null 表示求解器无法找到任何可行的解决方案。很可能您的时间窗口太紧了。

或者尝试放松你的时间窗口

或确保节点是可选的(使用 addDisjunction)。

【讨论】:

是的,问题出在时间窗口上。实际时间窗口是什么意思?是否像位置 1 的时间窗口是 (7,11) 那样以分钟为单位的持续时间,这意味着司机应该在 7 到 11 分钟内到达位置 1? 您决定什么是时间单位。单位时间为 1 分钟是一个合理的选择。求解器是完全不可知的,只理解正整数,无论​​它们的语义如何。 我可以再问一个问题吗?如何获得每辆车的路线长度?实际上,我必须为每辆车限制 2 条路线。是否可以?如果是,那怎么办? 您需要展开每条路线。请参阅代码示例中的打印功能。

以上是关于Google Or-Tools 路由 - 解决方案为空的主要内容,如果未能解决你的问题,请参考以下文章

Google Or-Tools:UnsatisfiedLinkError

Googles OR-Tools Modules for CSP 和 VRP 使用哪个求解器?

Google OR-Tools(使用 SCIP 求解器) - 如何访问求解器找到的中间解决方案?

有没有办法在 OR-Tools 路由中设置特定的出发点和到达点?

如何获取 Google OR-Tools 的进度日志?

google or-tools 无法获得最佳 LP 结果,如 gurobi 示例