Closed stevenshack closed 2 years ago
Added the min, max, and range methods to IntervalVar
. Can you share the Python code that uses SetStartValue
and SetEndValue
?
I don't have Python code handy, but let me illustrate with some ruby code.
Here's what I'm doing currently. I'm specifying that each vehicle should operate within its shift timeframe. Shift timeframes are relative seconds from midnight. Eg 32400 = 9AM
@shifts.each_with_index do |shift, vehicle_id| startofday = shift.start_time.beginning_of_day starttime = (shift.start_time - startofday).to_i endtime = (shift.end_time - startofday).to_i vehicle_index_start = @routing.start(vehicle_id) vehicle_index_end = @routing.end(vehicle_id) @traveltime_dimension.cumul_var(vehicle_index_start).set_range(starttime, endtime) @traveltime_dimension.cumul_var(vehicle_index_end).set_range(starttime, endtime) end
In my time dimension I have start cumul to zero set to false Time windows for delivery are similarly relative from midnight.
trip_windows.each_with_index do |time_window, location_idx| index = @manager.node_to_index(location_idx) @traveltime_dimension.cumul_var(index).set_range(time_window[0], time_window[1]) end
However I'm having problems forcing my vehicles to start within their shift timeframe. it would be useful to be able to simply force a vehicles start time to say 9am.
What I'd like to be able to do is something like this:
@traveltime_dimension.cumul_var(vehicle_index_start).SetStartValue(32400)
From what I can tell, there's no SetStartValue
method on IntVar
(the return type of CumulVar
) in Python or C++.
ah You're right, it's on IntervalVar.
So what's the right way to make a vehicle only operate within a specific timeframe? Setting start/end times doesn't seem to work. Do I iterate through every location and set the range on each one?
For reference I've looked at these or-tools threads: https://github.com/google/or-tools/issues/1052 https://github.com/google/or-tools/issues/1564 and tried setting start/end. But my vehicles still break the start time.
Setting the start and end time should be the way. Check out the VRPTW test for an example of start times:
Yup. I've checked I've got the the same code but for both start and end locations. But my vehicle keeps moving before start time. It services a node well before its shift starts.
@shifts.each_with_index do |shift, vehicle_id| startofday = shift.start_time.beginning_of_day starttime = (shift.start_time - startofday).to_i endtime = (shift.end_time - startofday).to_i vehicle_index_start = @routing.start(vehicle_id) vehicle_index_end = @routing.end(vehicle_id) @traveltime_dimension.cumul_var(vehicle_index_start).set_range(starttime, endtime) @traveltime_dimension.cumul_var(vehicle_index_end).set_range(starttime, endtime) end
I'll try and generate the smallest counterexample case I can.
As an aside I'm seeing odd behaviour with node_to_index(location_idx). I have my location matrix setup as starts[0..4], ends[4..9], Pickup/Delivery[10,11]
When I call manager.node_to_index(end_location) I get back -1. Is this expected? I only get -1 on end locations, start and P/D locations return as normal. I've checked and my starts/ends are created correctly.
I was going to simply set a time window for each and every location. Since each vehicle has a unique starting/end point that in theory would constrain the shift.
@manager.node_to_index(1) = 1 @manager.node_to_index(4) = 4 Vehicle end location gets -1 index. @manager.node_to_index(5) = -1 @manager.node_to_index(10) = 5 @manager.node_to_index(11) = 6
Yeah, that's expected for end nodes.
Cleaning up issues
The python API for or-tools has a number of useful tools for setting values and ranges - particularly useful for VRP problems. Could we add:
SetStartValue setstartmin setstartmax setstartrange
setendmin setendmax setendrange setendvalue
I believe these should make it easier to for example set the starting time of a vehicle (no more midnight deliveries!). Further making it easier to directly use the planners output without adding or subtracting error prone time offsets.