dvdoug / BoxPacker

4D bin packing / knapsack problem solver
MIT License
612 stars 156 forks source link

Packing issue with maxWeight #235

Closed aurimasrim closed 3 years ago

aurimasrim commented 3 years ago

Hello, we've found some strange behavior regarding weight and would appreciate it if you could check it.

Version 3.9.1

Specific example:

$packer = new Packer();
$packer->addBox(new TestBox('L', 1000, 1000, 1000, 0, 1000, 1000, 1000, 5));
$packer->addBox(new TestBox('XL', 1500, 1500, 1500, 0, 1500, 1500, 1500, 10));
$packer->addItem(new TestItem('', 1, 1, 1, 3, false));
$packer->addItem(new TestItem('', 1, 1, 1, 3, false));
$packer->addItem(new TestItem('', 1, 1, 1, 3, false));
$packer->addItem(new TestItem('', 1, 1, 1, 3, false));
$packedBoxes = $packer->pack();
foreach ($packedBoxes as $packedBox) {
    echo $packedBox->getBox()->getReference() . PHP_EOL;
}

The dimensions of the boxes are very big on purpose so the limiting factor for this packing case would be max weight. The actual result is:

XL
XL

Though I would expect it to be:

XL
L

The optimal solution would be to pack 3 items into the XL box and 1 item into the L box. Though the algorithm chooses to pack 2 XL boxes with 2 items in each.

I've debugged it a bit and I found out that it packs correctly at first but then the L box is replaced by XL box after a call to findBestBoxFromIteration https://github.com/dvdoug/BoxPacker/blob/3.9.1/src/Packer.php#L193

Do you know what could be the cause of it? Thanks in advance!

shakethatweight-simon commented 3 years ago

@aurimasrim Your issue relates to this: https://www.boxpacker.io/en/stable/weight-distribution.html - you can disable this if you want.

aurimasrim commented 3 years ago

But shouldn't weight distribution be applied only to already chosen boxes? I mean that if the optimal solution is 1 XL and 1 L then weight should be distributed between them?

dvdoug commented 3 years ago

But shouldn't weight distribution be applied only to already chosen boxes? I mean that if the optimal solution is 1 XL and 1 L then weight should be distributed between them?

Hi @aurimasrim

The "problem" with that is that to take a different example at the opposite end of the spectrum, imagine the "optimum" packing is 1xXL weighing 20kg and 1xpadded envelope weighing 250g. Restricting weight distribution purely between the two means that it can't do very much. The delivery driver and all of the warehouse operatives involved would probably very much prefer it if you shipped 2xM weighing ~10kg instead.

In my experience as long as the number of boxes is the same, the difference in shipping costs from using "non-optimal" sizes tends to be negligible thereby allowing for a human-factors adjustment.

Having said that, what's worked for me in the past is not necessarily the right thing for your business which is why the feature can be easily turned off :)

To come back to your original point:

But shouldn't weight distribution be applied only to already chosen boxes?

Doing it that way would be a valid choice, but I think it would have extremely limited impact on the results compared to not doing any weight distribution at all - there typically won't be much room left in the smaller "optimal" box to accept any items originally placed in a larger one.

aurimasrim commented 3 years ago

Hi @dvdoug good point. Thanks for the detailed explanation!