计算最大包大小(以PHP为单位)

时间:2010-01-02 23:46:58

标签: php algorithm

为此使用PHP。

从给定的一组物品中,每个物品都有自己的重量,我需要自动计算将物品包装成100磅包装的最有效方法(最大包装重量100磅是静态的,但可以在将来改变)。单个包装不能超过指定的最大值。

例如,我有5个项目 - 总重量为254磅:

  • 第1项 - > 51磅
  • 第2项 - > 28磅
  • 第3项 - > 73磅
  • 第4项 - > 51磅
  • 第5项 - > 51磅

人们会认为254磅需要3 x 100磅的包装。这个例子有意地证明了情况并非总是如此。某些项目配置无法很好地协同工作。这个例子需要4 x 100 lbs的最佳配置包。

项目数量和权重是完全可变的,任何单个项目都不会超过100磅。

实现这一目标的最佳方式是什么?

3 个答案:

答案 0 :(得分:8)

您所描述的问题称为Bin Packing Problem。没有人知道解决它的最佳方法。如果他们这样做,他们将能够证明P=NP或P!= NP - 计算中一个重要的开放性问题。

维基百科页面包括对一些示例算法的引用 - 第一拟合算法,最佳拟合递减,第一拟合递减。通常,解决此问题的一种快速方法是不尝试找到最佳解决方案,而是找到一个好的近似值。 “减少”指的是首先包装最大,最笨拙的元素,然后用最后的小元素填充间隙是一个好主意。这实际上类似于大多数人通常如何解决这个问题。

对于您在示例中给出的问题的大小,通过检查所有可能的排列来找到最佳解决方案很简单,但显然对于较大的示例而言效率不高。

答案 1 :(得分:1)

问题实际上与此处讨论的相同:

Convert function from recursion to iteration

盲搜索方法是应用每个组合的组合,这将创建一个N阶的算法!如果你只有少量的项目不是一个大问题(5个项目只提供120个组合搜索 - 但10需要超过360万)

根据我的帖子,请参阅

http://en.wikipedia.org/wiki/Travelling_salesman_problem

有关非详尽算法的描述。

下进行。

答案 2 :(得分:0)

对于那些感兴趣的人,这是我为解决我的问题所写的代码:

    //Loop thru cart items - adding weights to packages
    foreach((array)$this->cart_items as $cart_item) {
        for ($i = 0; $i < $cart_item->quantity; $i++) {

            $itemWeight = $cart_item->weight;   //Get current item weight
            $currWeight += $itemWeight;             //Add item weight to active package

            if ($currWeight > 100){                     //Max weight reached for active package

                $currWeight -= $itemWeight;         //Remove item from current package, too heavy
                $loopPack = 0;                                  
                $itemUsed = false;

                //Check if an existing package can take the item
                while (($loopPack != $packageCount) or ($itemUsed = false)) {
                    if ($packages[$loopPack] + $itemWeight < 100) {
                        $packages[$loopPack] += $itemWeight;
                        $itemUsed = true;
                    }
                    $loopPack++;
                }

                //if the item didn't fit in an existing package, create a new package for it
                if ($itemUsed == false) {
                    $packageCount++;
                    $packages[$packageCount-1] = $currWeight;
                    $currWeight = $cart_item->weight;           //Put unused item back in active package            
                }

            }
        }
    }
    //The remainder becomes a package
    $packageCount++;
    $packages[$packageCount-1] = $currWeight;

    print_r($packages);