First fit heuristic algorithm for 4D bin packing problem solver (4dbpp). An implementation of the "4D" bin packing problem i.e. given a list of items, how many boxes do you need to fit them all in taking into account physical dimensions and weights.
This project is a complete rewrite of box_packer
It also provide 2 additional "real life" features:
- Coerce items that can't be stacked.
- Coerce items that are not invertible.
...Especially if you need to pack (big) fragile items.
Add this line to your application's Gemfile:
gem 'tetromino'
And then execute:
$ bundle
Or install it yourself as:
$ gem install tetromino
tetromino = Tetromino.packer(dimensions: [40, 30, 20]) # Define the size of your box
tetromino.add_item!(dimensions: [40, 30, 10]) # Fill it up with item
tetromino.add_item!(dimensions: [10, 40, 30]) # ...Moarrr item!
tetromino.pack! # Pack your stuff
tetromino.packed_successfully? # => true
Dimensions should always be declared in the following order:
[depth, width, height]
You can also get the results of the algorithm.
results = tetromino.results
=> [#<struct Tetromino::Packing
placements=
[
#<struct Tetromino::Placement
dimensions=[40, 30, 10],
position=[0, 0, 0],
weight=0>,
#<struct Tetromino::Placement
dimensions=[40, 30, 10],
position=[0, 0, 10],
weight=0>
],
weight=0.0,
spaces=
[
#<struct Tetromino::Space
dimensions=[0, 30, 20],
position=[40, 0, 0]>,
#<struct Tetromino::Space
dimensions=[40, 0, 20],
position=[0, 30, 0]>,
#<struct Tetromino::Space
dimensions=[0, 30, 10],
position=[40, 0, 10]>,
#<struct Tetromino::Space
dimensions=[40, 0, 10],
position=[0, 30, 10]>,
#<struct Tetromino::Space
dimensions=[40, 30, 0],
position=[0, 0, 20]>
]>
]
Placements represent how your items have been organized into your box(es) (dimensions & positions).
results.placements
These are the empty spaces remaining in your box(es).
results.spaces
This is the total weight of the packed items.
results.weight
You can define a weight limit constraint on your box(es).
begin
tetromino = Tetromino.packer(dimensions: [40, 30, 20], max_weight: 4)
tetromino.add_item!(dimensions: [40, 15, 20], weight: 2)
tetromino.add_item!(dimensions: [40, 15, 20], weight: 3)
tetromino.pack!
tetromino.packed_successfully? # => false
rescue Tetromino::Exceptions::Error => error
puts error.message # => Maximum boxes quantity exceeded
end
You can try to pack your items in multiple boxes.
tetromino = Tetromino.packer(dimensions: [40, 30, 20], boxes_limit: 2)
tetromino.add_item!(dimensions: [40, 30, 20])
tetromino.add_item!(dimensions: [30, 20, 40])
tetromino.pack!
tetromino.packed_successfully? # => true
You can define if your items can't be stacked.
begin
tetromino = Tetromino.packer(dimensions: [40, 30, 20])
tetromino.add_item!(dimensions: [40, 30, 10], stackable: false)
tetromino.add_item!(dimensions: [40, 30, 10], stackable: false)
tetromino.pack!
tetromino.packed_successfully? # => false
rescue Tetromino::Exceptions::Error => error
puts error.message # => Maximum boxes quantity exceeded
end
You can define if your items can't be leaned. (impossible to permute height with depth or width)
begin
tetromino = Tetromino.packer(dimensions: [40, 30, 20])
tetromino.add_item!(dimensions: [40, 30, 10], invertible: false)
tetromino.add_item!(dimensions: [40, 10, 30], invertible: false)
tetromino.pack!
tetromino.packed_successfully? # => false
rescue Tetromino::Exceptions::Error => error
puts error.message # => Maximum boxes quantity exceeded
end
You can combine all the parameters at once:
tetromino = Tetromino.packer(dimensions: [40, 30, 20], boxes_limit: 2, max_weight: 5)
tetromino.add_item!(dimensions: [40, 30, 10], invertible: false, stackable: false, weight: 2)
tetromino.add_item!(dimensions: [30, 40, 10], invertible: false, stackable: false, weight: 3)
tetromino.pack!
tetromino.packed_successfully? # => true
Tetromino will always raise an error if it is unable to pack your items with the given constraints.
Bug reports and pull requests are welcome on GitHub at https://github.com/deliver-ee/tetromino.
The gem is available as open source under the terms of the MIT License.