box-packing
algorithms
optimization
computational-geometry
programming

How can I programmatically determine how to fit smaller boxes into a larger package?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

This problem is usually a form of bin packing or container loading. The hard part is that there are several versions of it: identical boxes, mixed box sizes, rotations allowed or disallowed, and either finding any feasible layout or the best possible one.

Start By Defining The Real Constraints

Before choosing an algorithm, write down the exact rules. The answer changes a lot depending on details that are often left implicit.

Useful questions are:

  • Are all small boxes identical or are there many sizes?
  • Can a box be rotated?
  • Must every box stay axis-aligned?
  • Do you want the maximum count, the best volume usage, or an exact placement list?
  • Are weight limits or stacking rules involved?

If you only have one small box size and axis-aligned rotations are allowed, the problem is much simpler than general 3D packing.

Simple Case: Identical Boxes With Rotation

For one box type, a strong baseline is to try all six axis-aligned orientations, compute how many boxes fit along each dimension, and keep the best result.

python
1from itertools import permutations
2
3
4def best_identical_box_fit(container, box):
5    best = None
6    seen = set()
7
8    for oriented in permutations(box):
9        if oriented in seen:
10            continue
11        seen.add(oriented)
12
13        counts = tuple(container[i] // oriented[i] for i in range(3))
14        total = counts[0] * counts[1] * counts[2]
15
16        candidate = {
17            "orientation": oriented,
18            "counts": counts,
19            "total": total,
20        }
21
22        if best is None or total > best["total"]:
23            best = candidate
24
25    return best
26
27
28container = (100, 80, 60)
29box = (30, 20, 10)
30print(best_identical_box_fit(container, box))

This is runnable and often sufficient for warehouse-style questions where every item is the same carton. It does not try fancy interlocking patterns, but it is easy to reason about and very fast.

Producing Placement Coordinates

A count alone is not always enough. Sometimes you need the actual coordinates for each box. Once you know the best orientation and the number of boxes along each axis, generate positions with nested loops.

python
1def generate_positions(container, box):
2    result = best_identical_box_fit(container, box)
3    ox, oy, oz = result["orientation"]
4    nx, ny, nz = result["counts"]
5
6    positions = []
7    for ix in range(nx):
8        for iy in range(ny):
9            for iz in range(nz):
10                positions.append((ix * ox, iy * oy, iz * oz))
11    return result, positions
12
13
14result, positions = generate_positions((100, 80, 60), (30, 20, 10))
15print(result)
16print(positions[:5])

Each tuple is the lower corner of a box. That is enough to visualize the layout or export it into another system.

When there are several box types, the problem becomes harder quickly. The number of possible arrangements grows too fast for brute force in most real inputs.

Common practical approaches are:

  • greedy placement, such as placing the largest remaining box first
  • best-fit heuristics that pick the box leaving the least wasted space
  • branch and bound for smaller exact problems
  • integer programming or constraint solving when the instance size is moderate and optimality matters

A minimal greedy sketch in Python might sort boxes by descending volume and place each one into the first free space that can hold it. That is not guaranteed to be optimal, but it is often good enough for operational tooling.

python
1def volume(box):
2    return box[0] * box[1] * box[2]
3
4
5boxes = [(30, 20, 10), (25, 25, 20), (40, 10, 10)]
6boxes = sorted(boxes, key=volume, reverse=True)
7print(boxes)

The hard part is not sorting the boxes. It is maintaining a good representation of the remaining free spaces after each placement.

Representing Free Space

A common model is to store a list of empty rectangular spaces. Initially there is one space: the whole container. When you place a box into one space, remove that space and split the leftover region into smaller rectangular spaces.

This approach is manageable, but it creates two engineering challenges:

  • merging overlapping or redundant free spaces
  • avoiding fragmentation, where a lot of small unusable spaces appear

That is why many production systems use mature solvers or specialized libraries instead of implementing 3D packing from scratch.

When Exact Optimality Matters

If the package is small and the shipment value is high, you may want an exact method. In that case, describe packing as a search problem with constraints:

  • each box is either placed or not placed
  • chosen boxes cannot overlap
  • every chosen box must stay inside the container
  • optional orientations must be one of the allowed rotations

Constraint programming, mixed-integer programming, or a dedicated packing solver can handle this better than ad hoc code. The runtime cost is higher, but the result is defensible.

Common Pitfalls

The biggest mistake is assuming that comparing total volumes is enough. A set of boxes can have less total volume than the container and still be impossible to place because of shape and orientation.

Another common error is forgetting rotation rules. If a real item must remain upright, allowing all six orientations will produce a mathematically valid layout that is physically wrong.

Developers also underestimate free-space bookkeeping. A greedy algorithm can look correct on simple inputs and then fail badly once placements carve the container into awkward leftovers.

Finally, do not ask an exact solver for global optimality on large instances unless you know the runtime budget. A heuristic with clear behavior is often the better engineering choice.

Summary

  • This is usually a bin packing or container loading problem.
  • For one box size, testing all axis-aligned orientations is a simple and effective baseline.
  • If you need placements, generate coordinates after choosing the best orientation.
  • Mixed box sizes usually require heuristics, search, or optimization tools.
  • Volume alone does not determine fit; geometry and orientation matter.

Course illustration
Course illustration

All Rights Reserved.