> ## Documentation Index
> Fetch the complete documentation index at: https://docs.solvice.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Capacity Management

> Configure and optimize vehicle capacity constraints with multi-dimensional support

# Capacity Management

The VRP solver provides comprehensive capacity management features to handle real-world loading constraints. From simple weight limits to complex multi-dimensional capacity tracking, this guide covers all capacity-related features.

## Overview

Capacity management ensures that vehicles don't exceed their loading limits while optimizing resource utilization. The solver supports:

* Multi-dimensional capacity (weight, volume, pallets, etc.)
* Dynamic capacity tracking for pickup/delivery operations
* Capacity utilization optimization
* Soft capacity constraints with violations

## Basic Capacity Configuration

### Single-Dimension Capacity

The simplest form uses a single capacity value:

```json theme={null}
{
  "resources": [
    {
      "name": "delivery-truck",
      "capacity": [1000],
      "shifts": [{
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T18:00:00Z"
      }]
    }
  ],
  "jobs": [
    {
      "name": "delivery-1",
      "location": {"latitude": 52.520, "longitude": 13.405},
      "load": [150],
      "duration": 600
    },
    {
      "name": "delivery-2", 
      "location": {"latitude": 52.523, "longitude": 13.401},
      "load": [200],
      "duration": 600
    }
  ]
}
```

<Tip>
  Always ensure that job loads and resource capacities have the same number of dimensions. If a resource has `capacity: [1000, 50]`, all jobs must have loads like `load: [weight, volume]`.
</Tip>

### Multi-Dimensional Capacity

Handle multiple capacity constraints simultaneously:

```json theme={null}
{
  "resources": [
    {
      "name": "delivery-van",
      "capacity": [2000, 15, 24],  // [weight_kg, volume_m3, pallet_positions]
      "shifts": [{
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T18:00:00Z"
      }]
    }
  ],
  "jobs": [
    {
      "name": "furniture-delivery",
      "location": {"latitude": 52.520, "longitude": 13.405},
      "load": [300, 4, 2],  // 300kg, 4m³, 2 pallet positions
      "duration": 1800
    },
    {
      "name": "appliance-delivery",
      "location": {"latitude": 52.523, "longitude": 13.401},
      "load": [150, 2, 1],  // 150kg, 2m³, 1 pallet position
      "duration": 900
    }
  ]
}
```

<Info>
  The solver tracks all capacity dimensions independently. A vehicle can only accept a job if ALL capacity dimensions have sufficient remaining space.
</Info>

<Warning>
  **Dimension Limit**: The solver supports a maximum of 5 capacity dimensions. If you need to track more than 5 different capacity types, consider combining related dimensions or using multiple optimization runs.
</Warning>

## Pickup and Delivery Capacity

For pickup and delivery operations, capacity changes dynamically during the route:

```json theme={null}
{
  "resources": [
    {
      "name": "courier-1",
      "capacity": [500],
      "shifts": [{
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T18:00:00Z",
        "start": {"latitude": 52.520, "longitude": 13.405},
        "end": {"latitude": 52.520, "longitude": 13.405}
      }]
    }
  ],
  "jobs": [
    {
      "name": "pickup-order-123",
      "location": {"latitude": 52.523, "longitude": 13.401},
      "load": [50],  // Positive load = pickup (adds to vehicle)
      "duration": 300,
    },
    {
      "name": "delivery-order-123",
      "location": {"latitude": 52.517, "longitude": 13.388},
      "load": [50],  // Same load = delivery (removes from vehicle)
      "duration": 300,
    }
  ],
  "relations": [
    {
      "type": "PICKUP_AND_DELIVERY",
      "jobs": ["pickup-order-123", "delivery-order-123"]
    }
  ]
}
```

### Capacity Flow Example

<Steps>
  <Step title="Initial State">
    Vehicle starts empty: `0 / 500 kg`
  </Step>

  <Step title="After Pickup">
    Load increases: `50 / 500 kg`
  </Step>

  <Step title="After Delivery">
    Load decreases: `0 / 500 kg`
  </Step>
</Steps>

## Active Capacity Coefficient

The `activeCapacityCoefficient` optimizes vehicle utilization by preferring fuller vehicles:

```json theme={null}
{
  "options": {
    "weights": {
      "activeCapacityCoefficient": 0.7,
      "capacityDiscountCoefficient": 0.1
    }
  }
}
```

<ParamField path="activeCapacityCoefficient" type="number" default="0.7">
  Controls preference for using vehicle capacity efficiently. Higher values (0.8-1.0) strongly prefer fuller vehicles, while lower values (0.3-0.5) allow more distributed loading.
</ParamField>

<ParamField path="capacityDiscountCoefficient" type="number" default="0.1">
  Discount factor for capacity utilization scoring. Helps balance between filling vehicles completely vs. other objectives.
</ParamField>

### How Active Capacity Works

The solver calculates a capacity utilization score for each vehicle:

<Tabs>
  <Tab title="Concept">
    The active capacity coefficient encourages the solver to:

    1. Use fewer vehicles by filling them more completely
    2. Reduce partial loads and empty space
    3. Consolidate deliveries when possible

    **Score Impact Formula:**

    ```
    utilization_score = (used_capacity / total_capacity) * activeCapacityCoefficient
    ```
  </Tab>

  <Tab title="Example Impact">
    With `activeCapacityCoefficient: 0.8`:

    * Vehicle A: 90% full → High preference score
    * Vehicle B: 30% full → Low preference score
    * Result: Solver prefers adding jobs to Vehicle A

    With `activeCapacityCoefficient: 0.3`:

    * Load distribution matters less
    * Other factors (distance, time) dominate
  </Tab>

  <Tab title="Configuration">
    ```json theme={null}
    {
      "options": {
        "weights": {
          // High value: Prioritize full vehicles
          "activeCapacityCoefficient": 0.9,
          
          // Medium value: Balance capacity with other objectives
          "activeCapacityCoefficient": 0.5,
          
          // Low value: Allow distributed loading
          "activeCapacityCoefficient": 0.2
        }
      }
    }
    ```
  </Tab>
</Tabs>

## Dynamic Capacity Tracking for PDP

Pickup and Delivery Problems (PDP) require sophisticated capacity tracking as vehicle loads change throughout the route:

### Real-Time Capacity Updates

<Steps>
  <Step title="Track Current Load">
    The solver maintains real-time load state for each vehicle:

    ```json theme={null}
    {
      "vehicleState": {
        "currentLoad": [300, 5],  // [weight_kg, volume_m3]
        "remainingCapacity": [700, 10],  // Available space
        "maxCapacityReached": [450, 8]  // Peak during route
      }
    }
    ```
  </Step>

  <Step title="Validate Each Stop">
    Before adding a job, the solver checks:

    * Can the vehicle handle the pickup load?
    * Will future deliveries free enough space?
    * Does the route respect capacity at all times?
  </Step>

  <Step title="Optimize Load Sequence">
    The solver may reorder stops to manage capacity:

    * Group pickups early when possible
    * Schedule deliveries to free space for later pickups
    * Balance load throughout the route
  </Step>
</Steps>

### Complex PDP Example

Here's a real-world scenario with multiple pickups and deliveries:

```json theme={null}
{
  "resources": [{
    "name": "courier-van",
    "capacity": [1000, 12],  // 1000kg, 12m³
    "shifts": [{
      "from": "2024-03-15T08:00:00Z",
      "to": "2024-03-15T18:00:00Z"
    }]
  }],
  "jobs": [
    // Morning pickups from suppliers
    {
      "name": "pickup-supplier-a",
      "location": {"latitude": 52.520, "longitude": 13.405},
      "load": [200, 3],
      "duration": 900,
      "windows": [{"from": "2024-03-15T08:00:00Z", "to": "2024-03-15T10:00:00Z"}]
    },
    {
      "name": "pickup-supplier-b",
      "location": {"latitude": 52.525, "longitude": 13.410},
      "load": [300, 4],
      "duration": 900,
      "windows": [{"from": "2024-03-15T08:00:00Z", "to": "2024-03-15T10:00:00Z"}]
    },
    
    // Midday deliveries to customers
    {
      "name": "deliver-customer-1",
      "location": {"latitude": 52.515, "longitude": 13.400},
      "load": [150, 2],
      "duration": 600,
      "windows": [{"from": "2024-03-15T11:00:00Z", "to": "2024-03-15T13:00:00Z"}]
    },
    
    // Afternoon mixed operations
    {
      "name": "pickup-return-1",
      "location": {"latitude": 52.510, "longitude": 13.395},
      "load": [100, 1],
      "duration": 600,
      "windows": [{"from": "2024-03-15T14:00:00Z", "to": "2024-03-15T16:00:00Z"}]
    },
    {
      "name": "deliver-customer-2",
      "location": {"latitude": 52.530, "longitude": 13.415},
      "load": [250, 3],
      "duration": 600,
      "windows": [{"from": "2024-03-15T15:00:00Z", "to": "2024-03-15T17:00:00Z"}]
    },
    {
        "name": "deliver-warehouse",
        "location": {"latitude": 52.210, "longitude": 13.195},
         "load": [100, 1],
         "duration": 300
    },
  ],
    "relations": [
        {
         "type": "PICKUP_AND_DELIVERY",
          "jobs": ["pickup-supplier-a", "deliver-customer-1"]
     },
     {
         "type": "PICKUP_AND_DELIVERY",
          "jobs": ["pickup-supplier-b", "deliver-customer-2"]
     },
     {
        "type": "PICKUP_AND_DELIVERY",
        "jobs": ["pickup-return-1", "deliver-warehouse"]
     }
    ]
}
```

### Capacity Timeline Visualization

The solver tracks how capacity changes throughout the route:

```
Time     | Stop                 | Action   | Load Change | Current Load | Remaining
---------|---------------------|----------|-------------|--------------|------------
08:00    | Start               | -        | -           | [0, 0]       | [1000, 12]
08:30    | pickup-supplier-a   | PICKUP   | +[200, 3]   | [200, 3]     | [800, 9]
09:15    | pickup-supplier-b   | PICKUP   | +[300, 4]   | [500, 7]     | [500, 5]
11:30    | deliver-customer-1  | DELIVERY | -[200, 3]   | [300, 4]     | [700, 8]
14:30    | pickup-return-1     | PICKUP   | +[100, 1]   | [400, 5]     | [600, 7]
16:00    | deliver-customer-2  | DELIVERY | -[300, 4]   | [100, 1]     | [900, 11]
17:00    | deliver-warehouse   | DELIVERY | -[100, 1]   | [0, 0]       | [1000, 12]
```

<Info>
  The solver ensures that at no point does the current load exceed the vehicle's capacity in any dimension.
</Info>

## Common Use Cases

### 1. Last-Mile Delivery

Standard parcel delivery with weight and volume constraints:

<CodeGroup>
  ```json Weight Only theme={null}
  {
    "resources": [{
      "name": "delivery-van",
      "capacity": [1000],  // 1000 kg
      "shifts": [{
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T18:00:00Z"
      }]
    }],
    "jobs": [
      {"name": "parcel-1", "load": [5]},
      {"name": "parcel-2", "load": [3]},
      {"name": "parcel-3", "load": [8]}
    ]
  }
  ```

  ```json Weight and Volume theme={null}
  {
    "resources": [{
      "name": "delivery-van",
      "capacity": [1000, 8],  // 1000 kg, 8 m³
      "shifts": [{
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T18:00:00Z"
      }]
    }],
    "jobs": [
      {"name": "parcel-1", "load": [5, 0.1]},
      {"name": "parcel-2", "load": [3, 0.05]},
      {"name": "parcel-3", "load": [8, 0.2]}
    ]
  }
  ```
</CodeGroup>

### 2. Waste Collection

Vehicles that fill up and need to visit disposal sites:

```json theme={null}
{
  "resources": [{
    "name": "garbage-truck",
    "capacity": [10000],  // 10 tons
    "shifts": [{
      "from": "2024-03-15T06:00:00Z",
      "to": "2024-03-15T14:00:00Z"
    }]
  }],
  "jobs": [
    // Collection points (pickups)
    {"name": "bin-1", "load": [200], "duration": 800},
    {"name": "bin-2", "load": [150], "duration": 600},
    {"name": "bin-3", "load": [300], "duration": 1200},
    // Disposal site (delivery)
    {"name": "disposal-site-bin-1", "load": [200], "duration": 1800},
    {"name": "disposal-site-bin-2", "load": [150], "duration": 1800},
    {"name": "disposal-site-bin-3", "load": [300], "duration": 1800}
  ],
  "relations": [
     {
        "type": "PICKUP_AND_DELIVERY",
        "jobs": ["bin-1", "disposal-site-bin-1"]
     },
     {
        "type": "PICKUP_AND_DELIVERY",
        "jobs": ["bin-2", "disposal-site-bin-2"]
     },
     {
        "type": "PICKUP_AND_DELIVERY",
        "jobs": ["bin-3", "disposal-site-bin-3"]
     }
  ]
}
```

