> ## 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.

# Load Compatibility

> Enforce which load types can coexist on a vehicle to support waste stream segregation and compartment restrictions

# Load Compatibility

Load compatibility lets you control which load types can coexist on a vehicle during the same trip. This is essential for waste collection (segregated waste streams), hazmat transport (incompatible materials), and any scenario where mixing certain cargo types is not allowed.

## Overview

Without load compatibility, the solver only checks that total load per dimension does not exceed capacity. With load compatibility, you define a matrix that restricts the **effective capacity** for each dimension based on what other dimensions are currently loaded.

<CardGroup cols={2}>
  <Card title="Per-Resource Configuration" icon="truck">
    Each vehicle can have its own compatibility matrix
  </Card>

  <Card title="Hard Constraint" icon="shield-halved">
    Violations are treated as hard constraints — the solver avoids them entirely
  </Card>
</CardGroup>

## Basic Configuration

Add a `loadCompatibility` matrix to any resource. The matrix dimensions must match the resource's `capacity` array.

### Mutually Exclusive Load Types

The most common use case: each trip carries only one type of cargo. Use a diagonal matrix where each dimension allows full capacity only for itself:

```json theme={null}
{
  "resources": [
    {
      "name": "waste-truck-1",
      "capacity": [8000, 8000, 8000],
      "loadCompatibility": [
        [8000, 0, 0],
        [0, 8000, 0],
        [0, 0, 8000]
      ],
      "shifts": [{
        "from": "2024-03-15T06:00:00Z",
        "to": "2024-03-15T17:00:00Z",
        "start": {"latitude": 51.054, "longitude": 3.717},
        "end": {"latitude": 51.054, "longitude": 3.717}
      }]
    }
  ],
  "jobs": [
    {
      "name": "general-waste-1",
      "location": {"latitude": 51.067, "longitude": 3.651},
      "load": [280, 0, 0],
      "duration": 360
    },
    {
      "name": "recycling-1",
      "location": {"latitude": 51.029, "longitude": 3.718},
      "load": [0, 350, 0],
      "duration": 360
    },
    {
      "name": "paper-1",
      "location": {"latitude": 51.047, "longitude": 3.652},
      "load": [0, 0, 200],
      "duration": 360
    }
  ]
}
```

With this configuration:

* If the truck picks up `general-waste-1` (load dimension 0), the effective capacity for dimensions 1 and 2 drops to **0**
* The truck cannot pick up `recycling-1` or `paper-1` on the same trip
* After visiting a [depot](/guides/vrp/features/depot-management) to unload, the truck can start a new trip with a different waste stream

## How the Matrix Works

The `loadCompatibility` matrix is an N x N matrix where N is the number of capacity dimensions.

`loadCompatibility[i][j]` defines the **effective maximum capacity for dimension j** when dimension i has non-zero load.

When multiple dimensions are active simultaneously, the effective capacity for dimension j is:

```
effectiveCapacity[j] = min(loadCompatibility[i][j]) for all active dimensions i
```

### Reading the Matrix

Consider this matrix for a 3-compartment vehicle:

```json theme={null}
"capacity": [8000, 5000, 3000],
"loadCompatibility": [
  [8000, 0,    0   ],
  [0,    5000, 0   ],
  [0,    0,    3000]
]
```

| When loaded with... | Dim 0 capacity | Dim 1 capacity | Dim 2 capacity |
| ------------------- | -------------- | -------------- | -------------- |
| Dimension 0 only    | 8000           | 0              | 0              |
| Dimension 1 only    | 0              | 5000           | 0              |
| Dimension 2 only    | 0              | 0              | 3000           |

This is a strict segregation matrix — each dimension is exclusive.

### Partially Compatible Types

Some cargo types can share a vehicle with reduced capacity:

```json theme={null}
{
  "resources": [
    {
      "name": "flexible-truck",
      "capacity": [500, 500],
      "loadCompatibility": [
        [500, 200],
        [200, 500]
      ],
      "shifts": [{
        "from": "2024-03-15T08:00:00Z",
        "to": "2024-03-15T17:00:00Z",
        "start": {"latitude": 51.058, "longitude": 3.784},
        "end": {"latitude": 51.058, "longitude": 3.784}
      }]
    }
  ],
  "jobs": [
    {
      "name": "type-a-pickup",
      "location": {"latitude": 51.043, "longitude": 3.725},
      "load": [100, 0],
      "duration": 600
    },
    {
      "name": "type-b-pickup",
      "location": {"latitude": 51.084, "longitude": 3.734},
      "load": [0, 150],
      "duration": 600
    }
  ]
}
```

