【问题标题】:Algorithm - Group/sort list to maximize minimum average group value算法 - 分组/排序列表以最大化最小平均分组值
【发布时间】:2016-01-24 21:58:29
【问题描述】:

我正在寻求一些帮助,以便在 Python 中编写一个完成以下任务的算法:

给定一个实数列表,将该列表排序/分组为 n 个较小的列表,以使平均最小组值最大化。

例如,考虑将下面的列表分为两个列表 - A 和 B,每个列表包含两个元素。

lis = [1,1,2,2]

在下面的第一个场景中,每个列表的最小值为 1,因此平均最小值为 1。

# Scenario 1
A = [1,2]
B = [1,2]

# Scenario 2
A = [1,1]
B = [2,2]

在第二种情况下,A 的最小值为 1,B 的最小值为 2,因此平均最小值为 1.5。这种安排是最优的。

很明显,最好将“相似”的值分组。我可以用Jenks natural breaks optimization(或一维k-means聚类)来做到这一点。但是,我不确定我的目标和 Jenks 优化的目标是否(数学上)等价。

任何帮助或意见将不胜感激。

编辑:较小的列表必须全部具有相同的大小(假设给定的列表总是分成较小的组,没有余数)。

【问题讨论】:

  • 较小的列表是否都必须具有相同的大小?
  • 是的,确实如此。对不起,我应该这么说的。
  • 对对象进行排序。根据需要切片。这会产生最佳解决方案 - 但您可能一直在问错误的问题。
  • 是的,您只需对列表进行排序,然后将其切片。要将其分成 n 个子列表,每个子列表有 m 个元素,请将最小的 m 放入一个子列表中,将下一个最小的 m 放入另一个子列表中,等等。

标签: python algorithm sorting optimization


【解决方案1】:

解决此问题的最佳方法是将数字从小到大排序,然后将排序后的列表拆分为n 组,而无需进一步重新排列。任何改进此分组的尝试都会降低其中一组的最小值,从而降低最小值的平均值。

一个例子可能有助于解释原因。

给定一个包含 12 个数字的列表:

[94, 82, 61, 2, 96, 34, 87, 13, 82, 91, 61, 39]

排序后的列表是:

[2, 13, 34, 39, 61, 61, 82, 82, 87, 91, 94, 96]

如果我们想要n=3 组,那么这些组是:

[[2, 13, 34, 39], [61, 61, 82, 82], [87, 91, 94, 96]]

所以最小值的平均值是avg(2,61,87)=50

你能做得比这更好吗?答案是否定的。

将任意数从一组 A 移动到另一组 B 将减少 A 的最小值,而不会相应地增加 B 的最小值。

例如,您可能认为将 61 转移到不同的组会有所帮助。

一种可能的重新排列是:

[[2, 13, 34, 61], [39, 61, 82, 82], [87, 91, 94, 96]]

此重排的值为avg(2,39,87)=42

另一种可能的重新排列是:

[[2, 13, 34, 39], [87, 61, 82, 82], [61, 91, 94, 96]]

此重排的值为avg(2,61,61)=41

所以你看,我们不能通过移动 61 来做得更好。同样,我们不能通过移动任何数字来做得更好。

【讨论】:

    【解决方案2】:

    似乎最简单的方法是对列表进行初始排序,以便始终将最低值分组在一起,例如:

    # Define the list of values to group
    values = [1, 2, 3, 10, 11, 12]
    
    # Sort the values
    values.sort()
    
    # Split the values down into an even number of `n` groups
    no_groups = 3
    group_size = len(values) / no_groups
    groups = []
    
    for i in range(0, no_groups):
        groups.append(values[0:(group_size)])
        values = values[group_size:]
    
    # Calculate the average minimum value of the groups
    average_min = float(sum([g[0] for g in groups])) / no_groups
    
    print(average_min)
    

    但是鉴于您提到 Jenks 和 K-means 聚类,我担心这太简单了,而且我遗漏了一些东西?

    【讨论】:

    • 我认为你是对的,这个问题没有多大意义,因为它归结为排序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多