A state-of-the-art solver for cutting and packing problems.
Online solver · Documentation · Ask a question
PackingSolver computes cutting and loading plans: given a set of pieces to cut or pack (the items) and a set of containers (the bins), it finds how to place the items in the bins. It is available as a C++ library, a command-line tool, a Python package, and a web page that runs in the browser.
| Problem type | Example |
|---|---|
Rectangles, guillotine cutsrectangleguillotineTwo-dimensional rectangles cut with edge-to-edge (guillotine) cuts |
![]() |
RectanglesrectangleTwo-dimensional rectangles |
![]() |
BoxesboxThree-dimensional boxes |
![]() |
Box stacksboxstacksThree-dimensional boxes, packed in stacks of items with the same width and length |
![]() |
One-dimensionalonedimensionalOne-dimensional items |
![]() |
Irregular shapesirregularTwo-dimensional shapes: polygons, possibly with circular arcs and holes |
![]() |
PackingSolver supports the following objectives:
- Bin packing: pack all the items in a minimum number of bins (optionally maximizing the value of the leftovers)
- Variable-sized bin packing: pack all the items in bins of minimum total cost
- Open dimension (all problem types except one-dimensional): pack all the items in a single bin of minimum length
- Knapsack: pack a subset of the items of maximum total profit
- Feasibility: pack all the items in the given bins
Each problem type comes with its own constraints:
| Problem type | Features |
|---|---|
| Rectangles, guillotine cuts | Guillotine or non-guillotine cuts · maximum number of cutting stages · cut types · first stage orientation · item rotations · cut thickness · trims · defects · cuts through defects · cutting sequences (stacks) · minimum and maximum distances between cuts · maximum number of consecutive 1-cuts and 2-cuts |
| Rectangles | Item rotations · defects · maximum weight of a bin · unloading constraints |
| Boxes | Item rotations · maximum weight of a bin |
| Box stacks | Item rotations · nesting height · maximum number of items in a stack · maximum weight above an item · maximum stack density · unloading constraints · maximum weight on the middle and rear axles |
| One-dimensional | Nesting length · maximum number of items in a bin · maximum weight of a bin · maximum weight after an item |
| Irregular shapes | Irregular bins · discrete and continuous item rotations · item mirroring · holes · defects · item-item, item-bin and item-defect spacing |
The online solver runs PackingSolver in your browser. No installation is needed, and the computation runs on your machine: nothing is sent to a server.
Install the Python package from PyPI (Python ≥ 3.12):
pip install packingsolverExample (rectangles, guillotine cuts):
import packingsolver.rectangleguillotine as psg
instance_builder = psg.InstanceBuilder()
instance_builder.set_objective(psg.Objective.BinPackingWithLeftovers)
instance_builder.add_bin_type(1000, 700, copies=5)
instance_builder.add_item_type(250, 200, copies=2)
instance_builder.add_item_type(150, 300, copies=2)
instance_builder.add_item_type(200, 150, copies=3)
instance = instance_builder.build()
parameters = psg.OptimizeParameters()
parameters.time_limit = 5
output = psg.optimize(instance, parameters)
psg.visualize(output.solution).show()Rectangles
import packingsolver.rectangle as psr
instance_builder = psr.InstanceBuilder()
instance_builder.set_objective(psr.Objective.BinPackingWithLeftovers)
instance_builder.add_bin_type(1000, 500, copies=10)
instance_builder.add_item_type(300, 200, copies=10)
instance_builder.add_item_type(250, 150, copies=10)
instance = instance_builder.build()
parameters = psr.OptimizeParameters()
parameters.time_limit = 5
output = psr.optimize(instance, parameters)
psr.visualize(output.solution).show()
Boxes
import packingsolver.box as psb
instance_builder = psb.InstanceBuilder()
instance_builder.set_objective(psb.Objective.Knapsack)
instance_builder.add_bin_type(216, 173, 110)
instance_builder.add_item_type(108, 76, 30, copies=20)
instance_builder.add_item_type(110, 43, 25, copies=20)
instance_builder.add_item_type(92, 81, 55, copies=20)
instance = instance_builder.build()
parameters = psb.OptimizeParameters()
parameters.time_limit = 5
output = psb.optimize(instance, parameters)
psb.visualize(output.solution).show()
Box stacks
import packingsolver.boxstacks as psbs
instance_builder = psbs.InstanceBuilder()
instance_builder.set_objective(psbs.Objective.Knapsack)
instance_builder.add_bin_type(7500, 2400, 3000)
instance_builder.add_item_type(2500, 800, 750, stackability_id=0, copies=10)
instance_builder.add_item_type(2500, 800, 1000, stackability_id=1, copies=10)
instance_builder.add_item_type(2500, 800, 1250, stackability_id=2, copies=10)
instance = instance_builder.build()
parameters = psbs.OptimizeParameters()
parameters.time_limit = 5
output = psbs.optimize(instance, parameters)
psbs.visualize(output.solution).show()
One-dimensional
import packingsolver.onedimensional as pso
instance_builder = pso.InstanceBuilder()
instance_builder.set_objective(pso.Objective.BinPacking)
instance_builder.add_bin_type(1000, copies=100)
for length in [
193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347,
349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,
431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499]:
instance_builder.add_item_type(length)
instance = instance_builder.build()
parameters = pso.OptimizeParameters()
parameters.time_limit = 5
output = pso.optimize(instance, parameters)
pso.visualize(output.solution).show()
Irregular shapes
import packingsolver.irregular as psi
bar = [(0, 0), (80, 0), (80, 20), (0, 20)]
square = [(0, 0), (40, 0), (40, 40), (0, 40)]
t_shape = [(0, 0), (60, 0), (60, 20), (40, 20), (40, 40), (20, 40), (20, 20), (0, 20)]
s_shape = [(20, 0), (60, 0), (60, 20), (40, 20), (40, 40), (0, 40), (0, 20), (20, 20)]
z_shape = [(0, 0), (40, 0), (40, 20), (60, 20), (60, 40), (20, 40), (20, 20), (0, 20)]
l_shape = [(0, 0), (40, 0), (40, 20), (20, 20), (20, 60), (0, 60)]
j_shape = [(0, 0), (40, 0), (40, 60), (20, 60), (20, 20), (0, 20)]
cross = [
(20, 0), (40, 0), (40, 20), (60, 20), (60, 40), (40, 40),
(40, 60), (20, 60), (20, 40), (0, 40), (0, 20), (20, 20)]
rotations = [(0, 0, False), (90, 90, False), (180, 180, False), (270, 270, False)]
instance_builder = psi.InstanceBuilder()
instance_builder.set_objective(psi.Objective.BinPacking)
instance_builder.add_bin_type(psi.build_rectangle(0, 180, 0, 160), copies=3)
instance_builder.add_item_type(psi.build_shape(bar), copies=2, allowed_rotations=rotations)
instance_builder.add_item_type(psi.build_shape(square), copies=2)
instance_builder.add_item_type(psi.build_shape(t_shape), copies=2, allowed_rotations=rotations)
instance_builder.add_item_type(psi.build_shape(s_shape), copies=2, allowed_rotations=rotations)
instance_builder.add_item_type(psi.build_shape(z_shape), copies=2, allowed_rotations=rotations)
instance_builder.add_item_type(psi.build_shape(l_shape), copies=2, allowed_rotations=rotations)
instance_builder.add_item_type(psi.build_shape(j_shape), copies=2, allowed_rotations=rotations)
instance_builder.add_item_type(psi.build_shape(cross), copies=3)
instance = instance_builder.build()
parameters = psi.OptimizeParameters()
parameters.time_limit = 5
output = psi.optimize(instance, parameters)
psi.visualize(output.solution).show()
Build the command-line tools with CMake:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release --parallel
cmake --install build --config Release --prefix installExample (rectangles, guillotine cuts):
./install/bin/packingsolver_rectangleguillotine \
--verbosity-level 1 \
--items data/rectangle/alvarez2002/ATP35_items.csv \
--bins data/rectangle/alvarez2002/ATP35_bins.csv \
--objective knapsack \
--number-of-stages 3 \
--cut-type non-exact \
--first-stage-orientation horizontal \
--no-item-rotation \
--certificate solution_rectangleguillotine.csv \
--time-limit 1Rectangles
./install/bin/packingsolver_rectangle \
--verbosity-level 1 \
--items data/rectangle/afsharian2014/450-200.txt/C22M25R10N15_D4_items.csv \
--bins data/rectangle/afsharian2014/450-200.txt/C22M25R10N15_D4_bins.csv \
--defects data/rectangle/afsharian2014/450-200.txt/C22M25R10N15_D4_defects.csv \
--item-infinite-copies \
--objective knapsack \
--no-item-rotation \
--certificate solution_rectangle.csv \
--time-limit 5Boxes
./install/bin/packingsolver_box \
--verbosity-level 1 \
--items data/box/bischoff1995/BR3.txt_1 \
--objective knapsack \
--certificate solution_box.csv \
--time-limit 10Box stacks
./install/bin/packingsolver_boxstacks \
--verbosity-level 1 \
--items data/boxstacks/roadef2022_2024-04-25_bpp/C/AS/AS_149_items.csv \
--bins data/boxstacks/roadef2022_2024-04-25_bpp/C/AS/AS_149_bins.csv \
--parameters data/boxstacks/roadef2022_2024-04-25_bpp/C/AS/AS_149_parameters.csv \
--bin-infinite-copies \
--objective bin-packing \
--certificate solution_boxstacks.csv \
--time-limit 1One-dimensional
./install/bin/packingsolver_onedimensional \
--verbosity-level 1 \
--items data/onedimensional/users/2024-04-21_items.csv \
--bins data/onedimensional/users/2024-04-21_bins.csv \
--parameters data/onedimensional/users/2024-04-21_parameters.csv \
--certificate solution_onedimensional.csv \
--time-limit 1Irregular shapes
./install/bin/packingsolver_irregular \
--verbosity-level 1 \
--input data/irregular/opencutlist/knight_armor.json \
--certificate solution_irregular.json \
--time-limit 10The input formats and the options of each solver are described in the documentation.
Open a solution certificate (--certificate) in the solution viewer, or run:
python3 scripts/visualize.py solution_rectangleguillotine.csvQuestions and feedback are welcome in the discussions. Bugs can be reported in the issues.
PackingSolver is released under the MIT license.






