Skip to content

Container Assignment Example

Download Notebook


The Container Assignment Problem decides whether each container should be transported by barge or by truck, minimizing total cost while respecting track capacity constraints for barge shipments.

import getpass
import os

from dotenv import load_dotenv
from luna_quantum.algorithms import SCIP

from luna_usecases.container_assignment import (
    Container,
    ContainerAssignmentCollection,
    ContainerAssignmentData,
    ContainerAssignmentFormulation,
    ContainerAssignmentInstance,
)

load_dotenv()
if "LUNA_API_KEY" not in os.environ:
    os.environ["LUNA_API_KEY"] = getpass.getpass("Enter your Luna API key: ")

Create Data

Define 4 containers with barge/truck costs and 3 tracks with capacity limits.

containers = [
    Container(name="Con_0", barge_cost=2.0, truck_cost=5.0, routes=[1, 1, 0]),
    Container(name="Con_1", barge_cost=3.0, truck_cost=6.0, routes=[0, 1, 1]),
    Container(name="Con_2", barge_cost=1.5, truck_cost=4.5, routes=[1, 0, 1]),
    Container(name="Con_3", barge_cost=4.0, truck_cost=7.0, routes=[1, 1, 1]),
]

data = ContainerAssignmentData.from_containers(
    containers,
    track_capacities={"track_0": 2, "track_1": 2, "track_2": 1},
)
print(data.to_string())
Container Assignment Data:
  Containers: 4
  Tracks: 3
  Track capacities: {'track_0': 2, 'track_1': 2, 'track_2': 1}

Plot Data

Visualize container costs and track capacities.

data.plot()

<Axes: title={'center': 'Costs per Container'}, ylabel='Cost'>
png

Create Formulation

Minimize total transport cost while respecting track capacity limits.

formulation = ContainerAssignmentFormulation()
print(formulation.to_string(data))
Container Assignment Formulation:
  Containers: 4
  Tracks: 3

Indices:
  i = container index (i = 0, ..., 3)
  j = track index (j = 0, ..., 2)

Decision Variables:
  x[i] in {0,1} for i = 0, ..., 3
  x[i] = 1 if container i is transported by truck, 0 for barge
  Total: 4 binary variables

Objective:
  minimize sum_i (truck_costs[i] - barge_costs[i]) * x[i] + const

Constraints:
  1. Track capacity constraints (3 constraints):
     sum_i routes[i,j] * (1 - x[i]) <= capacity[j]  for all j = 0, ..., 2

Create Instance

Combine data and formulation into a solvable instance.

instance = ContainerAssignmentInstance(data=data, formulation=formulation)
print(instance.to_string())
Data:Container Assignment Data:
  Containers: 4
  Tracks: 3
  Track capacities: {'track_0': 2, 'track_1': 2, 'track_2': 1}
Formulation:Container Assignment Formulation:
  Containers: 4
  Tracks: 3

Indices:
  i = container index (i = 0, ..., 3)
  j = track index (j = 0, ..., 2)

Decision Variables:
  x[i] in {0,1} for i = 0, ..., 3
  x[i] = 1 if container i is transported by truck, 0 for barge
  Total: 4 binary variables

Objective:
  minimize sum_i (truck_costs[i] - barge_costs[i]) * x[i] + const

Constraints:
  1. Track capacity constraints (3 constraints):
     sum_i routes[i,j] * (1 - x[i]) <= capacity[j]  for all j = 0, ..., 2

Formulate Model

Translate the instance into a mathematical optimization model.

model = instance.formulate()

Solve and Interpret

Solve the model with SCIP and interpret the raw result into a use-case-specific solution.

scip = SCIP()
job = scip.run(model)
sol = job.result()
uc_solution = instance.interpret(sol)
print(uc_solution.to_string())
/Users/maximilianjanetschek/PycharmProjects/luna-usecases/.venv/lib/python3.13/site-packages/rich/live.py:260:
UserWarning: install "ipywidgets" for Jupyter support
  warnings.warn('install "ipywidgets" for Jupyter support')






2026-05-29 11:33:34 INFO     Sleeping for 5.0 seconds. Waiting and checking a function in a loop.


2026-05-29 11:33:41 INFO     Sleeping for 10.0 seconds. Waiting and checking a function in a loop.


2026-05-29 11:33:52 INFO     Sleeping for 15.0 seconds. Waiting and checking a function in a loop.


2026-05-29 11:34:08 INFO     Sleeping for 20.0 seconds. Waiting and checking a function in a loop.




Container Assignment Solution:
  Total cost: 16.50
  Valid: True
  Truck containers: [2 3]
  Barge containers: [0 1]

Plot Solution

Visualize the optimal solution.

uc_solution.plot(data)

<Axes: title={'center': 'Cost Breakdown'}, ylabel='Cost'>
png

Collections

Generate a benchmark collection of random instances for batch processing.

collection = ContainerAssignmentCollection.from_random(
    min_containers=4,
    max_containers=6,
    n_tracks=3,
    seed=42,
)
model = collection.instances[0].formulate()
print(model)
Model: container_assignment<container_assignment>
Minimize
  22.096269849051172 * x_0 + 6.9621730040367655 * x_1 + 8.02180735429602 * x_2
  + 21.60627953079882 * x_3
Subject To
  track_cap_track_0: -x_0 - x_2 - x_3 <= -1
  track_cap_track_1:  <= 2
  track_cap_track_2:  <= 2
Binary
  x_0 x_1 x_2 x_3