分数最小的分配

时间:2017-01-13 06:20:18

标签: python math scipy mathematical-optimization combinatorics

假设我们有多个元素E和多个集S

我们需要将元素分配给集合,以便:

  1. 所有集合大致包含相同数量的元素(最小值 最小和最大集之间的集合大小差异)
  2. 每组的元素数量应尽可能少。
  3. 需要将每个元素分配给至少总数的最小百分比集合。为每个元素指定了这个%(这个 意味着元素当然要分配给多个集合 相应地)
  4. 注意(1)和(2)是问题目标,在某些情况下,它们之间存在权衡。我正在有效地寻找一种参数化这种权衡的数学公式/解决方案。同时(3)只是一个问题约束。

    我们如何找到最佳分配?这个问题在文献中有名字吗?如果它很重要,我特意在Python中寻找解决方案。

    例如,假设我们有3组和10个元素,每个元素都指定了 min。组的分数,如下所示:

    0     97.844356
    1     48.006223
    2     99.772135
    3     16.899074
    4      0.111023
    5      1.028894
    6      5.315590
    7    100.000000
    8     99.838698
    9     93.323315
    

1 个答案:

答案 0 :(得分:2)

您可以在集合上无限旋转,以确定要分配的下一个集合。然后,为每个元素计算应分配给它的集合数,然后相应地进行分配:

from itertools import cycle
from math import ceil

elems = [
    [0, 97.844356],
    [1, 48.006223],
    [2, 99.772135],
    [3, 16.899074],
    [4, 0.111023],
    [5, 1.028894],
    [6, 5.315590],
    [7, 100.000000],
    [8, 99.838698],
    [9, 93.323315]
]

def assign(elements, n):
    sets = [[] for _ in range(n)]
    gen = (e for e, p in elements for _ in range(ceil(p*n/100)))

    for s, e in zip(cycle(sets), gen):
        s.append(e)

    return sets

print(assign(elems, 3))

输出:

[[0, 1, 2, 4, 7, 8, 9], [0, 1, 2, 5, 7, 8, 9], [0, 2, 3, 6, 7, 8, 9]]

在上面cycle用于在目标集上无限迭代。 gen是一个生成器,它根据概率返回要添加的最少元素数量:

>>> n = 3
>>> gen = (e for e, p in elems for _ in range(ceil(p*n/100)))
>>> list(gen)
[0, 0, 0, 1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9]

最后zip用于生成(target set, element)个元组,然后在循环中分配。