-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
constraint on max travel time not enforced, CVRPTW, pickup/delivery, IntExpr, CumulVar #685
Comments
I would say:
if delivery_index > 0:
solver.Add(routing.VehicleVar(index) == routing.VehicleVar(delivery_index)) # 1)
solver.Add(time_dimension.CumulVar(index) <= time_dimension.CumulVar(delivery_index)) # 2)
min_dur = int(travel_time_callback(index, delivery_index))
max_dur = int(max_dur_mult * min_dur)
dur_expr = time_dimension.CumulVar(delivery_index) - time_dimension.CumulVar(index)
solver.Add(dur_expr <= max_dur) # 3)
routing.AddPickupAndDelivery(i, dropoffs[i])
print dur_constraint i.e. what you want:
|
@Mizux Thank you. No dice, though I've made an interesting finding. If I give the solver an easy way out by ensuring there are as many vehicles available as customers and that vehicle capacity is 1, such that each customer must be served alone, a solution is found incredibly fast. This indicates to me that the time constraints I'm imposing are not in fact unsatisfiable. In the original case where each vehicle has enough capacity for all customers, the solver is getting stuck iterating the entire search space with 2 vehicles rather than investigating solution candidates using more vehicles. I understand convergence speed is highly affected by the initial solution, and maybe my failing case gets stuck in local optima, but I've let this thing run for quite a long time on such a small data set. Are there any search parameter flags you recommend tweaking that might help it jump out of local optima to investigate candidates using more vehicles, or ways I can log and see whether the entire search space has indeed been exhausted, maybe via search monitor?
particularly odd. why does adding one seat make the problem intractable?
I've updated gist with your suggestions, and added a couple options to make testing easier
updated to ortools (6.7.4973) |
my 2 cents,
|
@Mizux thanks for the pointers.
Final observation. There are failing cases which terminate FASTER than the search time limit. If I understand local search, it will run exhaustively until time limit or feasible solution is reached. Since, intuitively, adding more vehicle capacity should not preclude a solution, yet the solver failing prior to time limit, it has either exhausted every solution candidate (unlikely), or determined according to another criteria to terminate search.
|
Hi, Concerning objective value: Now when you create a dimension "Foo" and set a globalSpan coefficient k != 0 e.g. In your case supposing you have set cumul var to zero in your time dimension i.e. min vehicle start is 0: Maybe your "total duration of all routes" is the objective value which is not anymore equivalent to the sum of all end cumul_var of the time dimension ;) note: you can add severals dim to objective i.e. non zero coeff to differents dimensions, in this case coefs weight the different incentives (or how to compare time cost, to distance cost, to order number cost etc...). |
Hi, Did anybody found a way to limit the max travel time per vehicle? I tried some of the things posted in this issue but couldn't make it work. Thanks! |
Off topic.. Just create a "Time" Dimension and set the vehicle capacity to |
Thanks @Mizux , what I meant was to limit the maximum time distance traveled per vehicle. For example, say I want to restrict to traveling 12 hours, if I add this the way you told me then I get a: ~/.local/lib/python3.6/site-packages/ortools/constraint_solver/pywrapcp.py in SetRange(self, l, u)
1337
1338 def SetRange(self, l: 'int64', u: 'int64') -> "void":
-> 1339 return _pywrapcp.IntExpr_SetRange(self, l, u)
1340
1341 def SetValue(self, v: 'int64') -> "void":
Exception: CP Solver fail when I try to add a destination with a time window starting after 12h. Did I understood this correctly? Sorry for the off topic, should I create a new issue? Thanks again! ;) |
@bertop89 Not to step on toes but definitely create a new issue :) It will depend on whether your As far as your error, paste all of your code. if it's large use https://gist.github.com/ |
@Mizux While we're back here, regarding the original issue, all of your suggestions were certainly improvements. I now understand
My guess is that, in the latter execution, 2 customers begin on a vehicle which cannot satisfy time constraints.
|
Inspect don't know yet. But at least you can enable some log using: search_parameters.log_search = True e.g. if I hack cvrp.py $ examples/python/cvrp.py
WARNING: Logging before InitGoogleLogging() is written to STDERR
I0619 13:58:50.682148 116024 search.cc:241] Start search (memory used = 22.41 MB)
I0619 13:58:50.682247 116024 search.cc:241] Root node processed (time = 0 ms, constraints = 89, memory used = 22.41 MB)
I0619 13:58:50.682484 116024 search.cc:241] Solution #0 (7032, time = 0 ms, branches = 34, failures = 0, depth = 33, memory used = 22.41 MB)
I0619 13:58:50.682811 116024 search.cc:241] Solution #1 (6872, objective maximum = 7032, time = 0 ms, branches = 37, failures = 2, depth = 33, neighbors = 282, filtered neighbors = 1, accepted neighbors = 1, memory used = 22.41 MB)
I0619 13:58:50.684059 116024 search.cc:241] Finished search tree (time = 1 ms, branches = 73, failures = 38, neighbors = 1190, filtered neighbors = 1, accepted neigbors = 1, memory used = 22.41 MB)
I0619 13:58:50.684094 116024 search.cc:241] End search (time = 1 ms, branches = 73, failures = 38, memory used = 22.41 MB, speed = 73000 branches/s)
... |
Initial search is mandatory for starting local search. For writing a Pickup&Delivery you need three statements
e.g. supposing there is a "distance" dimension (also work with "time/duration" dimension if any). routing.AddPickupAndDelivery(routing.NodeToIndex(1),routing.NodeToIndex( 2))
routing.solver().Add(routing.CumulVar(routing.NodeToIndex(1), "distance") <= routing.CumulVar(routing.NodeToIndex(2), "distance"))
routing.solver().Add(routing.VehicleVar(routing.NodeToIndex(1)) == routing.VehicleVar(routing.NodeToIndex(2))) src: https://github.com/google/or-tools/blob/master/examples/cpp/pdptw.cc#L268 |
AFAIK the open source FSS (First Solution Strategy) is not good at back tracking so sometime it just can't find any solution.
|
No problem! @Jylanthas @Mizux if you know another way to force same vehicle to visit node/set of nodes, please let me know. I have opened an issue for that #847 (comment) Thank you! |
How did you model these constraints ? Did you use constraintActive = routing.ActiveVar(routing.NodeToIndex(208)) * routing.ActiveVar(routing.NodeToIndex(204))
routing.solver().Add(
constraintActive * routing.VehicleVar(routing.NodeToIndex(208)) ==
constraintActive * routing.VehicleVar(routing.NodeToIndex(204))) since solver will add node one by one during the first strategy ("greedy algorithm") step, if you don't use |
@Mizux and @Jylanthas Any idea how to do this from one of the previous suggestions
In java? If I try to subtract one IntVar from the other I get this error
I also logged this on StackOverflow What I am trying to achieve is to ensure that the total duration (i.e on duty time of driver) is not exceeding a time limit.... since there can be a significant waiting time at the first depot node, due to time windows, I cant simply constrain the time dimension to the allowed on duty time as the slack will exceed the total allowed time. That is why I wanted to add the following condition
|
since Java do not provide operator overload (i.e. override operator
for (int i = 0; i < data.vehicleNumber; ++i) {
solver.addConstraint(
solver.makeLessOrEqual(
solver.makeDifference(
timeDimension.cumulVar(routing.end(i)),
timeDimension.cumulVar(routing.start(i))),
onDutyTimeLimit));
} |
I'm not sure whether my expectations are unreasonable or if I've stumbled upon a bug. I've configured a CVRPTW with pickup and delivery precedence constraints. I would like to place a maximum allowable travel time (pickup to dropoff) constraint per individual customer, where the max travel time is a constant
= some_coefficient *direct_travel_time(pickup_node, dropoff_node)
. The idea being "riders should not endure more than 1.3x their direct path driving time". I've added a reproducible stripped-down gist. Let me know if this is not easy to work with. Thanks a bunch in advance.https://gist.github.com/Jylanthas/a9878ace7445ffc6f0b7246ff90eac53
constraint excerpt from gist
result
expect
plan_dur
<=max_dur
, in the console print, whereplan_dur = dropoff_at - pickup_at
as retrieved fromassignment.Value(time_dimension.CumulVar(respective pickup or dropoff node index))
ortools (5.1.4045)
pip 1.5.6
python 2.7
Mac Sierra 10.12.5
The text was updated successfully, but these errors were encountered: