best way to loop through and combine products

谁都会走 提交于 2021-01-29 06:18:31

问题


I'm looking for your personal thoughts on the best way to do this as there a number of ways that I can see to get to the same end.

I have a store front that has multiple different booklets that can be ordered in any combination.

Each booklet item has L x W x H and weight in the database. They're all really the same L x W, it's the thickness and weight that varies.

I also have a set max box size.

I know I can fit a height of 10.5 in the largest box size.

I can combine the books however for shipping. So I want to fill the box to the max I can, then repeat until I only have a partial box.

The final result I need is an array of each of the boxes and their weight.

Example:

Items ordered

  1. 100 of Book 1 with a thickness of .05 and weight of .15
  2. 200 of Book 2 with a thickness of .07 and a weight of .23

Heights

  1. 100 * .05 = 5
  2. 200 * .07 = 14

Weights

  1. 100 * .15 = 15
  2. 200 * .23 = 46

Box 1 Contains

  1. 150 of Book 2
  2. Height: 150 * .07 = 10.5
  3. Weight: 150 * .23 = 34.5

Box 2 Contains

  1. 50 of Book 2 and 100 of Book 1
  2. Height: (100 * .05) + (50 * .07) = 8.5
  3. Weight: (100 * .15) + (50 * .25) = 27.5

How would you go about looping through the information to get the output? Start with one product, figure the height, divide it out to full boxes, calculate the weight of those boxes and add each full box to the array, take the height of the partial box and move on to the next product? Or......??

Static coding would be "easy", but I'm trying to code this dynamically so that I don't have to come back in every time I add a new product.

-edit-

Here is my current loop, but this is only totaling the quantity and dividing into boxes. The current products are all the same size / shape, so this worked fine then.

    if($zip_code != '')
    {
        my $item_list = enc_sql_select_multi("SELECT * FROM `$PREF{shopping_carts_table}` WHERE `cart_id` = '$cart_id' AND `sold` = '0' AND `deleted_from_cart` = '0'");
        my $item_qty = '0';
        foreach my $k (sort { $a <=> $b } keys %$item_list)
        {
            $item_qty =~ s/,//g;
            my $item_id = $$item_list{$k}{id};
            my $item_qty_new = $$item_list{$k}{option1value};
            $item_qty_new =~ s/,//g;
            $item_qty = $item_qty + $item_qty_new;
        }
        if ($item_qty != '0')
            {
                $item_qty =~ s/,//g;
                if ( $item_qty == 25 )
                {
                    my $tempCount = $carton_specs{25}{boxNo};
                    $tempCount++;
                    $carton_specs{25}{boxNo} = $tempCount;
                }
                elsif ( $item_qty == 50 )
                {
                    my $tempCount = $carton_specs{50}{boxNo};
                    $tempCount++;
                    $carton_specs{50}{boxNo} = $tempCount;
                }
                elsif ( $item_qty == 100 )
                {
                    my $tempCount = $carton_specs{100}{boxNo};
                    $tempCount++;
                    $carton_specs{100}{boxNo} = $tempCount;
                }
                elsif ($item_qty > 100 && $item_qty < 5000)
                {
                    my $fullBoxCt = int($item_qty / 200);
                    my $tempCountFull = $carton_specs{200}{boxNo};
                    $tempCountFull = $tempCountFull + $fullBoxCt;
                    $carton_specs{200}{boxNo} = $tempCountFull;
                    my $partBoxQty = $item_qty - (200 * $fullBoxCt);
                    if ($partBoxQty != 0)
                    {
                        my $tempCountPart = $carton_specs{$partBoxQty}{boxNo};
                        $tempCountPart++;
                        $carton_specs{$partBoxQty}{boxNo} = $tempCountPart;
                    }
                }
                else
                {
                    @shipDetails =
                    (
                        {
                            Code => 1000,
                            Price => '0.00'
                        },
                        {
                            Code => 1500,
                            Price => '0.00'
                        }
                    );
                    return (@shipDetails);
                }
            }

回答1:


There is no getting away from this being a classic example of the bin-packing problem and while I am no mathematician either, a lot of people who are have given this considerable thought. So:

There is no known optimal solution to this problem that can be computed in polynomial time and it would appear the size of your inputs can be quite large. Therefore, you should adopt one of the following heuristics:

  1. First Fit Algorithm: Process the booklets one by one placing it in the first box that has enough capacity to hold the booklet. If there are no such boxes, a new box must be started and added to the list of boxes available.
  2. Best Fit Algorithm: Process the booklets one by one placing it in the box where it fits the tightest (has the smallest capacity left). If there are no boxes that can hold the booklet, a new box must be started and added to the list of boxes available.
  3. First Fit Decreasing Algorithm: First order the booklets by decreasing height and then perform the First Fit Algorithm. In your example you would be packing up the "Book 2" booklets first.
  4. Best Fit Decreasing Algorithm: First order the booklets by decreasing height and then perform the Best Fit Algorithm.

But, of course, your orders consist of N items of of a certain type of booklet. We will take the prescription "one at a time" in the above algorithms loosely. So if you are doing, for example, the First Fit Algorithm, then when you find the first box that has the capacity to hold the booklet, it is easy enough to calculate the maximum number of those booklets, M, that box could hold and process up to min(M, N_LEFT) booklets at one time where N_LEFT is the number of booklets of that size you still have left to pack up. Likewise for any of the other three algorithms.

You can survey other bin-packing heuristics of which the above are just a sample four. I can't say one is necessarily superior to the others in all cases. I think any reasonable implementation of any of them will be satisfactory for your purposes. Anyway, this is my take.




回答2:


This is a bin-packing problem. The best optimal algorithm is Korf's. If this is too slow for the amount of data you have, there are various algorithms that provide good approximate answers faster.



来源:https://stackoverflow.com/questions/63819538/best-way-to-loop-through-and-combine-products

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!