Google OR Tools - Setting time window dimensions fails with low level error

725 views Asked by At

So am trying to use the VRPTW example at https://developers.google.com/optimization/routing/vrptw as a basis for some of my own code.

In my case I want to schedule over multiple days with multiple vehicles (each starting/returning at the driver's home). In the example, it is assumed that there is one depot from which all vehicles start on the one day. The first column of the time matrix is the depot number and I believe the 0 index in that code is because all vehicles leave/return from the depot.

// 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]);
} 

So in my case lets say I have three days for delivers by the two vehicles, in my time matrix I have columns for:

  • Day1 - Vehicle 1 (starts/returns from Position A)
  • Day1 - Vehicle 2 (starts/returns from Position B)
  • Day2 - Vehicle 1 (starts/returns from Position A)
  • Day2 - Vehicle 2 (starts/returns from Position B)
  • Day3 - Vehicle 1 (starts/returns from Position A)
  • Day3 - Vehicle 2 (starts/returns from Position B)

I then have an array of vehicle start and end nodes, to point to these entries. All this is working fine and I am happy with the results or-tools is providing.

Where I have a problem is that I now want to set time windows for each of the vehicles. So should look like this:

  • Day 1 - Vehicle 1 Time Window 0-1440
  • Day 1 - Vehicle 2 Time Window 0-1440
  • Day 2 - Vehicle 1 Time Window 1440-2880
  • Day 2 - Vehicle 2 Time Window 1440-2880
  • Day 3 - Vehicle 1 Time Window 2880-4320
  • Day 3 - Vehicle 2 Time Window 2880-4320

So I have changed the example code above to the code below. I thought the code looked ok but it falls over with "Could not get your data. fail" (which seems like a pretty low level error) at the indicated line.

        var useIndex = 0;
        for (int i = 0; i < data.DayCount; i++)
        {
            var fromTime = i * 1440;
            var toTime = (i + 1) * 1440;
            for (int j = 0; j < data.VehicleCount; ++j)
            {
                long index = routing.Start(useIndex);
                timeDimension.CumulVar(index).SetRange(fromTime, toTime);   <---- FAILS HERE

                useIndex++;
            }
        }

It goes through the first day fine, setting the values to 0-1440. It is when it does the second loop and tries to set the values to 1440-2880 that it fails. If I set all values to 0-1440 on every loop it is fine. So its only when I attempt to change the value that there is a problem. Any thoughts on why?

Edit 1 The stacktrace of the error message shows the error occurs here :

at Google.OrTools.ConstraintSolver.IntExpr.SetRange(Int64 l, Int64 u)

I am using Google.OrTools 9.0.9048

Edit 2 It looks like the from value has to start with 0 (0-1440 is fine). If I try to assign all ranges to 1440-2880, it fails immediately.

2

There are 2 answers

2
Mizux On BEST ANSWER

TLDR: SetRange() checks if the new range requested is in the domain, and fail otherwise.

Question: What is the vehicle capacity (aka horizon) for the time dimension ? It must be at least 4320 !

i.e. when you used something like this

routing.AddDimension(
  transit_evaluator_index,
  X, # max Slack time aka waiting time here
  Y, # <=== HERE vehicle capacity
  False, # Force start cumul to zero (not wanted for time dimension) 
  "Time") # name of the dimension and used as uid

I mean, all range values must be less or equal to Y.

1
Laurent Perron On

Do not use SetRange. Use the Solver.Add(solver.MakeBetweenCt()). The SetRange API is meant to be used inside the search.