Cloudstek / php-laff

Largest Area Fit First (LAFF) 3D box packing algorithm class for PHP
MIT License
83 stars 32 forks source link

Support input of container sizes #2

Open nilsga opened 11 years ago

nilsga commented 11 years ago

If you extend this script to also support an array of possible container sizes, and then finding the combination that fits all boxes, it would be even more perfect :)

Example:

$container_sizes = array(
    array(
        'length' => 10,
        'height' => 5,
        'width' => 25
    ),
    array(
        'length' => 15,
        'height' => 15,
        'width' => 40
    )
);

$boxes = array(); // Boxes with dimensions

$packer = new LAFFPacker();
$packer->pack($boxes, $container_sizes);

$containers = $packer->get_containers(); // Array of containers
mdeboer commented 11 years ago

That's a great idea! I'll have a go at it after I'm back from holiday and have a bit more time to spend.

2ndMile commented 10 years ago

Hi mdeboer,

Thanks for the great piece of code. I am implementing it in a Drupal Commerce shipping module. I see that you added the ability to specify container size. I see the note about not specifying the height of the container. I find this interesting. If I want to specify a size of a container, the height would be part of that... and then I would just have left over product that doesn't fit. I am just wondering about your decision to calculate the container height on the fly.

mdeboer commented 10 years ago

Hi 2ndMile!

With all the millions of things going on in my life I forgot about it unfortunately, yet I'm willing to still make the change if you like and it's great to hear that you're implementing it in a Drupal Commerce module!

Not sure about the comment about the height, I think this had to do with two "modes", either finding out how many boxes you need (total calculated height / box height) and a mode that just checks whether it fits or not. But I'll look into that and update the documentation on that a bit!

If you got any questions, feel free to send me an email (info@maartendeboer.net) or file a bug report/feature request!

mdeboer commented 10 years ago

I looked into the issue and I think it's best to first make the code a bit more OOP, this makes it a lot easier to work with multiple containers. This also allows you to add more data to boxes and containers and extend the whole code a lot easier.

Anyway, I'll start working on this in my spare time so bear with me! I'll keep you guys posted :+1:

2ndMile commented 10 years ago

Good to hear. I worked on the implementation some last night. Since the height was returned (using my width and length) I compared it with the height of the physical container being packed. This works out well.

You saved me a lot of hair pulling. I am using some code from https://drupal.org/sandbox/jhaskins/1873204 to make my module. Most of the shipping modules available for Drupal Commerce are pretty bad when it comes to packing products in containers. Many of them have their own packing algorithm built-in and none of them are good. Joe's idea (the author of the Commerce module) of separating the packing logic from the rate retrieval makes sense on many levels. I am trying to contact him to see if he wants to implement your class. If not, I will go out on my own and try to get this into some useable form for the community.

mdeboer commented 10 years ago

Awesome that's great! I'll make another branch with unstable course for testing soon :)

Update: I decided not to get in to branching but I tagged this initial release as v1.0 and created a milestone for this task for v2.0 which will be just here in the master branch.

mdeboer commented 10 years ago

Happy Christmas by the way!

2ndMile commented 10 years ago

Merry Christmas to you too!

mdeboer commented 10 years ago

I worked on the code making it more OOP and easy to develop, first few commits should come soon. Got some other projects that require my attention as well :)

obfuscode commented 10 years ago

hey mdeboer - any chance you implemented this? I don't care if it's rough code - would really love it if you have it laying around!

nguyenanhthai commented 8 years ago

Hi guys, Your work is awesome! I have written some extend lines for your class that can limit the height of container box. When we limit the height of container, we can run the packing algorithm recursively on remaining boxes. So there we can resolve the problem with several containers.

However, when we have several containers, we have a confusion (fuzzy) when choose which containers has the highest priority to pack first. So there if we have several containers, we will have several solutions for one packing problem. Then, we need some further way to handle (sorting, filtering) for generated solutions.

tharmann commented 4 years ago

This is a simple, albeit BRUTE, way to achieve this: https://gist.github.com/tharmann/f1fd9aa1c5d24fe359491cd49b0eba6f

What the code does is basically break a list of items into smaller and smaller chunks until everything fits in a box/container. It has some limitations...example, if the there are adjacent items in the list that will always only fit into a container by themselves...the whole order gets split into one item per box. The good thing is that an optimal box is still found for each item.

I will try to improve this functionality in the future...but for for now, the code outputs something like this: array(3) { [0]=> array(3) { ["box"]=> array(7) { ["ol"]=> float(20.125) ["ow"]=> float(11.25) ["oh"]=> float(14.437) ["il"]=> int(20) ["iw"]=> float(11.125) ["ih"]=> float(14.312) ["max_weight"]=> int(60) } ["items"]=> array(3) { [0]=> string(11) "Product One" [1]=> string(11) "Product Two" [2]=> string(13) "Product Three" } ["total_weight"]=> int(14) } [1]=> array(3) { ["box"]=> array(7) { ["ol"]=> float(14.25) ["ow"]=> float(9.375) ["oh"]=> float(9.5) ["il"]=> float(14.125) ["iw"]=> float(9.25) ["ih"]=> float(9.375) ["max_weight"]=> int(30) } ["items"]=> array(3) { [0]=> string(12) "Product Four" [1]=> string(12) "Product Five" [2]=> string(11) "Product Six" } ["total_weight"]=> int(7) } [2]=> array(3) { ["box"]=> array(7) { ["ol"]=> float(11.125) ["ow"]=> float(9.125) ["oh"]=> float(6.125) ["il"]=> int(11) ["iw"]=> int(9) ["ih"]=> int(6) ["max_weight"]=> int(20) } ["items"]=> array(1) { [0]=> string(13) "Product Seven" } ["total_weight"]=> int(3) } }