Skip to content
Advertisement

OR-Tools Vehicle Routing with Multiple Trips, Multiple Pickup and limited capacity

I am trying to solve a routing problem as follows:

  • We have many ‘tasks’ and each task contains many items to be collected by workers
  • items can appear in multiple tasks (e.g. item 1 can be in both task A and B)
  • We already have the distance matrix of the items
  • depot is fixed
  • in each trip, each worker can ONLY collect items in AT MOST 3 tasks (business domain constraint)

My question is how to use or-tools to implement a solver that:

  • allows each worker to “unload” the items collected at the depot and continue to next trip
  • set a constraint that limits workers to collect items in at most 3 tasks

So far I have tried:

  • treat same items appearing in n tasks as n different nodes (reflected in the distance matrix, and the distance among these n nodes are set to 0)
  • uses pickup and deliveries to model each task, so one item in each task will be pointed by other items in within the same task. And create a capacity constraint of 3 and set the demand of that node as 1. (e.g. task A contains [1, 2, 3, 4]. I add pickup and deliveries [1, 4], [2, 4], [3, 4]. Then create a capacity constraint of 3 for each worker, and set node 4 a demand of 1.) But adding this seems to kill the jupyter notebook kernal. (Removing this the code can run.)

Sorry for such a long question, thanks and please help!

Update: I made use of AddDisjunction and AddPickupAndDelivery and the results seem to be what I expected. I am not 100% sure if this is the answer to this problem. I am treating same items appearing in different tasks as different nodes. And add the whole set of items in each task as a disjunction set. For pickup and delivery, I didn’t duplicate the nodes, I simply make each item points to the same 1 item in that task.

The code I wrote (updated):

JavaScript

The result I got:

JavaScript

Advertisement

Answer

Posting my final solution for anybody who is working on a similar setting problem:

  1. allows each vehicle to “unload” the items collected at the depot and continue to next trip
  2. set a constraint that limits workers to collect items in at most 3 tasks

For 1, I simply set the number of vehicles to be equal the number of tasks. The solution found should contains a lot of vehicles with no items. Our business use case allows workers to move onto next route once he/she has finished the current route so there’s no need to mimic “loading/unloading” in ortools.

For 2, since each task has multiple items. I used a list to represent items for a particular task, e.g.:

JavaScript

Then all the items are represented by a list of list, and 0 is the depot, e.g.:

JavaScript

The key is to created a dummy node for each task and set its demand to 1:

JavaScript

add capacity constraint:

JavaScript

Then create pickup and delivery constraints, where the pickup nodes are the REAL items and the delivery nodes are the DUMMIES:

JavaScript

AddDisjunction is no longer required as my problem always has a feasible solution without dropping any node. You might add disjunctions if your problem might requires dropping nodes to get a solution.

That’s it.

If your solver get stuck finding the solution. Try to change your first solution strategy to PATH_CHEAPEST_ARC as this strategy always (I think) gives you a solution.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement