2016-07-01 6 views
0

を持つグループへの配列:スプリット私はこのような小数点以下の値を持つ配列を持っている分値と最小要素

私は最小の合計値を持つ最小5つの要素のグループにこの配列を分割することができますどのように
$a = array(1.66, 28.13, 3.37, 2, 12, 88.90, 6.88, 0.57, 1.50); 

50と言うことができます!

私はこの機能を使用していますが、私がしようとしていることはかなり解決していません。

function split_into_groups($input_array) { 

    $limit = 50; 
    rsort($input_array); 
    $b = array(array()); 
    $index = 0; 
    foreach($input_array as $i){ 
     if($i + array_sum($b[$index]) > $limit){ 
      $b[++$index] = array(); 
     } 
     $b[$index][] = $i; 
    } 
    return $b; 
} 

出力:

array(4) { 
    [0]=> 
    array(0) { 
    } 
    [1]=> 
    array(1) { 
    [0]=> 
    float(88.9) 
    } 
    [2]=> 
    array(3) { 
    [0]=> 
    float(28.13) 
    [1]=> 
    int(12) 
    [2]=> 
    float(6.88) 
    } 
    [3]=> 
    array(5) { 
    [0]=> 
    float(3.37) 
    [1]=> 
    int(2) 
    [2]=> 
    float(1.66) 
    [3]=> 
    float(1.5) 
    [4]=> 
    float(0.57) 
    } 
} 
+0

あなたが試したことと、どこにいらっしゃったのかを教えてください。 –

+0

ループスルー、選択した和にヒットしたとき合計の合計を保持する50 –

+0

サンプル出力してください。 –

答えて

1

これはちょっと難しいことでしたが、これはあなたが後にしていることを願っています。 コード内の注釈で十分説明できるはずです。そうでない場合はコメントを残してください。

<?php 
$a = array(1.66, 28.13, 3.37, 2, 12, 88.90, 6.88, 0.57, 1.50); 
// split into groups of at least 5 elements, 
// each group must have sum of at least 50 

// create array to hold arrays of groups: 
$groups = array(0); 

// initialize a counter to say which element of $groups to add to: 
$group_selector = 0; 

// this must be declared as an array, creating a multidimentional array: 
$groups[$group_selector] = array(); 

// loop through each item in $a, deciding where to put it: 
for ($i=0; $i < count($a); $i++) { 

    // check if there is less than 5 elements in current group, OR the sum is less than 50: 
    if ((count($groups[$group_selector]) < 5) || (array_sum($groups[$group_selector]) < 50)) { 

     // add current $a item to current group: 
     array_push($groups[$group_selector], $a[$i]); 

    } else { 
     // increment the group selector and declare it as a new array: 
     $group_selector++; 
     $groups[$group_selector] = array(); 
     array_push($groups[$group_selector], $a[$i]); 
    } 

} # end of main for loop 

// print the raw array (doesn't look very good): 
print_r($groups); 

echo '<br><br>'; 

// print the sum of each group, and the number of items it contains: 
for ($i=0; $i < count($groups); $i++) { 
    echo 'count: ' . array_sum($groups[$i]) . '<br>number of items: ' . count($groups[$i]) . '<br><br>'; 
} 
?> 
0

小さなアレイでは、強引なアプローチがうまく合理的に働くかもしれません。

このアルゴリズムは、すべての制約を満たすまで配列をシャッフルします。または、最大反復回数後に停止します。

define('MAX_ITER',  10000); 
define('MIN_CHUNK_SUM', 50); 
define('MAX_CHUNK_SIZE', 5); 

$chunk = solve(
    array(1.66, 28.13, 3.37, 2, 12, 88.90, 6.88, 0.57, 1.50), 
    $i 
); 

if($chunk === false) { 
    printf("No solution found\n"); 
} 
else { 
    printf("Found a solution in %d iterations\n", $i); 

    foreach($chunk as $n => $c) { 
    arsort($c); 
    printf("Chunk #%d: SUM = %g with { %s }\n", $n, array_sum($c), implode(", ", $c)); 
    } 
} 

function solve($a, &$i) { 
    for($i = 0; $i < MAX_ITER; $i++) { 
    shuffle($a); 
    $chunk = array_chunk($a, MAX_CHUNK_SIZE); 

    foreach($chunk as $c) { 
     if(array_sum($c) < MIN_CHUNK_SUM) { 
     continue 2; 
     } 
    } 
    return $chunk; 
    } 
    return false; 
} 

出力例:

// Found a solution in 4 iterations 
// Chunk #0: SUM = 50.51 with { 28.13, 12, 6.88, 2, 1.5 } 
// Chunk #1: SUM = 94.5 with { 88.9, 3.37, 1.66, 0.57 } 

注arsort()は、それを表示する前に溶液を標準化するよりも、他の目的を果たしていないこと。

関連する問題