Skip to content

Load and capacities

In this tutorial we dive deeper into the modelling of deliveries, pickups, and vehicle capacities. We jointly refer to pickup and delivery amounts as load. When a task requires a particular delivery amount, that amount needs to travel from the depot to the task. Similarly, a pickup amount needs to travel from the task back to the depot - a case of reverse logistics. Tasks may simultaneously require pickups and deliveries. The total amount of load present in the vehicle must not at any point exceed the vehicle capacity. Let’s look at a few simple examples.

Deliveries

Let's first look at a small delivery example with two tasks: a delivery to Rotterdam requiring 4 units, and a delivery to Amsterdam requiring 5 units. The delivery demand is loaded into a vehicle with 10 capacity at the depot in Utrecht, and then delivered to each location. This models a classic capacitated vehicle routing problem.

request.json
{
  "locations": [
    {
      "id": "loc-Rotterdam",
      "latitude": 51.9255,
      "longitude": 4.4786
    },
    {
      "id": "loc-Amsterdam",
      "latitude": 52.3676,
      "longitude": 4.9041
    },
    {
      "id": "loc-Utrecht",
      "latitude": 52.0907,
      "longitude": 5.1214
    }
  ],
  "tasks": [
    {
      "id": "task-Rotterdam",
      "location": "loc-Rotterdam",
      "delivery": [
          4
      ]
    },
    {
      "id": "task-Amsterdam",
      "location": "loc-Amsterdam",
      "delivery": [
          5
      ]
    }
  ],
  "depots": [
    {
      "id": "depot-Utrecht",
      "location": "loc-Utrecht"
    }
  ],
  "vehicle_types": [
    {
      "id": "vehicle_type",
      "start_depot": "depot-Utrecht",
      "end_depot": "depot-Utrecht",
      "num_available": 2,
      "capacity": [
        10
      ],
      "shift": {
        "earliest_start": "2025-01-01T08:00:00",
        "latest_end": "2025-01-01T18:00:00"
      }
    }
  ],
  "options": {
    "stop": {
      "seconds": 1,
      "type": "max_runtime"
    }
  }
}

A single vehicle is assigned since the total delivery demand sums to just 9, below the vehicle's capacity of 10.

The vehicle's load progresses along the route as follows:

Location Load
Utrecht 9
Rotterdam 5
Amsterdam 0
Utrecht 0

Mixed pickups and deliveries

Beyond simple deliveries, tasks can also require pickups. A pickup is loaded at the task location, and returned to the depot. Consider this new scenario, where Rotterdam now requires delivery of 4 units and pickup of 6 units, while Amsterdam requires delivery of 5 units and pickup of 4 units.

request.json
{
  "locations": [
    {
      "id": "loc-Rotterdam",
      "latitude": 51.9255,
      "longitude": 4.4786
    },
    {
      "id": "loc-Amsterdam",
      "latitude": 52.3676,
      "longitude": 4.9041
    },
    {
      "id": "loc-Utrecht",
      "latitude": 52.0907,
      "longitude": 5.1214
    }
  ],
  "tasks": [
    {
      "id": "task-Rotterdam",
      "location": "loc-Rotterdam",
      "delivery": [
          4
      ],
      "pickup": [
          6
      ]
    },
    {
      "id": "task-Amsterdam",
      "location": "loc-Amsterdam",
      "delivery": [
          5
      ],
      "pickup": [
          4
      ]
    }
  ],
  "depots": [
    {
      "id": "depot-Utrecht",
      "location": "loc-Utrecht"
    }
  ],
  "vehicle_types": [
    {
      "id": "vehicle_type",
      "start_depot": "depot-Utrecht",
      "end_depot": "depot-Utrecht",
      "num_available": 2,
      "capacity": [
        10
      ],
      "shift": {
        "earliest_start": "2025-01-01T08:00:00",
        "latest_end": "2025-01-01T18:00:00"
      }
    }
  ],
  "options": {
    "stop": {
      "seconds": 1,
      "type": "max_runtime"
    }
  }
}

The presence of pickups changes which routes are feasible. The vehicle cannot visit Rotterdam before Amsterdam, as the load would exceed capacity: 9 - 4 + 6 = 11. Instead, Amsterdam must be visited first:

The vehicle's load progresses as follows:

Location Load Calculation
Utrecht 9 Load deliveries (4 + 5)
Amsterdam 8 9 - 5 (delivery) + 4 (pickup)
Rotterdam 10 8 - 4 (delivery) + 6 (pickup)
Utrecht 10 Unload pickups (6 + 4)

Multiple load dimensions

We have so far looked at only a single load dimension. FastVRP supports arbitrarily many load dimensions, which can be helpful to express constraints on weight, volume, and number of tasks.

Let's extend the delivery example with extra dimensions for volume (in cm³) and number of tasks. Rotterdam requires [4, 1600, 1] and Amsterdam requires [5, 2500, 1], representing weight, volume and task count respectively. The vehicle capacity is [10, 1000000, 1], limiting it to 10 kg, 1,000,000 cm³ and at most 1 task.

request.json
{
  "locations": [
    {
      "id": "loc-Rotterdam",
      "latitude": 51.9255,
      "longitude": 4.4786
    },
    {
      "id": "loc-Amsterdam",
      "latitude": 52.3676,
      "longitude": 4.9041
    },
    {
      "id": "loc-Utrecht",
      "latitude": 52.0907,
      "longitude": 5.1214
    }
  ],
  "tasks": [
    {
      "id": "task-Rotterdam",
      "location": "loc-Rotterdam",
      "delivery": [
          4,
          1600,
          1
      ]
    },
    {
      "id": "task-Amsterdam",
      "location": "loc-Amsterdam",
      "delivery": [
          5,
          2500,
          1
      ]
    }
  ],
  "depots": [
    {
      "id": "depot-Utrecht",
      "location": "loc-Utrecht"
    }
  ],
  "vehicle_types": [
    {
      "id": "vehicle_type",
      "start_depot": "depot-Utrecht",
      "end_depot": "depot-Utrecht",
      "num_available": 2,
      "capacity": [
          10,
          1000000,
          1
      ],
      "shift": {
        "earliest_start": "2025-01-01T08:00:00",
        "latest_end": "2025-01-01T18:00:00"
      }
    }
  ],
  "options": {
    "stop": {
      "seconds": 1,
      "type": "max_runtime"
    }
  }
}

Each dimension is considered independently: the vehicle's load must not exceed the capacity in any dimension at any point along the route. Although the total weight and volume both fit in a single vehicle, the task limit of 1 means each vehicle can only visit one task. Two vehicles are therefore needed:

Conclusion

In this tutorial you learned how FastVRP's load modelling works. You now understand how to use pickups, deliveries, and vehicle capacities to model a wide range of constraints.

Tip

If the total load exceeds your fleet's capacity, FastVRP prioritises tasks with higher priority values (see Task priorities). You can also consider reloading, which allows vehicles to replenish their capacity mid-route.