Multi-product demands and vehicle capacities

280 views
Skip to first unread message

Ayca

unread,
Feb 16, 2021, 9:55:00 AM2/16/21
to or-tools-discuss
Hello,

I'm working on multi-depot CVRPTW problem. My problem includes 2 depots, 4 vehicles, 19 customers. And also includes 3 types of products. The vehicle that goes to the customer meets the demands of all 3 products belonging to that customer.

Customers have a different number of demands for each product:

data['demands'] =  [[0, 0, 0],
                        [0, 0, 0],
                        [150000, 10000, 8000],
                        [170000, 10000, 8000],
                        [240000, 20000, 25000],
                        [200000, 5000, 5000],
                        [220000, 14000, 20000],
                        [140000, 4000, 5000],
                        [300000, 22000, 15000],
                        [130000, 9000, 7000],
                        [150000, 5000, 4000],
                        [280000, 15000, 20000],
                        [180000, 12000, 15000],
                        [140000, 9000, 12000],
                        [20000, 5000, 6000],
                        [250000, 6000, 5000],
                        [180000, 12000, 10000],
                        [160000, 2500, 2500],
                        [120000, 2000, 2000],
                        [120000, 2000, 2000],
                        [90000, 3000, 3000]]

Vehicles have a different number of capacities for each product:

data['vehicle_capacities'] = [[1100000, 60000, 60000],
                                                [1100000, 60000, 60000],
                                                [700000, 40000, 50000],
                                                [700000, 40000, 50000]]

I'm trying to add demand constraints and vehicle capacity constraints. 

def create_demand_evaluator(data, manager):
    """Creates callback to get demands at each location."""
    _demands = data['demands']
    y=[]
    for i in range(0,21):
        y.append(int(_demands[i][0] + _demands[i][1] + _demands[i][2]))
                
    def demand_evaluator(from_index):
        """Returns the demand of the current node"""
        # Convert from routing variable Index to demands NodeIndex.
        from_node = manager.IndexToNode(from_index)
        return y[from_node]

    return demand_evaluator


def add_capacity_constraints(manager,routing, data, demand_evaluator_index):
    """Adds capacity constraint"""
    capacity = 'Capacity'
    for i in range(0,4):
        for j in range(0,3):
            routing.AddDimensionWithVehicleCapacity(
                    demand_evaluator_index,
                    0,  # null capacity slack
                    int(data['vehicle_capacities'][i][j]),
                    True,  # start cumul to zero
                    capacity)

# Add Capacity constraint
    demand_evaluator_index = routing.RegisterUnaryTransitCallback(create_demand_evaluator(data, manager))
    add_capacity_constraints(manager,routing, data, demand_evaluator_index)

I wrote like this. Is it correct? I took a error because of add_capacity_constraints. How can I add constraints and fix problems?

Thanks a lot in advance.




blind.lin...@gmail.com

unread,
Feb 16, 2021, 12:29:03 PM2/16/21
to or-tools...@googlegroups.com
I would suggest that you need to create unique dimensions for each
slot in capacity. I think you are almost there, but you are not
changing the "name" of the dimension. So perhaps this is the change
you need?

``` python
# (note I changed the last thing to demand_evaluator_fn)

def add_capacity_constraints(manager,routing, data, demand_evaluator_fn):
"""Adds capacity constraint"""
capacity_dimension_name = 'Capacity'

for jth_item in range(0,3):
# fix the dimension name to be unique
jth_item_capacity_name = f'{capacity_dimension_name}_item_{jth_item}'

# get a vector of capacities for each of the vehicles (your i iterator, I think)
vehicle_capacities = [vehicle_capacities[i][jth_item]
for i in range(0,4)] # i is per vehicle, I think
# create the callback function for the demand for this item
demand_evaluator_index = routing.RegisterUnaryTransitCallback(demand_evaluator_fn(jth_item))

routing.AddDimensionWithVehicleCapacity(
demand_evaluator_index,
0, # null capacity slack
vehicle_capacities,
True, # start cumul to zero
jth_item_capacity_name)

# Create callback function generator
demand_evaluator_fn = create_demand_evaluator(data, manager)
add_capacity_constraints(manager,routing, data, demand_evaluator_fn)

```

Something like that. I didn't double check things, so this probably
won't work, but the idea is the vehicle capacities is a vector (per
vehicle), and the dimension name must change for each new dimension.

Hope that helps,
James
> --
> You received this message because you are subscribed to the Google Groups "or-tools-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to or-tools-discu...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/or-tools-discuss/24011098-c1e8-4853-a7d2-b1e49aa075f2n%40googlegroups.com.


--

James E. Marca
Activimetrics LLC
Reply all
Reply to author
Forward
0 new messages