2017-05-29 70 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