如何在4个盒子中平均分配物品?

时间:2013-12-22 13:19:53

标签: php arrays math logic formula

假设我有7个不同重量的。实际上php数组包含这些数据。

Bag A    60 Kg
Bag B    80 Kg
Bag C    20 Kg
Bag D    10 Kg
Bag E    80 Kg
Bag F    100 Kg
Bag G    90 Kg

在php中它看起来像这样

    Array
(
    [30] => 60
    [31] => 120
    [32] => 120
    [33] => 60
    [35] => 180
)

现在我必须通过平衡重量来平均分配 4容器中的所有 7袋。 但我无法打破行李来控制体重。怎么做请建议我。我如何建立一个公式或php功能,将分配所有平衡重量的袋子。 容器容量没有限制。并且在分配之后也没有必要使所有容器重量相等。我只需要负载平衡。 提前谢谢。

2 个答案:

答案 0 :(得分:3)

计算行李重量的总和,然后除以行李箱数量。然后使用bin包装算法将袋子分配到各个容器。例如。从阵列中一次取一个袋子并放入第一个容器中,容器的重量加上袋子的重量小于最大容器重量。

http://en.wikipedia.org/wiki/Bin_packing_problem

<强>更新 用Ruby编写的例子。应该不是很难在PHP中重写它。它将袋子相对均匀地分配到容器中(可能存在更准确的解决方案)。

# A list of bags with different weights
list_of_bags = [11, 41, 31, 15, 15, 66, 67, 34, 20, 42, 22, 25]
# total weight of all bags 
weight_of_bags = list_of_bags.inject(0) {|sum, i| sum + i}
# how many containers do we have at our disposal?
number_of_containers = 4
# How much should one container weight? 
weight_per_container = weight_of_bags / number_of_containers
# We make an array containing an empty array for each container
containers = Array.new(number_of_containers){ |i| [] }

# For each bag
list_of_bags.each do |bag| 
    # we try to find the first container 
    containers.each do |container| 
        # where the weight of the container plus the weigth of the bag is 
        # less than the maximum allowed (weight_per_container)
        if container.inject(0) {|sum, i| sum + i} + bag < weight_per_container
            # if the current container has space for it we add the bag
            # and go to the next one 
            container.push(bag)
            break
        end 
    end
end

# output all containers with the number of items and total weight
containers.each_with_index do |container, index| 
    puts "container #{index} has #{container.length} items and weigths: #{container.inject(0) {|sum, i| sum + i}}"
end

示例结果:

container 0 has 3 items and weigths: 83
container 1 has 3 items and weigths: 96
container 2 has 2 items and weigths: 87
container 3 has 2 items and weigths: 76

答案 1 :(得分:1)

创建一个获取产品重量并返回行李号的函数 - 具有最小可用空间的行号。把它放进包里。重复直到完成。

$bags = array(60,80,20,10,80,100,90);
$containers = array(1=>100,2=>100,3=>100,4=>100); // number -> free space
$placement = array();

rsort($bags); // biggest first - usually it's better

function bestContainerFor($weight) {
    global $containers;
    $rest = 0;
    $out = 0; // in it won't change $weight fits nowhere
    foreach($containers as $nr=>$space) {
        if($space<$weight) continue; // not enough space
        if($space-$weight<$rest) continue; // we have a better case
        $rest = $space-$weight;
        $out = $nr;
    }
    if($out) $containers[$out]-=$weight; // occupy the space
    return $out;
}

foreach($bags as $nr=>$w) {
    $p = bestContainerFor($w);
    $placement[$nr] = $p; // for later use; in this example it's not needed
    if( $p) print "Bag $nr fits in $p<br>";
    if(!$p) print "Bag $nr fits nowhere<br>";
}

没有经过测试。如果你给我一些你的代码的细节,我会尝试适应。这只是说明了它的原理。

请注意

  • 适用于可变容器尺寸,
  • 它为您提供每个行李的放置,而不是总重量,
  • 这对于平等分配来说不是最佳的,只是给出一个好的案例