1 year ago
#238230
Seraph
CVRPSPD (Capacitated Vehicle Routing Problem with Simultaneous Pickup and Delivery)
I really need help with this problem.
The setup of the problem I am attempting to solve is as follows:
There is a depot from which all vehicles are dispatched. Vehicles are loaded with a number of full bins at the depot. Vehicles travel from the depot to sites, where they drop off full bins and pick up empty bins. Vehicles continue to visit sites until they have saturated their capacity with empty bins from sites. Once saturated with empty bins, vehicles return to the depot, drop off their empty bins, and pick up full bins. This process repeats until all sites have had their demand for pickups of empty bins and dropoffs of full bins met, with vehicles completing multiple tours if necessary. Minimizing the total amount of time required to satisfy all site demands should be the objective.
I have begun by modifying this example cvrp_reload but am struggling with the combination of these two dimensions: pickups of empty bins and deliveries of full bins.
The main idea of my code:
- use a dimension to track the pickups of empty bins.
- use another dimension to track the deliveries of full bins.
- the cumulated sum of empty bins and full bins on the vehicle <= vehicle capacity
- duplicate depots so the vehicle could revisit the depot to unload the empty bins and reload full bins when necessary.
The problem here is that:
- I made up a simple example that the pickups and deliveries demand is: [0, 4, 6, 2, 3] and [0, -5, -5, -2, -3], the vehicle capacity is 6 (I use only one single vehicle here). I duplicate 2 depots.
_locations = [
(4, 4), # depot
(2, 0), (8, 0), # 1, 2
(0, 1), (1, 1)] # 3, 4
_locations[1:1] = tuple(repeat(_locations[0], _duplicate_depot_num))
data['locations'] = _locations
data['num_locations'] = len(data['locations'])
data['pickups'] = [0, 4, 6, 2, 3] # pick up empty bins
data['pickups'][1:1] = tuple(repeat(-_capacity, _duplicate_depot_num))
data['deliveries'] = [0, -5, -5, -2, -3] # delivery full bins
data['deliveries'][1:1] = tuple(repeat(_capacity, _duplicate_depot_num))
When I set the capacity as 6, the solver dropped node 4(pick up 6, delivery -5). Because when it revisits depot, it is always loaded with a max capacity which is 6. The result:
[(4, 4), (4, 4), (4, 4), (2, 0), (8, 0), (0, 1), (1, 1)]
Objective: 100026
dropped orders: [4]
dropped reload stations: [4, 2]
Route for vehicle 0:
0 Pickups(0) Deliveries(0)-> 3 Pickups(0) Deliveries(5)-> 1 Pickups(4) Deliveries(0)-> 6 Pickups(0) Deliveries(6)-> 5 Pickups(3) Deliveries(3)-> 0 Pickups(5) Deliveries(1)
Distance of the route: 26m
Pickups of the route: 5
Deliveries of the route: 1
This is obviously not the optimal solution, because obviously, the vehicle could first depart with a load of 5 full bins and immediately visit node 4, then visit nodes 3, 5, 6. Why node 4 is dropped?
- When I set the capacity as 10, the result is:
[(4, 4), (4, 4), (4, 4), (2, 0), (8, 0), (0, 1), (1, 1)]
Objective: 32
dropped orders: []
dropped reload stations: [2]
Route for vehicle 0:
0 Pickups(0) Deliveries(0)-> 3 Pickups(0) Deliveries(10)-> 6 Pickups(4) Deliveries(5)-> 5 Pickups(7) Deliveries(2)-> 1 Pickups(9) Deliveries(0)-> 4 Pickups(0) Deliveries(10)-> 0 Pickups(6) Deliveries(5)
Distance of the route: 32m
Pickups of the route: 6
Deliveries of the route: 5
Notice the last step the vehicle return to the depot with Deliveries(5) and Pickups(6) which is 11 in sum, and it is larger than 10!!! Given I add the following constraint, why does it results like this?
# Add Constraint: Pick + Deliveries <= max_capacity
for node in range(len(data['pickups'])):
index = manager.NodeToIndex(node)
routing.solver().Add(
pickups_dimension.CumulVar(index) + deliveries_dimension.CumulVar(index) <= data["vehicle_capacity"])
My full code is here: cvrpspd.ipynb and I have been struggling with this problem for several days. Any insights would be greatly appreciated! Thank you!!
python
routes
or-tools
pickup
0 Answers
Your Answer