计算prestashop中载体模块的多个产品的盒子大小

时间:2012-09-09 10:49:21

标签: algorithm prestashop

我目前正在为Kuroneko开发一个载体模块,这是一家门到门的日本送货公司。该载体与重量一起考虑箱子的尺寸。但它不使用音量,这将太容易了。它使用三个维度(高度,重量和深度)的总和。

如果您只有一个产品可以装盒,那么它仍然很容易但是当您需要装箱2个产品时会发生什么?假设您有两个尺寸乘积(x1,y1,z1)和(x2,y2,z2),如何以最小X + Y + Z的方式计算最终的盒子尺寸X,Y,Z? / p>

这是我的临时解决方案,但请告诉我是否有更好的计算方法: 令m1为第一个乘积的最小尺寸,min(x1,y1,z1)和m2为第二个。您必须考虑到框中产品的旋转以便以最佳方式拟合它们,从而为两种产品定义新尺寸nx,ny,nz。我们假设nx = m。如果m = x则ny = y,nz = z,否则如果m = y则ny = x,nz = z,否则如果m = z,则ny = y,nz = x。因此总盒子大小变为2 * nx,max(ny1,ny2),max(nz1,nz2)。

但据我所知,我不认为这种方法适用于超过2种产品。有什么想法吗?

3 个答案:

答案 0 :(得分:4)

  • 回答演示Here
  • 您可以查看代码here(我添加了canvas以进行可视化)

逻辑:

  1. 查找总音量(w * h * d)[+(w * h * d)..]

  2. 收集所有可能的宽度高度和深度值,从最低到最高排序

  3. 查找所有可能的宽度排列,然后是高度,然后是宽度

    3A。 示例:宽度范围1,2,3的总和排列为1,2,3,4,5,6

    3B。我们需要这个,因为宽度的最终值绝对不能为1.5例如基于示例(3a。)

  4. 根据(3。)计算的排列,找出宽度,高度和深度的所有可能组合

  5. 存储总音量等于或大于(1。)

    的总音量的所有组合

    5a上。这是因为最终音量不可能小于实际音量(1.)

    5b中。对于大于(1.)的卷,它意味着死区。

  6. 排序来自(5.)Ascending的所有组合,第一个结果将是最准确的音量
  7. 最准确的音量可能仍然具有不同的尺寸

    7a中。 示例:第16卷可以是2x2x4或4x4x1或2x1x8或16x1x1

    7b中。 查找每个W + H + D的总和和最小的总和将是更准确的维度。

    7C。示例来自(7a。)2 + 2 + 4 = 8,4 + 4 + 1 = 9,2 + 1 + 8 = 11,16 + 1 + 1 = 18 ....因此我们的脚本将选择2 x 2 x 4

答案 1 :(得分:1)

我一直在寻找这个算法,但链接已关闭,但是我可以使用这种方法找到它。

无论如何,我会在这里发布,因为它可能对其他人有用

<?php

$test = '1,2,3|4,2,1|0.1,0.9,0.01';

$dimensions = explode("|", $test);

//1. Find total volume
$volume = 0;
//2. Find WHD ranges
$widthRange     = array();
$heightRange    = array();
$depthRange     = array();
foreach($dimensions as $dimension) {
    list($width, $height, $depth) = explode(',', $dimension);

    $volume += $width * $height * $depth;

    $widthRange[] = $width;

    $heightRange[] = $height;

    $depthRange[] = $depth;
}

//3. Order the WHD ranges
sort($widthRange);
sort($heightRange);
sort($depthRange);

echo 'Volume: '.$volume.'<br />';
echo 'Width Range: '.implode(', ', $widthRange).'<br />';
echo 'Height Range: '.implode(', ', $heightRange).'<br />';
echo 'Depth Range: '.implode(', ', $depthRange).'<br />';

//4. Figure out every combination with WHD
$widthCombination   = array();
$heightCombination  = array();
$depthCombination   = array();

function combination($list) {
    $combination = array();
    $total = pow(2, count($list)); 
    for ($i = 0; $i < $total; $i++) {   
        $set = array();
        //For each combination check if each bit is set  
        for ($j = 0; $j < $total; $j++) {  
           //Is bit $j set in $i?  
            if (pow(2, $j) & $i) $set[] = $list[$j];       
        }  

        if(empty($set) || in_array(array_sum($set), $combination)) {
            continue;
        }

        $combination[] = array_sum($set);
    }

    sort($combination);

    return $combination;
}

$widthCombination = combination($widthRange);
$heightCombination = combination($heightRange);
$depthCombination = combination($depthRange);

echo 'Width Combination: '.implode(', ', $widthCombination).'<br />';
echo 'Height Combination: '.implode(', ', $heightCombination).'<br />';
echo 'Depth Combination: '.implode(', ', $depthCombination).'<br />';

$stacks = array();
foreach($widthCombination as $width) {
    foreach($heightCombination as $height) {
        foreach($depthCombination as $depth) {
            $v = $width*$height*$depth;
            if($v >= $volume) {
                $stacks[$v][$width+$height+$depth] = array($width, $height, $depth);
            }
        }
    }
}

ksort($stacks);

foreach($stacks as $i => $dims) {
    ksort($stacks[$i]);
    foreach($stacks[$i] as $j => $stack) {
        rsort($stack);
        break;
    }

    break;
}

echo '<pre>'.print_r($stacks, true).'</pre>';

所有赠送金额均属于Christian Blanquera

答案 2 :(得分:0)

以上算法不适用于尺寸: $test = '100,10,10|50,50,50'; 第一个结果是:

(
  [0] => 50
  [1] => 60
  [2] => 50              
)

,但第一个产品不合适。组合数组应仅包含大于或等于最大尺寸的大小之和(宽度组合不应包含50)。