Skip to main content

Limiting capacity of the warehouse

Warehouses often have limited capacity, requiring restrictions on the number of trucks serviced concurrently. This model is supported by SWAT APIs and a cumulative limitation parameter can be used to enforce this constraint.

Impact on Route Planning::

Cumulative limitations in the Vehicle Routing Problem (VRP) represent constraints on the total number of resources that can be used or the total amount of a resource that can be consumed at a specific location or within a specific time frame. These limitations are often applied to depots or other service locations and can significantly impact route planning and resource allocation.

Cumulative Limitations:

Cumulative limitations define the maximum capacity or usage of a resource over time. In the context of VRP, this often refers to the number of vehicles that can be serviced simultaneously at a warehouse. For example, a warehouse might have a limited number of loading docks, restricting the number of vehicles that can be loaded or unloaded concurrently. Other examples include:

  • Warehouse Capacity: A warehouse might have a limited number of parking spaces or loading bays, restricting the number of vehicles that can be present at the warehouse at any given time.
  • Service Capacity: A service location might have a limited number of service personnel or equipment, restricting the number of vehicles that can be serviced concurrently.
  • Resource Availability: A resource, such as a specific type of fuel or a specialized tool, might be available in limited quantities, restricting the number of vehicles that can use it within a given time frame.

Example:

A delivery company operates from a central qarehouse with only two loading docks. This means that only two trucks can be loaded simultaneously. The company has a fleet of five trucks and receives the following orders:

  • Order 1: Requires loading at the warehouse.
  • Order 2: Requires loading at the warehouse.
  • Order 3: Requires loading at the warehouse.

In this example, cumulative limitation might be used to limit number of vehicles services at the same time at a warehouse with a certain set service time. Cumulative limitation is set in model_parameters of the request.

Implementation

Nodes, groups and corresponding service teime need to be set in model_parameters.cumulative_limitations configuration.

group and node_uids can be used together in the same configuration with groups used to configure a whole group with limitations, or node_uids for only select nodes.

For this option to work properly, every vehicle should have not more than one node of type vehicle_position, bound as a partial route. This node is a placeholder for the pickup event. If the partial_route contains other nodes, the vehicle_position node must be the last in the list.

The time interval when the pickups can happen is identified by the intersection (i.e. the biggest common interval) of the time windows of cumulative limitation nodes. Each service interval has a duration of depot_service_time. The list of nodes_uids objects should hold uid of the vehicle_position nodes. The scheduler will split pickup time intervals into service intervals and will create max_cumulative_vehicles pickup nodes for each service interval. The uid of the created nodes start with cumulative_. All these nodes are optional, but one and only one such node should be added to each affected vehicle. After this, the scheduler will remove the vehicle_position nodes from partial_route and instead insert pickup nodes immediately after the partial_route one per vehicle for every service interval.

For each cumulative limitation the vehicle_position nodes may belong to several groups other than set in the group. In this case the other groups in the node[”groups”] must be equal for all nodes. The created pickup nodes will inherit the group list from the vehicle_position nodes excluding the cumulative_limitation.group. For example:

cumulative_limitations = [{
"group": "CL1",
"node_uids": ["n3"],
"depot_service_time": 300,
"max_cumulative_vehicles": 3
}],
nodes: [
{"uid": "n1", groups = ["CL1", "group_a", "group_b"], <...>}, - valid
{"uid": "n2", groups = ["CL1", "group_b", "group_a"], <...>}, - valid
{"uid": "n3", groups = ["group_b", "group_a"], <...>}, - valid
{"uid": "n4", groups = ["CL1", "group_a", "group_Z"], <...>}, - NOT valid
{"uid": "n5", groups = ["group_a", "group_b", "group_Z"], <...>} - NOT valid
]
tip

Regardless of the uid in the vehicle_position nodes all created pickup nodes in the final json start with cumulative_, and same for booking_uid. The response from the stateless API will contain all temporary cumulative_ bookings in the rejected bookings. Since the pickup nodes are moved from partial_route to the main part of the route, the flag zero_cost_if_only_partial_routes is not applicable to them anymore.

Special cases

Special case cumulative_limitations with groups_order. Both features use groups and modify the partial_route. There are two ways to avoid conflicts:

  • Using separate pickup and vehicle_position nodes on each vehicle:

    • Create the groups_order with group names and their priorities,
    • Create a pickup node for groups_order with highest priority, add this highest priority group to groups of this node,
    • Create a vehicle_position nodes,
    • Add the pickup node and the vehicle_position to the partial_route; make sure the vehicle_position node is the last in the list.
  • Using the same node for pickup and vehicle_position on each vehicle:

    • Create the groups_order with group names and priorities,
    • Create a vehicle_position node, assign it the highest priority group,
    • Add the vehicle_position node uid to cumulative_limitations,
    • Add the vehicle_position node uid to partial_route,
    • Note: the uid, booking_uid and node_type of this node after the simulation will be overwritten.

Example

{
"model_parameters": {
"cumulative_limitations": [
{
"node_uids": ["10W_0_start"],
"depot_service_time": 100,
"max_cumulative_vehicles": 10
}
]
},
...
"vehicles": [
{
"agent_id": "10W_0",
"capacity": {
"CBCM": 21500000,
"WEIGHT": 11710,
},
"lat": 0,
"lon": 0,
"assigned_nodes": [
{
"uid": "10W_0_start",
"node_type": "vehicle_position",
"open_time_ts": "2022-02-18T16:00:00+00:00",
"close_time_ts": "2025-02-18T20:42:00+00:00",
"close_time_ts_dynamic": "2026-02-19T16:42:00+00:00",
"service_time": 0,
"lat": 11.975487,
"lon": 101.399407,
"stop_id": "depot",
"max_slack": null,
"demand": {
"CBCM": 0,
"WEIGHT": 0
},
"groups": [],
"trip_cost": 0
}
],
"partial_route": [
"10W_0_start",
],
"partial_route_end": [
"10W_0_end"
],
...
}
]
}