Bin Packing Problem (BPP) Example
The Bin Packing Problem (BPP) asks to pack a set of items with given weights into the minimum number of fixed-capacity bins. It is NP-hard.
import getpass
import os
import matplotlib.pyplot as plt
import numpy as np
from dotenv import load_dotenv
from luna_quantum.algorithms import SCIP
from luna_usecases.bin_packing_problem import (
BppCollection,
BppData,
BppFormulation,
BppInstance,
)
load_dotenv()
if "LUNA_API_KEY" not in os.environ:
# Prompt securely for the key if not already set
os.environ["LUNA_API_KEY"] = getpass.getpass("Enter your Luna API key: ")
Create Data
Define the problem data.
# Define item weights and bin capacity
item_weights = np.array([4.5, 2.3, 6.1, 3.8, 5.2, 1.9, 4.0, 2.7])
bin_capacity = 10.0
item_names = ["A", "B", "C", "D", "E", "F", "G", "H"]
bpp_data = BppData.from_weights(
item_weights=item_weights,
bin_capacity=bin_capacity,
item_names=item_names,
)
print(bpp_data.to_string())
Bin Packing Data:
Items: 8
Item names: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
Item weights: [4.5 2.3 6.1 3.8 5.2 1.9 4. 2.7]
Bin capacity: 10.0
Max bins: 8
Alternative: Generate Random Data
You can also generate random problem instances:
# Generate a random BPP instance with 6 items
random_data = BppData.generate_random(
n_items=6,
bin_capacity=10.0,
seed=42,
)
print(random_data.to_string())
Bin Packing Data:
Items: 6
Item names: ['0', '1', '2', '3', '4', '5']
Item weights: [7.8 4.4 8.6 7. 1. 9.8]
Bin capacity: 10.0
Max bins: 6
Plot Data
Visualize the item weights relative to bin capacity.

Create Formulation
Define the optimization formulation.
Bin Packing Problem Formulation:
Items: 8
Max bins: 8
Bin capacity: 10.0
Decision Variables:
x[i,j] in {0,1} for i = 0, ..., 7, j = 0, ..., 7
x[i,j] = 1 if item i is packed in bin j
y[j] in {0,1} for j = 0, ..., 7
y[j] = 1 if bin j is used
Total: 72 binary variables
Objective:
minimize sum_j y[j] for j = 0, ..., 7
Constraints:
1. Each item in exactly one bin (8 constraints):
sum_j x[i,j] == 1 for all i = 0, ..., 7
2. Bin capacity not exceeded (8 constraints):
sum_i w[i] * x[i,j] <= 10.0 * y[j] for all j = 0, ..., 7
Create Instance
Combine data and formulation into an instance.
Data:Bin Packing Data:
Items: 8
Item names: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
Item weights: [4.5 2.3 6.1 3.8 5.2 1.9 4. 2.7]
Bin capacity: 10.0
Max bins: 8
Formulation:Bin Packing Problem Formulation:
Items: 8
Max bins: 8
Bin capacity: 10.0
Decision Variables:
x[i,j] in {0,1} for i = 0, ..., 7, j = 0, ..., 7
x[i,j] = 1 if item i is packed in bin j
y[j] in {0,1} for j = 0, ..., 7
y[j] = 1 if bin j is used
Total: 72 binary variables
Objective:
minimize sum_j y[j] for j = 0, ..., 7
Constraints:
1. Each item in exactly one bin (8 constraints):
sum_j x[i,j] == 1 for all i = 0, ..., 7
2. Bin capacity not exceeded (8 constraints):
sum_i w[i] * x[i,j] <= 10.0 * y[j] for all j = 0, ..., 7
Formulate Model
Create the optimization model.
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:28 INFO Sleeping for 5.0 seconds. Waiting and checking a function in a loop.
2026-05-29 11:33:35 INFO Sleeping for 10.0 seconds. Waiting and checking a function in a loop.
2026-05-29 11:33:46 INFO Sleeping for 15.0 seconds. Waiting and checking a function in a loop.
Bin Packing Solution:
Bins used: 4
Valid: True
Bin assignments: [['A', 'B', 'F'], ['C', 'D'], ['E', 'G'], ['H']]
Bin loads: [8.7, 9.899999999999999, 9.2, 2.7]
Plot Solution
Visualize the optimal solution.

Collections
Generate a benchmark collection of random instances for batch processing.
collection = BppCollection.from_random(
min_num_items=5,
max_num_items=8,
bin_capacity=10.0,
num_instances=2,
seed=42,
)
model = collection.instances[0].formulate()
print(model)
Model: bin_packing_problem<bin_packing_problem>
Minimize
y_0 + y_1 + y_2 + y_3 + y_4
Subject To
item_one_bin_0: 6 * x_0_0 + 6 * x_0_1 + 6 * x_0_2 + 6 * x_0_3 + 6 * x_0_4 == 6
item_one_bin_1: 6 * x_1_0 + 6 * x_1_1 + 6 * x_1_2 + 6 * x_1_3 + 6 * x_1_4 == 6
item_one_bin_2: 6 * x_2_0 + 6 * x_2_1 + 6 * x_2_2 + 6 * x_2_3 + 6 * x_2_4 == 6
item_one_bin_3: 6 * x_3_0 + 6 * x_3_1 + 6 * x_3_2 + 6 * x_3_3 + 6 * x_3_4 == 6
item_one_bin_4: 6 * x_4_0 + 6 * x_4_1 + 6 * x_4_2 + 6 * x_4_3 + 6 * x_4_4 == 6
capacity_0: 13.200000000000001 * x_0_0 + 19.200000000000003 * x_1_0
+ 9 * x_2_0 + 46.2 * x_3_0 + 36.599999999999994 * x_4_0 - 60 * y_0 <= 0
capacity_1: 13.200000000000001 * x_0_1 + 19.200000000000003 * x_1_1
+ 9 * x_2_1 + 46.2 * x_3_1 + 36.599999999999994 * x_4_1 - 60 * y_1 <= 0
capacity_2: 13.200000000000001 * x_0_2 + 19.200000000000003 * x_1_2
+ 9 * x_2_2 + 46.2 * x_3_2 + 36.599999999999994 * x_4_2 - 60 * y_2 <= 0
capacity_3: 13.200000000000001 * x_0_3 + 19.200000000000003 * x_1_3
+ 9 * x_2_3 + 46.2 * x_3_3 + 36.599999999999994 * x_4_3 - 60 * y_3 <= 0
capacity_4: 13.200000000000001 * x_0_4 + 19.200000000000003 * x_1_4
+ 9 * x_2_4 + 46.2 * x_3_4 + 36.599999999999994 * x_4_4 - 60 * y_4 <= 0
Binary
x_0_0 x_0_1 x_0_2 x_0_3 x_0_4 x_1_0 x_1_1 x_1_2 x_1_3 x_1_4 x_2_0 x_2_1 x_2_2
x_2_3 x_2_4 x_3_0 x_3_1 x_3_2 x_3_3 x_3_4 x_4_0 x_4_1 x_4_2 x_4_3 x_4_4 y_0
y_1 y_2 y_3 y_4