2017-05-29 71 views
0

对于一个项目,需要根据每个平面的百分比将二维数组排列到平面中,并根据每个平面的百分比将平面彼此成比例。 (我希望这是有道理的,否则请看下面的例子)。在这个二维数组中,'第一'级代表行和'第二'级,列。例如;将二维数组划分为表面

array(
    // row 1 
    array(
     // items 
     number1 
     number2 
     numberN 
    ), 
    // row 2 
    array(
     // items.. 
    ), 
    // row N 
    array(
     // items.. 
    ) 
) 

该数组中的数字已被添加/排列,以便它们形成面板。面板一起形成一个网格。每个数字代表一个项目(对于这个问题无关紧要)。我自己想出了一个解决方案。 Click here for print of the 2D array (The groups are color coded.)

可以说,有三组(下面列出)。这些组代表上面介绍的面板。每组有一些介于零和百分之一之间的百分比。飞机的百分比总和必须是百分之百。组的最大数量是七个。示例组信息;

  • 组1(图A):70%
  • 组2(图B):20%
  • 组3(图C):10%

同样这种安排应导致在一个带有(子)面板的大面板中。 As shown in this schematic figure.

我想出了将最终结果分成4个角的想法。每个角落将按规则计算。这些角落应该是基于其所在角(左上角,右上角,左下角,右下角)的镜像(水平和/或垂直)。

规则列表;

  • 项目数应为TE相同的每一行
  • 完整网格的各方面比应为2比1。因此,宽度为两倍HIGHT。
  • 行的数量是基于总项目,因为方面是已知的。

经过几天的工作,我能够想出一个工作脚本。但在某些情况下,这确实表现出奇怪(如其中,不像预期的那样)。见上面的当前解决方案

所以,我的问题是;杠杆设计师是如何做到的?这是一个已知的问题,并有解决方案(如算法)什么解决这种(种)的问题?我现在很长一段时间一直在努力解决以下问题。在互联网上搜索,试图找到类似的问题。但我没有成功。
我不是要求现成的解决方案。只是一个正确的方向指针将不胜感激。

+0

是否百分比表示二维数组中单元格的百分比或值的总和的百分比,还是......?如果百分比无法准确达到,那么需要做些什么? – trincot

+0

@trincot它们代表项目的数量。因此,出于演示目的说,有4K项目。第一组有2800件(因为70%)。第二800和最后400.百分比将是一个近似值,而不是绝对值。 –

+0

(1)那么数组中的值对算法没有意义?他们都可以'空'? (2)飞机能否“接触”海誓山盟,所以一方面一个地区没有任何细胞?或者,在看到下一个区域之前,这些区域需要在4个方向的每个方向上有相同数量的“空间”(行/列)? (3)如果一个百分比如此之低以至于最接近的解决方案给一个小组根本没有细胞呢?这可以接受吗? – trincot

回答

0

假设飞机应具有大致相同的“宽高比”为一体的完整矩阵,您可以使用此算法:

  • 计算每个百分比会是什么系数,适用于宽度和高度在减去可用区域的百分比后得到确切的区域。该系数是需要应用于该区域的系数的平方根(与百分比有关)。

  • 由于该系数通常是非整数,因此检查舍入宽度和高度的方式会产生一个距离所需区域最近的区域。

  • 对每架飞机重复此操作。

下面是代码:

function createPlanes($width, $height, $groupPercentages) { 
    $side = 0; 
    $area = $width * $height; 
    $planeWidth = $width; 
    $planeHeight = $height; 
    $sumPct = 0; 
    $coefficient2 = 1; 
    foreach ($groupPercentages as $i => $pct) { 
     $plane = [ 
      "column" => floor(($width - $planeWidth)/2), 
      "row" => floor(($height - $planeHeight)/2), 
      "width" => $planeWidth, 
      "height" => $planeHeight, 
     ]; 
     $coefficient2 -= $pct/100; 
     $coefficient = sqrt($coefficient2); 
     $planeArea = $coefficient2 * $area; 
     $planeWidth = $coefficient * $width; 
     $planeHeight = $coefficient * $height; 
     // determine all possible combinations of rounding: 
     $deltas = [ 
      abs(floor($planeWidth) * floor($planeHeight) - $planeArea), 
      abs(floor($planeWidth) * min(ceil($planeHeight), $plane["height"]) - $planeArea), 
      abs(min(ceil($planeWidth), $plane["width"]) * floor($planeHeight) - $planeArea), 
      abs(min(ceil($planeWidth), $plane["width"]) * min(ceil($planeHeight), $plane["height"]) - $planeArea) 
     ]; 
     // Choose the one that brings the area closest to the required area 
     $choice = array_search(min($deltas), $deltas); 
     $planeWidth = $choice & 2 ? ceil($planeWidth) : floor($planeWidth);   
     $planeHeight = $choice & 1 ? ceil($planeHeight) : floor($planeHeight); 
     $newSumPct = ($area - $planeWidth * $planeHeight)/$area * 100; 
     $plane["pct"] = $newSumPct - $sumPct; 
     $sumPct = $newSumPct; 
     $planes[] = $plane; 
    } 
    return $planes; 
} 

// Example call for a 2D array with 20 columns and 32 rows, and 
// three percentages: 10%, 20%, 70%: 
$planes = createPlanes(20, 32, [10, 20, 70]); 

$planes变量会得到这个内容:

array (
    array (
    'column' => 0, 
    'row' => 0, 
    'width' => 20, 
    'height' => 32, 
    'pct' => 10.9375, 
), 
    array (
    'column' => 0, 
    'row' => 1, 
    'width' => 19, 
    'height' => 30, 
    'pct' => 20, 
), 
    array (
    'column' => 1, 
    'row' => 3, 
    'width' => 17, 
    'height' => 26, 
    'pct' => 69.0625, 
), 
) 

内部属性定义在平面开始(行,列),以及如何它是(高度,宽度)大,这是平面相对于总面积的实际百分比。

请注意,实际的2D不需要是算法的一部分,因为它的值不会影响它。

+0

我真的很感谢你的时间和想法在这个问题上。但我相信我之前的解释是不完整的,并且可以解释。您提供的示例不能解决我的问题:( 我编辑了我的问题并添加了重要信息,请您再看一次吗? –

+0

我很抱歉,但在编辑中看不到任何规则,我的回答无法处理。另一方面,我昨天问了几个问题(在你的问题的评论中),其中你只回答了1个问题。也许这会很好,你用你期望的结果制定了一个例子。如果这些数字不重要,那么只需使用该示例的全部1个值,以避免人们开始认为它们表示该算法的重要内容。 – trincot