当前位置: 首页 > 知识库问答 >
问题:

将数组分成最小和最大长度的组的最佳Ruby算法是什么?

养枫涟
2023-03-14

我有一个背景工作,需要合并很多项目在一起。我想将其拆分为多个“子作业”,每个子作业合并数据的一个子集,然后最后一个过程将所有“子作业”的输出合并在一起。

一种简单的方法是将数据分成x元素组。问题是最后一个组可能有1个元素的剩余部分,因此它将是一个“noop”。我想找到最佳的“x”,这样组就大致相等,并且每个组中有最小和最大数量的元素(例如,不少于10个元素,不超过20个)

在Ruby中有什么好的算法?

以下是一些示例输出,最小为10,最大为20。这些数字表示每个数组中的元素数。

<number of elements in input> => <subgroup 1>, <subgroup 2>, etc. 

5 => 5
10 => 10
15 => 15
20 => 20
21 => 10, 11
30 => 15, 15
40 => 20, 20
41 => 13, 14, 14
42 => 14, 14, 14
43 => 14, 14, 15
45 => 15, 15, 15
50 => 16, 17, 17
55 => 18, 18, 19
60 => 20, 20, 20
61 => 15, 15, 15, 16

基本上,我想把数组分成大致均匀的组,但是每个组中的元素数量最小和最大。

共有3个答案

卓正业
2023-03-14

以下是我尝试的解决方案:

class ArrayPartition
  def self.partition_lengths(length, minimum, maximum)
    if length <= maximum
      return [length]
    end

    group_size = maximum
    groups = []

    while groups.empty? || groups.last < minimum
      groups = []
      remaining = length
      while remaining > group_size
        groups << group_size
        remaining -= group_size
      end
      groups << remaining
      group_size -= 1
    end

    # Redistribute evenly
    avg_group_size = (length / groups.size.to_f).round
    groups = []
    remaining = length
    while remaining > maximum
      groups << avg_group_size
      remaining -= avg_group_size
    end
    groups << remaining

    groups.sort
  end
end

RSpec测试:

RSpec.describe ArrayPartition do
  it 'partitions an array into optimal groups with min and max elements' do
    expect(ArrayPartition.partition_lengths(5, 5, 10)).to eq [5]
    expect(ArrayPartition.partition_lengths(6, 5, 10)).to eq [6]
    expect(ArrayPartition.partition_lengths(7, 5, 10)).to eq [7]
    expect(ArrayPartition.partition_lengths(10, 5, 10)).to eq [10]
    expect(ArrayPartition.partition_lengths(11, 5, 10)).to eq [5, 6]
    expect(ArrayPartition.partition_lengths(12, 5, 10)).to eq [6, 6]
    expect(ArrayPartition.partition_lengths(13, 5, 10)).to eq [6, 7]
    expect(ArrayPartition.partition_lengths(16, 5, 10)).to eq [8, 8]
    expect(ArrayPartition.partition_lengths(20, 5, 10)).to eq [10, 10]
    expect(ArrayPartition.partition_lengths(21, 5, 10)).to eq [7, 7, 7]
    expect(ArrayPartition.partition_lengths(22, 5, 10)).to eq [7, 7, 8]

    expect(ArrayPartition.partition_lengths(5, 10, 20)).to eq [5]
    expect(ArrayPartition.partition_lengths(10, 10, 20)).to eq [10]
    expect(ArrayPartition.partition_lengths(15, 10, 20)).to eq [15]
    expect(ArrayPartition.partition_lengths(20, 10, 20)).to eq [20]
    expect(ArrayPartition.partition_lengths(21, 10, 20)).to eq [10, 11]
    expect(ArrayPartition.partition_lengths(30, 10, 20)).to eq [15, 15]
    expect(ArrayPartition.partition_lengths(40, 10, 20)).to eq [20, 20]
    expect(ArrayPartition.partition_lengths(41, 10, 20)).to eq [13, 14, 14]
    expect(ArrayPartition.partition_lengths(42, 10, 20)).to eq [14, 14, 14]
    expect(ArrayPartition.partition_lengths(43, 10, 20)).to eq [14, 14, 15]
    expect(ArrayPartition.partition_lengths(45, 10, 20)).to eq [15, 15, 15]
    expect(ArrayPartition.partition_lengths(50, 10, 20)).to eq [16, 17, 17]
    expect(ArrayPartition.partition_lengths(55, 10, 20)).to eq [18, 18, 19]
    expect(ArrayPartition.partition_lengths(60, 10, 20)).to eq [20, 20, 20]
    expect(ArrayPartition.partition_lengths(61, 10, 20)).to eq [15, 15, 15, 16]
  end
end
孙京
2023-03-14

稍有不同的版本:

def divide(c, max = 20)
  groups = (c.to_f / max).ceil
  min_count = (c.to_f / groups).floor

  [min_count + 1] * (c % min_count) + [min_count] * (groups - c % min_count)
end
薛霄
2023-03-14

我会这样处理:

# count of original items
count = 61

# max bucket size
max = 20

# decide buckets
groups = (count / max) + (count % max > 0 ? 1 : 0)

# this will be the final result
result = []

# create buckets
groups.times { result.push(0) }

# iterate over original items and distribute them in the buckets
count.times do |n|
  result[n % groups] += 1
end

p result

给定Count为61,它会打印16, 15, 15, 15。我已经在代码片段中解释了每个语句的目的。

 类似资料:
  • 我正在尝试提出一种算法,用于将团队排序并分配给固定数量的用户。我发现的大多数算法都假设要除以的组数;我想创建一个智能系统,其中组自动分配(尽其最大能力),并根据总用户数以及每个组的最小和最大用户数进行预测。 为每一组假设以下标准: < li >每组最少3个 < li >每组最多6个 < li >基于用户总数的智能分组 以下是基于总用户数和每个组的最小/最大值的一些可能性: 对于24名成员: 4组5

  • 本文向大家介绍JS获取数组最大值、最小值及长度的方法,包括了JS获取数组最大值、最小值及长度的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JS获取数组最大值、最小值及长度的方法。分享给大家供大家参考,具体如下: 希望本文所述对大家JavaScript程序设计有所帮助。

  • 问题陈述: 我需要得到一个给定数字的最佳面额组合。例如:我有三种面额,给定的数字是30,那么列表应该返回

  • 主要内容:普通算法,分治算法程序中,我们经常使用数组(列表)存储给定的线性序列(例如 {1,2,3,4}),那么如何查找数组(序列)中的最大值或者最小值呢? 查找数组(序列)中最大值或最小值的算法有很多,接下来我们以 {3,7,2,1} 序列为例讲解两种查找最值的算法,一种是普通算法,另一种是借助 分治算法解决。 普通算法 普通算法的解决思路是:创建两个变量 max 和 min 分别记录数组中的最大值和最小值,它们的初始值都

  • 问题内容: 是否有一种“计算”快速的方法来获取迭代器的数量? …似乎浪费了CPU周期。 问题答案: 如果您只有迭代器,那么这就是您要做的-它不 知道 还有多少项目要迭代,因此您无法查询该结果。有一些实用程序方法似乎可以做到这一点(例如Guava中的方法),但是在它们的下面仅执行大致相同的操作。 但是,许多迭代器来自集合,您通常可以查询集合的大小。如果它是用户制作的类,那么您要为其提供迭代器,则可以

  • 子数组包含正数和负数。你必须找到一个最大和子数组,使子数组的长度大于或等于k。 下面是我用C++编写的使用Kadane算法的代码。 我的代码工作得很好,但很慢,我想不出任何方法来改进我的代码。我也读过这个问题,找到最长的子数组,它的和可以被K整除,但这不是我想要的,长度也可以大于K。