2012-11-12 192 views
2

下面PHP集团行数据分为2组,是一个集我有基于总价值

ID | Dept | Value 

1 | 0 | 50.58 

2 | 0 | 75.64 

3 | 0 | 32.57 

4 | 0 | 187.57 

5 | 0 | 354.54 

我将如何去分割将其分为2组,部门1和部门2中,其中击穿将基于价值。即,其值接近总值的一半。

在上面的例子中,ID1-4将在组1中,总数为346.36,ID5将在组2中,总数为354.54。

+0

啊?总价值的一半是350.45。那么你需要在“部门1”中具有小于此值的任何值以及“部门2”中的任何其他值? – Luke

回答

0

这是一个非常困难的问题。有很多算法可以做到这一点“bin packing”解决方案(即试图在各种容器上平均分割各种大小)。这基本上是一样的。有关它的更多信息,请看Fill volume algorithm

简而言之,这并不容易,最多只能得到最佳解决方案的近似值。

+0

你可以给出任何代码实例来获得一个近似值,我没有期望每次都能得到确切的答案,因为数据集可以定期改变。 – buzzmonkey

+0

我相信我为其他问题提供的链接有一些例子。也看看http://en.wikipedia.org/wiki/Bin_packing_problem。基本上最简单的解决方案是按降序排列项目,并将其分配给剩余空间的第一个部门。但在你的情况下,你不介意轻微的溢出,所以你必须想出这个想法的一些变种。 – CodePB

0

此代码应该做你想做的事情。

<?php 
// Your records stored as arrays 
$records = array(
     array(1, 0, 50.58), 
     array(2, 0, 75.64), 
     array(3, 0, 32.57), 
     array(4, 0, 187.57),   
     array(5, 0, 354.54) 
); 

// Blank value for total value 
$total_value = 0; 

// Calculate half way of total 
foreach ($records AS $record) 
{ 
    $total_value += $record[2]; 
} 

// Get the half way point 
$half_way = $total_value/2; 

// Create array for each department 
$dept_1 = array(); 
$dept_2 = array(); 

// Split the records in to department 
foreach ($records AS $record) 
{ 
    if ($record[2] >= $half_way) 
    { 
     // Put in to department 1 
     array_push($dept_2, $record); 
    } 
    else 
    { 
     // Put in to department 2 
     array_push($dept_1, $record); 
    } 
} 

// Show each departments contents 
var_dump($dept_1); 
var_dump($dept_2); 
?> 

它产生两个数组$dept_1$dept_2取决于它们的值是否高于或低于一半的总的:

array(4) { 
    [0]=> 
    array(3) { 
    [0]=> 
    int(1) 
    [1]=> 
    int(0) 
    [2]=> 
    float(50.58) 
    } 
    [1]=> 
    array(3) { 
    [0]=> 
    int(2) 
    [1]=> 
    int(0) 
    [2]=> 
    float(75.64) 
    } 
    [2]=> 
    array(3) { 
    [0]=> 
    int(3) 
    [1]=> 
    int(0) 
    [2]=> 
    float(32.57) 
    } 
    [3]=> 
    array(3) { 
    [0]=> 
    int(4) 
    [1]=> 
    int(0) 
    [2]=> 
    float(187.57) 
    } 
} 

array(1) { 
    [0]=> 
    array(3) { 
    [0]=> 
    int(5) 
    [1]=> 
    int(0) 
    [2]=> 
    float(354.54) 
    } 
} 
+0

这并不完全是问题的要求。他希望将分配给每个部门的项目总数约为总数的一半。你的解决方案在这种情况下工作(因为它在一个部门中是1个,其余部分在另一个部门中),但是如果你要添加另一个大型项目,它将不起作用 – CodePB