我有一个带有十进制值的数组,如下所示:
$a = array( 1.66, 28.13, 3.37, 2, 12, 88.90, 6.88, 0.57, 1.50 );
如何将此数组拆分为最少5个元素的组,这些元素的最小总和值为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 :(得分: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>';
}
?>
答案 1 :(得分: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()除了在显示解决方案之前标准化解决方案外没有任何其他目的。