Php 求解最优组合数的算法——装箱问题

Php 求解最优组合数的算法——装箱问题,php,algorithm,math,Php,Algorithm,Math,假设我有以下措施: 八十 180 200 240 410 50 110 我可以存储每个数字组合,每个单元最多480个。我如何计算所需的最少数量单位,以便以最有效的方式传播所有措施 我已经标记了PHP,但也可以是JS,甚至是伪语言 我知道我应该告诉你我已经做了什么,但我一直在思考如何处理这个问题。我想到的第一件事是递归,但我不是数学专家,不知道如何高效地实现它 非常感谢您的帮助 更详细地说:我正试图根据墙壁所需的不同长度来计算我必须订购的踢脚线数量。每条踢脚线的长度为480cm,我想知道铺踢脚线的

假设我有以下措施:

八十 180 200 240 410 50 110

我可以存储每个数字组合,每个单元最多480个。我如何计算所需的最少数量单位,以便以最有效的方式传播所有措施

我已经标记了PHP,但也可以是JS,甚至是伪语言

我知道我应该告诉你我已经做了什么,但我一直在思考如何处理这个问题。我想到的第一件事是递归,但我不是数学专家,不知道如何高效地实现它

非常感谢您的帮助

更详细地说:我正试图根据墙壁所需的不同长度来计算我必须订购的踢脚线数量。每条踢脚线的长度为480cm,我想知道铺踢脚线的最佳方式,因此我必须购买最少数量的踢脚线。这并不是说要额外订购一条裙子,但要想弄明白它是一个有趣的难题(至少对我来说)

使用解决方案更新

尽管人们试图解决这个问题,我还是开始摆弄箱子包装问题的描述,并遵循将所有物品从最大到最小进行排序,然后以尽可能最佳的方式将其放入的想法,我创建了这个小类,将来可能会帮助其他人:

<?php
class BinPacker {
    private $binSize;

    public function __construct($binSize) {
        $this->binSize = $binSize;
    }

    public function pack($elements) {
        arsort($elements);
        $bins = [];
        $handled = [];

        while(count($handled) < count($elements)) {
            $bin = [];

            foreach($elements as $label => $size) {
                if(!in_array($label, $handled)) {
                    if(array_sum($bin) + $size < $this->binSize) {
                        $bin[$label] = $size;
                        $handled[] = $label;
                    }
                }
            }

            $bins[] = $bin;
        }

        return $bins;
    }

    public function getMeta($bins) {
        $meta = [
            'totalValue' => 0,
            'totalWaste' => 0,
            'totalBins' => count($bins),
            'efficiency' => 0,
            'valuePerBin' => [],
            'wastePerBin' => []
        ];

        foreach($bins as $bin) {
            $value = array_sum($bin);
            $binWaste = $this->binSize - $value;

            $meta['totalValue'] += $value;
            $meta['totalWaste'] += $binWaste;
            $meta['wastePerBin'][] = $binWaste;
            $meta['valuePerBin'][] = $value;

        }

        $meta['efficiency'] = round((1 - $meta['totalWaste'] / $meta['totalValue']) * 100, 3);

        return $meta;
    }
}

$test = [
    'Wall A' => 420,
    'Wall B' => 120,
    'Wall C' => 80,
    'Wall D' => 114,
    'Wall E' => 375,
    'Wall F' => 90
];

$binPacker = new BinPacker(488);
$bins = $binPacker->pack($test);

echo '<h2>Meta:</h2>';
var_dump($binPacker->getMeta($bins));

echo '<h2>Bin Configuration</h2>';
var_dump($bins);
虽然数据集相对较小,但满足了相当高的无效率。但在我自己的配置中,我输入了所有的墙壁和天花板措施,我的效率达到了
94.212%
(n=129措施)

(注意:该类不检查模糊标签,因此,例如,如果您两次定义
墙A
,则结果将不正确。)


结论:对于天花板和墙壁踢脚板,我可以订购一个比我手动尝试有效展开踢脚板少的踢脚板。

在我看来,这就像是一个变化,您试图选择480(或略低于480)的元素组合。这是一个在计算上相当困难的问题,根据它需要的效率/准确度,试图获得准确度可能有点过头了


一个粗略的启发式方法可能只是对度量值进行排序,不断地将最小的度量值添加到一个单元中,直到下一个度量值让您进行检查,然后添加到一个新单元并重复

很难理解你所说的“以最有效的方式传播”是什么意思。你能用更正式的方式陈述你的问题吗?也许算法属于其他地方,比如,既然你说它更像是一个算法而不是编程问题。我给这个问题添加了上下文。或者,我发现很难通过这个问题来判断。是的,装箱问题更准确,我会编辑我的答案。谢谢这两个,装箱问题准确地描述了我想要弄明白的东西。
Meta:

array (size=6)
  'totalValue' => int 1199
  'totalWaste' => int 265
  'totalBins' => int 3
  'efficiency' => float 77.898
  'valuePerBin' => 
    array (size=3)
      0 => int 420
      1 => int 465
      2 => int 314
  'wastePerBin' => 
    array (size=3)
      0 => int 68
      1 => int 23
      2 => int 174

Bin Configuration

array (size=3)
  0 => 
    array (size=1)
      'Wall A' => int 420
  1 => 
    array (size=2)
      'Wall E' => int 375
      'Wall F' => int 90
  2 => 
    array (size=3)
      'Wall B' => int 120
      'Wall D' => int 114
      'Wall C' => int 80