v0.0.1
First release of packingsolver3d: Pythonic, in-process bindings for the two three-dimensional solvers of PackingSolver, box and boxstacks. The upstream C++ (commit a7e53303) is compiled together with a pybind11 bridge into one extension module; nothing runs in a subprocess and no C++ object ever reaches Python.
What it does
packingsolver3d.box-- 3D bin packing, knapsack, variable-sized bin packing and open-dimension objectives over rectangular boxes: several bin types with copies and costs, item types with copies, profits, weights and any subset of the six rotations, bin weight capacity, and every upstream algorithm switch (tree search, sequential single knapsack, sequential value correction, column generation, dichotomic search, dual feasible functions).packingsolver3d.boxstacks-- the truck-loading engine on top of the same model: stacks with stackability ids, nesting height, maximum stackability, maximum weight above, stack density, semi-trailer truck axle limits, floor defects and unloading constraints.- Value in, value out -- frozen dataclasses (
Instance,BinType,ItemType, ...) go in, aResultwithstatus,value,bound, bins, stacks and placements comes out;Result.runrecords the exact upstream options, upstream's log and the wall time. - Honest statuses --
OPTIMALonly when the achieved value meets a bound upstream reported for that objective; a good-looking heuristic packing staysFEASIBLE. - Guarded inputs -- instances that the chosen solver would silently misread are refused with typed errors (
UnsupportedFeatureError,StackSemanticsError,InvalidInstanceError) instead of being solved as a different problem. - Budgets --
time_limitandmemory_limitgo to upstream's own timer and memory check; anytime and deterministic optimisation modes are exposed. - Visualisation --
packingsolver3d.visual.plot_resultdraws any result as an interactive plotly figure (optionalplotextra). - Concurrency -- the GIL is released while upstream runs and its log is collected through a per-call stream, so several threads may solve at once.
Benchmarks
The documentation carries a reproducible capability study on three public instance families (Egeblad-Pisinger 3D knapsack, Martello-Pisinger-Vigo class 9, Ivancic-Mathur-Mohanty THPACK9; 97 cases) next to py3dbp, jerry800416/3D-bin-packing, gedex/bp3d, the five U-Nesting strategies and two exact reference codes, with every solution re-validated by an independent geometry checker: https://packingsolver3d.readthedocs.io/en/latest/benchmarks/index.html
Wheels
CPython 3.7--3.14 on Linux x86_64 and Windows AMD64, 3.8--3.14 on Linux aarch64 and macOS (x86_64 and arm64, 11.0+), 3.11--3.14 on Windows ARM64; an sdist for everything else (needs a C++17 compiler, git, network access and CMake 3.28+, which pip installs where a cmake wheel exists). The sdist is installed from source in clean Debian, Alpine and Ubuntu containers on every CI run.
Known upstream behaviours
Documented, not papered over -- see https://packingsolver3d.readthedocs.io/en/latest/explanations/upstream_behaviours/index.html: the LP backend is always HiGHS; copies_min defaults to "all copies"; boxstacks groups stacks by (group_id, stackability_id) without checking footprints and keeps items upright; boxstacks accepts floor defects but places stacks over them at the pinned commit; limits are upstream's own checks and the solver runs in-process; unset profit and cost default to geometry; the default objective produces no solution and is refused; anytime runs are not reproducible run to run.
Install
pip install packingsolver3d # solver only
pip install "packingsolver3d[plot]" # with plotly for the figuresDocumentation: https://packingsolver3d.readthedocs.io/en/latest/ -- Unofficial distribution, not endorsed by the PackingSolver author; upstream is MIT licensed, see NOTICE.md.