### 3. Mixed Fleet Optimization

Different vehicle types with varying capacities:

```json theme={null}
{
  "resources": [
    {
      "name": "bike-courier",
      "capacity": [20, 0.5],  // 20kg, 0.5m³
      "category": "BIKE",
      "shifts": [{
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T18:00:00Z"
      }]
    },
    {
      "name": "cargo-van",
      "capacity": [1000, 8],  // 1000kg, 8m³
      "category": "CAR",
      "shifts": [{
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T18:00:00Z"
      }]
    },
    {
      "name": "truck",
      "capacity": [5000, 40],  // 5 tons, 40m³
      "category": "TRUCK",
      "shifts": [{
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T18:00:00Z"
      }]
    }
  ],
  "jobs": [
    {"name": "small-parcel", "load": [15, 0.3]},
    {"name": "large-parcel", "load": [500, 5]},
    {"name": "bulk-delivery", "load": [3000, 25]}
  ]
}
```

## Best Practices

<Tip>
  **Capacity Planning Guidelines:**

  1. **Reserve Buffer**: Keep 10-15% capacity buffer for unexpected additions
  2. **Dimension Selection**: Only use dimensions that actually constrain your operations
  3. **Load Accuracy**: Ensure load estimates include packaging and handling equipment
  4. **Mixed Units**: Keep units consistent (all kg or all lbs, not mixed)
</Tip>

### Handling Overloading

When capacity constraints make problems infeasible:

<Steps>
  <Step title="Enable Partial Planning">
    ```json theme={null}
    {
      "options": {
        "partialPlanning": true
      }
    }
    ```
  </Step>

  <Step title="Check Unassigned Jobs">
    Review the response for jobs that couldn't be assigned due to capacity:

    ```json theme={null}
    {
      "unassigned": ["heavy-delivery-5", "bulky-item-3"],
      "unassignedReasons": {
        "heavy-delivery-5": ["CAPACITY_EXCEEDED"],
        "bulky-item-3": ["NO_VEHICLE_WITH_SUFFICIENT_CAPACITY"]
      }
    }
    ```
  </Step>

  <Step title="Add Resources or Adjust Loads">
    Either add more vehicles or review if load estimates are accurate.
  </Step>
</Steps>

## Performance Considerations

<Warning>
  **Multi-dimensional capacity impact:**

  * Each additional capacity dimension increases computation complexity
  * Use 1-3 dimensions for best performance
  * More than 5 dimensions may significantly slow solving
</Warning>

### Optimization Tips

1. **Simplify When Possible**: If volume rarely constrains, use weight only
2. **Round Values**: Round loads to reasonable precision (1kg vs 1.234kg)
3. **Group Similar Items**: Combine small items into single jobs when feasible

## Capacity in Response

The solution includes capacity tracking information:

```json theme={null}
{
  "routes": [
    {
      "resource": "delivery-van",
      "jobs": [
        {
          "job": "delivery-1",
          "arrival": "2024-03-15T09:15:00Z",
          "departure": "2024-03-15T09:25:00Z",
          "load": [150],  // Current load after this job
          "cumulativeLoad": [150]  // Total load at this point
        },
        {
          "job": "delivery-2",
          "arrival": "2024-03-15T09:45:00Z",
          "departure": "2024-03-15T09:55:00Z",
          "load": [200],
          "cumulativeLoad": [350]  // 150 + 200
        }
      ],
      "summary": {
        "maxLoad": [350],  // Peak load during route
        "capacityUtilization": 0.35  // 35% of 1000kg capacity
      }
    }
  ]
}
```

## Related Features

* [Pickup and Delivery](/guides/vrp/features/relations) - Complex paired job handling
* [Vehicle Types](/guides/vrp/features/resource-management) - Different capacity per vehicle type
* [Job Relations](/guides/vrp/features/job-relations) - Capacity-aware job sequencing
