-
-
Notifications
You must be signed in to change notification settings - Fork 157
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
33 changed files
with
5,497 additions
and
10,998 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,26 @@ | ||
checks: | ||
php: true | ||
php: true | ||
|
||
tools: | ||
external_code_coverage: | ||
timeout: 3600 # Timeout in seconds. | ||
filter: | ||
excluded_paths: | ||
- 'features/' | ||
- 'tests/' | ||
|
||
build: | ||
environment: | ||
# Languages | ||
php: | ||
version: "7.1" | ||
|
||
tests: | ||
override: | ||
- | ||
command: 'vendor/bin/phpunit --coverage-clover=build/phpunit.clover --exclude-group efficiency' | ||
coverage: | ||
file: 'build/phpunit.clover' | ||
format: 'clover' | ||
- | ||
command: 'vendor/bin/behat' | ||
coverage: | ||
file: 'build/behat.clover' | ||
format: 'clover' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
default: | ||
extensions: | ||
LeanPHP\Behat\CodeCoverage\Extension: | ||
auth: ~ | ||
drivers: | ||
- local | ||
filter: | ||
forceCoversAnnotation: false | ||
mapTestClassNameToCoveredClassName: false | ||
whitelist: | ||
addUncoveredFilesFromWhitelist: true | ||
processUncoveredFilesFromWhitelist: true | ||
include: | ||
directories: | ||
'src': | ||
prefix: '' | ||
report: | ||
format: clover | ||
options: | ||
target: build/behat.clover |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
Weight distribution | ||
=================== | ||
|
||
If you are shipping a large number of items to a single customer as many businesses do, it might be that more than one box is | ||
required to accommodate all of the items. A common scenario which you'll have probably encountered when receiving your own | ||
deliveries is that the first box(es) will be absolutely full as the warehouse operative will have tried to fit in as much as | ||
possible. The last box by comparison will be virtually empty and mostly filled with protective inner packing. | ||
|
||
There's nothing intrinsically wrong with this, but it can be a bit annoying for e.g. couriers and customers to receive e.g. | ||
a 20kg box which requires heavy lifting alongside a similarly sized box that weighs hardly anything at all. If you have to send | ||
two boxes anyway, it would be much better in such a situation to have e.g. an 11kg box and a 10kg box instead. | ||
|
||
Happily, this smoothing out of weight is handled automatically for you by BoxPacker - once the initial dimension-only packing | ||
is completed, a second pass is made that reallocates items from heavier boxes into any lighter ones that have space. | ||
|
||
For most use-cases the benefits are worth the extra computation time - however if a single "packing" for your scenarios | ||
involves a very large number of permutations e.g. thousands of items, you may wish to tune this behaviour. | ||
|
||
By default, the weight distribution pass is made whenever the items fit into 12 boxes or less. To reduce (or increase) the | ||
threshold, call ``setMaxBoxesToBalanceWeight()`` | ||
|
||
.. code-block:: php | ||
<?php | ||
use DVDoug\BoxPacker\Packer; | ||
$packer = new Packer(); | ||
$packer->setMaxBoxesToBalanceWeight(3); | ||
.. note:: | ||
|
||
A threshold value of either 0 or 1 will disable the weight distribution pass completely |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
What's new / Upgrading | ||
====================== | ||
|
||
.. note:: | ||
|
||
A full changelog, including changes in versions not yet | ||
released is available from https://github.com/dvdoug/BoxPacker/blob/master/CHANGELOG.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
Feature: BoxPacker | ||
In order to make logistics easier | ||
As a developer | ||
I need to be able to find out how a set of items can fit into a set of boxes | ||
|
||
Scenario: Fitting small items into a small box only | ||
Given there is a box "Small", which has external dimensions 300mm w × 300mm l × 10mm d × 10g and internal dimensions 296mm w × 296mm l × 8mm d and has a max weight of 1000g | ||
And there is a box "Large", which has external dimensions 3000mm w × 3000mm l × 100mm d × 100g and internal dimensions 2960mm w × 2960mm l × 80mm d and has a max weight of 10000g | ||
When I add 3 x keep flat "Small Item" with dimensions 250mm w × 250mm l × 2mm d × 200g | ||
And I do a packing | ||
Then I should have 1 boxes of type "Small" | ||
And I should have 0 boxes of type "Large" | ||
|
||
Scenario: Fitting large items into a large box only | ||
Given there is a box "Small", which has external dimensions 300mm w × 300mm l × 10mm d × 10g and internal dimensions 296mm w × 296mm l × 8mm d and has a max weight of 1000g | ||
And there is a box "Large", which has external dimensions 3000mm w × 3000mm l × 100mm d × 100g and internal dimensions 2960mm w × 2960mm l × 80mm d and has a max weight of 10000g | ||
When I add 3 x keep flat "Large Item" with dimensions 2500mm w × 2500mm l × 20mm d × 2000g | ||
And I do a packing | ||
Then I should have 0 boxes of type "Small" | ||
And I should have 1 boxes of type "Large" | ||
|
||
Scenario: Fitting mixed size items into a mix of box sizes | ||
Given there is a box "Small", which has external dimensions 600mm w × 600mm l × 10mm d × 10g and internal dimensions 596mm w × 596mm l × 8mm d and has a max weight of 1000g | ||
And there is a box "Large", which has external dimensions 3000mm w × 3000mm l × 50mm d × 100g and internal dimensions 2960mm w × 2960mm l × 40mm d and has a max weight of 10000g | ||
When I add 1 x keep flat "Small Item" with dimensions 550mm w × 550mm l × 2mm d × 500g | ||
When I add 4 x keep flat "Large Item" with dimensions 2500mm w × 2500mm l × 20mm d × 500g | ||
And I do a packing | ||
Then I should have 1 boxes of type "Small" | ||
And I should have 2 boxes of type "Large" | ||
|
||
Scenario: Simple stacking | ||
Given there is a box "Small", which has external dimensions 292mm w × 336mm l × 60mm d × 10g and internal dimensions 292mm w × 336mm l × 60mm d and has a max weight of 9000g | ||
And there is a box "Large", which has external dimensions 421mm w × 548mm l × 335mm d × 100g and internal dimensions 421mm w × 548mm l × 335mm d and has a max weight of 10000g | ||
When I add 1 x keep flat "Small Item" with dimensions 226mm w × 200mm l × 40mm d × 440g | ||
When I add 1 x keep flat "Large Item" with dimensions 200mm w × 200mm l × 155mm d × 1660g | ||
And I do a packing | ||
Then I should have 0 boxes of type "Small" | ||
And I should have 1 boxes of type "Large" | ||
|
||
Scenario: Making sure whatever bug caused issue #3 doesn't come back | ||
Given there is a box "Box A", which has external dimensions 51mm w × 33mm l × 33mm d × 1g and internal dimensions 51mm w × 33mm l × 33mm d and has a max weight of 1g | ||
And there is a box "Box B", which has external dimensions 50mm w × 40mm l × 40mm d × 1g and internal dimensions 50mm w × 40mm l × 40mm d and has a max weight of 1g | ||
When I add 6 x keep flat "Item" with dimensions 28mm w × 19mm l × 9mm d × 0g | ||
And I do a packing | ||
Then I should have 1 boxes of type "Box A" | ||
And I should have 0 boxes of type "Box B" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
Feature: BoxPacker | ||
In order to make logistics easier | ||
As a developer | ||
I need to be able to find out how a set of items can fit into a box | ||
|
||
Scenario: Packing 3 items that fit easily | ||
Given the box "Box", which has external dimensions 300mm w × 300mm l × 10mm d × 10g and internal dimensions 296mm w × 296mm l × 8mm d and has a max weight of 1000g | ||
When I add 3 x "Small Item" with dimensions 250mm w × 250mm l × 2mm d × 200g | ||
And I do a volume-only packing | ||
Then the packed box should have 3 items of type "Small Item" | ||
|
||
Scenario: Packing 3 items that fit exactly | ||
Given the box "Box", which has external dimensions 300mm w × 300mm l × 10mm d × 10g and internal dimensions 296mm w × 296mm l × 8mm d and has a max weight of 1000g | ||
When I add 2 x "Small Item" with dimensions 250mm w × 250mm l × 2mm d × 200g | ||
When I add 1 x "Medium Item" with dimensions 250mm w × 250mm l × 4mm d × 200g | ||
And I do a volume-only packing | ||
Then the packed box should have 2 items of type "Small Item" | ||
And the packed box should have 1 items of type "Medium Item" | ||
|
||
Scenario: Packing 3 items that would fit exactly but break the weight limit | ||
Given the box "Box", which has external dimensions 300mm w × 300mm l × 10mm d × 10g and internal dimensions 296mm w × 296mm l × 8mm d and has a max weight of 1000g | ||
When I add 1 x "Small Item" with dimensions 250mm w × 250mm l × 2mm d × 200g | ||
When I add 1 x "Medium Item" with dimensions 250mm w × 250mm l × 2mm d × 400g | ||
When I add 1 x "Heavy Item" with dimensions 250mm w × 250mm l × 2mm d × 500g | ||
And I do a volume-only packing | ||
Then the packed box should have 0 items of type "Small Item" | ||
And the packed box should have 1 items of type "Medium Item" | ||
And the packed box should have 1 items of type "Heavy Item" | ||
|
||
Scenario: Packing 2 items that fit exactly as long as they aren't rotated | ||
Given the box "Box", which has external dimensions 300mm w × 300mm l × 10mm d × 10g and internal dimensions 296mm w × 296mm l × 8mm d and has a max weight of 1000g | ||
When I add 1 x "Small Item" with dimensions 296mm w × 148mm l × 2mm d × 200g | ||
When I add 1 x "Medium Item" with dimensions 296mm w × 148mm l × 4mm d × 500g | ||
And I do a volume-only packing | ||
Then the packed box should have 1 items of type "Small Item" | ||
And the packed box should have 1 items of type "Medium Item" | ||
|
||
Scenario: Packing 3 items where 2 are oversized | ||
Given the box "Box", which has external dimensions 300mm w × 300mm l × 10mm d × 10g and internal dimensions 296mm w × 296mm l × 8mm d and has a max weight of 1000g | ||
When I add 1 x "Item A" with dimensions 297mm w × 296mm l × 2mm d × 200g | ||
When I add 1 x "Item B" with dimensions 297mm w × 296mm l × 2mm d × 500g | ||
When I add 1 x "Item C" with dimensions 296mm w × 296mm l × 4mm d × 290g | ||
And I do a volume-only packing | ||
Then the packed box should have 0 items of type "Item A" | ||
And the packed box should have 0 items of type "Item B" | ||
And the packed box should have 1 items of type "Item C" | ||
|
||
Scenario: Packing 2 items that fit exactly side by side after rotating | ||
Given the box "Box", which has external dimensions 300mm w × 500mm l × 10mm d × 10g and internal dimensions 296mm w × 496mm l × 8mm d and has a max weight of 1000g | ||
When I add 1 x "Item A" with dimensions 296mm w × 248mm l × 8mm d × 200g | ||
When I add 1 x "Item B" with dimensions 248mm w × 296mm l × 8mm d × 200g | ||
And I do a volume-only packing | ||
Then the packed box should have 1 items of type "Item A" | ||
And the packed box should have 1 items of type "Item B" | ||
|
||
Scenario: Packing 3 items with 2 fitting exactly side by side after rotating, and then 1 stacked (perfect fit) | ||
Given the box "Box", which has external dimensions 300mm w × 300mm l × 10mm d × 10g and internal dimensions 296mm w × 296mm l × 8mm d and has a max weight of 1000g | ||
When I add 1 x "Item A" with dimensions 248mm w × 148mm l × 4mm d × 200g | ||
When I add 1 x "Item B" with dimensions 148mm w × 248mm l × 4mm d × 200g | ||
When I add 1 x "Item C" with dimensions 296mm w × 296mm l × 4mm d × 200g | ||
And I do a volume-only packing | ||
Then the packed box should have 1 items of type "Item A" | ||
And the packed box should have 1 items of type "Item B" | ||
And the packed box should have 1 items of type "Item C" | ||
|
||
Scenario: Packing 3 items with 2 fitting exactly side by side after rotating, and then 1 stacked (with overhang) | ||
Given the box "Box", which has external dimensions 250mm w × 250mm l × 10mm d × 10g and internal dimensions 248mm w × 248mm l × 8mm d and has a max weight of 1000g | ||
When I add 1 x "Item A" with dimensions 200mm w × 200mm l × 4mm d × 200g | ||
When I add 2 x "Item B" with dimensions 110mm w × 110mm l × 4mm d × 200g | ||
And I do a volume-only packing | ||
Then the packed box should have 1 items of type "Item A" | ||
And the packed box should have 2 items of type "Item B" | ||
|
||
Scenario: Packing an item which requires 3D rotation to fit | ||
Given the box "Box", which has external dimensions 100mm w × 100mm l × 300mm d × 10g and internal dimensions 100mm w × 100mm l × 300mm d and has a max weight of 1500g | ||
When I add 1 x "Item A" with dimensions 150mm w × 50mm l × 50mm d × 20g | ||
And I do a volume-only packing | ||
Then the packed box should have 1 items of type "Item A" | ||
|
||
Scenario: Not 3D rotating unnecessarily (issue #53) | ||
Given the box "Box", which has external dimensions 500mm w × 1000mm l × 500mm d × 0g and internal dimensions 500mm w × 1000mm l × 500mm d and has a max weight of 0g | ||
When I add 1 x "Item A" with dimensions 500mm w × 500mm l × 500mm d × 0g | ||
When I add 2 x "Item B" with dimensions 500mm w × 500mm l × 250mm d × 0g | ||
And I do a volume-only packing | ||
Then the packed box should have 1 items of type "Item A" | ||
Then the packed box should have 2 items of type "Item B" | ||
|
||
Scenario: Making sure whatever bug caused issue #75 doesn't come back | ||
Given the box "Box", which has external dimensions 20mm w × 12mm l × 10mm d × 0g and internal dimensions 20mm w × 12mm l × 10mm d and has a max weight of 2500g | ||
When I add 2 x "Item A" with dimensions 12mm w × 12mm l × 5mm d × 8g | ||
When I add 2 x "Item B" with dimensions 8mm w × 12mm l × 5mm d × 8g | ||
And I do a volume-only packing | ||
Then the packed box should have 2 items of type "Item A" | ||
Then the packed box should have 2 items of type "Item B" | ||
|
||
Scenario: Test identical items that could be fit side by side actually do (issue #89) | ||
Given the box "SRA3 Sheet", which has external dimensions 450mm w × 320mm l × 1mm d × 0g and internal dimensions 450mm w × 320mm l × 1mm d and has a max weight of 0g | ||
When I add 4 x "A5 Sheet" with dimensions 148mm w × 210mm l × 1mm d × 0g | ||
And I do a volume-only packing | ||
Then the packed box should have 4 items of type "A5 Sheet" | ||
|
||
Scenario: Test smaller cubes successfully fit into a larger cube (issue #9) | ||
Given the box "Box", which has external dimensions 24mm w × 24mm l × 24mm d × 24g and internal dimensions 24mm w × 24mm l × 24mm d and has a max weight of 100g | ||
When I add 64 x keep flat "Item" with dimensions 6mm w × 6mm l × 6mm d × 1g | ||
And I do a volume-only packing | ||
Then the packed box should have 64 items of type "Item" | ||
|
||
Scenario: Test shallower items can be stacked alongside a taller one (issue #11) | ||
Given the box "Box", which has external dimensions 4mm w × 4mm l × 4mm d × 4g and internal dimensions 4mm w × 4mm l × 4mm d and has a max weight of 100g | ||
When I add 2 x keep flat "Tall Item" with dimensions 2mm w × 2mm l × 4mm d × 1g | ||
When I add 32 x keep flat "Shallow Item" with dimensions 1mm w × 1mm l × 1mm d × 1g | ||
And I do a volume-only packing | ||
Then the packed box should have 2 items of type "Tall Item" | ||
And the packed box should have 32 items of type "Shallow Item" | ||
|
||
Scenario: Test shallower items can be stacked alongside a taller one (issue #13) | ||
Given the box "Box", which has external dimensions 12mm w × 12mm l × 12mm d × 12g and internal dimensions 10mm w × 10mm l × 10mm d and has a max weight of 1000g | ||
When I add 2 x keep flat "Item A" with dimensions 5mm w × 3mm l × 2mm d × 2g | ||
When I add 1 x keep flat "Item B" with dimensions 3mm w × 3mm l × 3mm d × 3g | ||
And I do a volume-only packing | ||
Then the packed box should have 2 items of type "Item A" | ||
And the packed box should have 1 items of type "Item B" |
Oops, something went wrong.