将数组划分为相等加权的子数组

时间:2015-01-23 18:43:23

标签: ruby algorithm

算法问题在这里。

我有一个包含产品重量的无序数组,例如: [3, 2, 5, 5, 8]需要分成更小的数组。

规则:

  • 必需:应返回1个或更多数组。
  • 必需:任何数组都不应超过12个。
  • REQUIRED :返回最小可能数量的数组,例如以上示例的总重量为23,可以分为两个阵列。
  • IDEALLY :阵列应尽可能均匀加权。

在上面的示例中,理想回报为[ [3, 8], [2, 5, 5] ]

我目前的想法:

  • 要返回的数组数量为(sum(input_array) / 12).ceil
  • greedy algorithm可以运作得很好吗?

2 个答案:

答案 0 :(得分:2)

这是bin packing problemmultiprocessor scheduling problem的组合。两者都是NP难的。

您的三个要求构成了装箱问题:找到适合所有数字的固定尺寸(12)的最小箱数。

一旦你解决了这个问题,就会遇到多处理器调度问题:给定一定数量的垃圾箱,在这些垃圾箱中分配数字的最均匀方式是什么。

这两个问题都有众多众所周知的近似算法。

答案 1 :(得分:0)

对于完全不同的东西怎么样。真的很简单。像这样,这是基于普通的马感:

module Splitter

    def self.split(values, max_length = 12)

        # if the sum of all values is lower than the max_length there
        # is no point in continuing
        return values unless self.sum(values) > max_length

        optimized = []
        current = []

        # start off by ordering the values. perhaps it's a good idea
        # to start off with the smallest values first; this will result
        # in gathering as much values as possible in the first array. This
        # in order to  conform to the rule "Should return minimum possible 
        # number of arrays"
        ordered_values = values.sort

        ordered_values.each do |v|

            if self.sum(current) + v > max_length

                # finish up the current iteration if we've got an optimized pair
                optimized.push(current)

                # reset for the next iteration
                current = []
            end

            current.push(v)
        end

        # push the last iteration
        optimized.push(current)

        return optimized
    end

    # calculates the sum of a collection of numbers
    def self.sum(numbers)
        if numbers.empty?
            return 0
        else
            return numbers.inject{|sum,x| sum + x }
        end
    end
end

可以这样使用:

product_weights = [3, 2, 5, 5, 8]
p Splitter.split(product_weights)

输出将是:

  

[[2,3,5],[5],[8]]

现在,如前所述,这是一个非常简单的样本。我为了简洁而排除了数组中空值或非数值的验证。但它似乎符合您的主要要求:

  • 将(预期的:所有数字)值拆分为数组
  • 每个阵列有一个上限,样本默认为12
  • 按照收集的最小数字返回最小数量 编辑:从评论编辑后,这确实不起作用

我对“返回最小可能数量的数组,并尽可能均匀地平衡权重”的评论有一些疑问。我相信其他人会想出一个符合要求的更好且经过数学验证的算法的实现,但这可能至少是讨论的一个合适的例子吗?