With this matrix, when dimension 0 is loaded:

* Dimension 0 retains full capacity (500)
* Dimension 1 is reduced to 200

Both jobs can be served on the same trip because the type-b load (150) fits within the reduced capacity (200).

## Waste Collection Example

A complete waste collection setup with 3 segregated streams, load compatibility, and depot visits:

```json theme={null}
{
  "resources": [
    {
      "name": "collection-vehicle-1",
      "capacity": [8000, 8000, 8000],
      "loadCompatibility": [
        [8000, 0, 0],
        [0, 8000, 0],
        [0, 0, 8000]
      ],
      "tags": ["General Waste", "Dry Mixed Packaging", "Paper and cardboard"],
      "category": "TRUCK",
      "shifts": [{
        "from": "2024-03-15T06:15:00Z",
        "to": "2024-03-15T16:00:00Z",
        "start": {"latitude": 51.054, "longitude": 3.717},
        "end": {"latitude": 51.054, "longitude": 3.717},
        "breaks": [{"type": "DRIVE", "driveTime": 16200, "duration": 2700}]
      }]
    }
  ],
  "jobs": [
    {
      "name": "household-general-1",
      "location": {"latitude": 51.082, "longitude": 3.750},
      "load": [280, 0, 0],
      "duration": 360,
      "tags": [{"name": "General Waste", "hard": true}]
    },
    {
      "name": "household-recycling-1",
      "location": {"latitude": 51.068, "longitude": 3.724},
      "load": [0, 200, 0],
      "duration": 360,
      "tags": [{"name": "Dry Mixed Packaging", "hard": true}]
    },
    {
      "name": "household-paper-1",
      "location": {"latitude": 51.040, "longitude": 3.669},
      "load": [0, 0, 150],
      "duration": 360,
      "tags": [{"name": "Paper and cardboard", "hard": true}]
    }
  ],
  "depots": [
    {
      "name": "transfer-station",
      "location": {"latitude": 51.087, "longitude": 3.728},
      "duration": 900,
      "windows": [{"from": "2024-03-15T08:00:00Z", "to": "2024-03-15T17:00:00Z"}]
    }
  ]
}
```

The solver produces multi-trip routes where each trip collects a single waste stream, visits the depot to unload, and starts a new trip with a different stream.

## Constraint Behavior

Load compatibility is enforced as a **hard constraint** named `Load Compatibility`. When violated, it appears in the response's `violations` section:

```json theme={null}
{
  "score": {"hard": -1, "soft": -45000, "feasible": false},
  "violations": [
    {
      "constraint": "Load Compatibility",
      "description": "Vehicle collection-vehicle-1 carries incompatible load types"
    }
  ]
}
```

<Note>
  Load compatibility is implicitly toggleable. If you omit the `loadCompatibility` field on a resource, no compatibility restrictions apply to that vehicle. You can enable it on some vehicles and leave it off on others.
</Note>

## Best Practices

<AccordionGroup>
  <Accordion title="Match dimensions across jobs, resources, and depots">
    All `load` arrays on jobs, `capacity` arrays on resources, and `capacity` arrays on depots must have the **same number of dimensions**. Mismatched dimensions cause validation errors.
  </Accordion>

  <Accordion title="Combine with tags for stream assignment">
    Use [tags](/guides/vrp/features/tag-ranking) alongside load compatibility to ensure vehicles are assigned to the correct waste stream. Tags control *which* vehicle can serve a job; load compatibility controls *what else* can be on the vehicle at the same time.
  </Accordion>

  <Accordion title="Use depots to enable multi-trip collection">
    Load compatibility alone prevents mixing on a single trip. To collect multiple waste streams per shift, add [depots](/guides/vrp/features/depot-management) so the vehicle can unload between trips and reset its load.
  </Accordion>
</AccordionGroup>

## Related Features

<CardGroup cols={2}>
  <Card title="Disposal Site Selection" icon="industry" href="/guides/vrp/features/depot-management">
    Dynamically assign trips to optimal disposal sites
  </Card>

  <Card title="Capacity Management" icon="box" href="/guides/vrp/features/capacity-management">
    Configure multi-dimensional vehicle capacity constraints
  </Card>

  <Card title="Tags & Ranking" icon="tags" href="/guides/vrp/features/tag-ranking">
    Match jobs to vehicles using capability tags
  </Card>

  <Card title="Job Relations" icon="link" href="/guides/vrp/features/job-relations">
    Define pickup-delivery pairs and job sequencing
  </Card>
</CardGroup>
