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 求解器) - 如何访问求解器找到的中间解决方案?