Algorithm 具有固定截止的子阵列的最大和

Algorithm 具有固定截止的子阵列的最大和,algorithm,Algorithm,我有一个整数列表,我需要找到一种方法来获得其中一个子集的最大和,将元素添加到总数中,直到和等于(或大于)一个固定截止点。我知道这看起来很像背包,但我不确定它是否等效 排序数组并添加最大元素直到sum首先在任何sum中,最后添加最大元素不会产生更糟糕的结果。因此,作为第一步,假设元素从最小到最大进行排序是无害的 现在我们使用一种类似于通常的子集和的动态规划方法 def best_cutoff_sum (cutoff, elements): elements = sorted(element

我有一个整数列表,我需要找到一种方法来获得其中一个子集的最大和,将元素添加到总数中,直到和等于(或大于)一个固定截止点。我知道这看起来很像背包,但我不确定它是否等效


排序数组并添加最大元素直到sum首先在任何sum中,最后添加最大元素不会产生更糟糕的结果。因此,作为第一步,假设元素从最小到最大进行排序是无害的

现在我们使用一种类似于通常的子集和的动态规划方法

def best_cutoff_sum (cutoff, elements):
    elements = sorted(elements)
    sums = {0: None}
    for e in elements:
        next_sums = {}
        for v, path in sums.iteritems():
            next_sums[v] = path
            if v < cutoff:
                next_sums[v + e] = [e, path]
        sums = next_sums
    best = max(sums.keys())
    return (best, sums[best])

print(best_cutoff_sum(15, [6, 5, 4, 4, 4, 3, 2, 2, 1]))
def最佳截止和(截止,元素):
元素=已排序(元素)
总和={0:None}
对于元素中的e:
下一个_和={}
对于v,路径为sums.iteritems():
下一个_和[v]=路径
如果v<截止值:
下一步求和[v+e]=[e,路径]
总和=下一个总和
最佳=最大值(sums.keys())
回报(最佳,总和[最佳])
打印(最佳截止和(15[6,5,4,4,4,3,2,2,1]))
只需做一点工作,就可以将当前嵌套数组的路径转换为所需的任何格式


如果你的非负元素列表有
n
个元素,你的截止值是
c
,你的最大值是
v
,那么这个算法需要时间
O(n*(k+v))

这与一般情况下的背包问题不完全相同,因为(用背包问题的术语)你知道在你的问题中,每个元素的权重等于其值。然而,你的问题仍然是NP难的,因为它解决了问题。所以你找不到比这更有效的了。我觉得描述有点不清楚。是否希望子集的总和大于或等于截止值,但元素数最少?否。我可以根据需要使用任意数量的元素,但只能添加元素,直到总和等于或大于截止值。所以,加上4,4,4,和2就得到了14,但我们还不到15,所以我们可以加上最大的元素,6。
def best_cutoff_sum (cutoff, elements):
    elements = sorted(elements)
    sums = {0: None}
    for e in elements:
        next_sums = {}
        for v, path in sums.iteritems():
            next_sums[v] = path
            if v < cutoff:
                next_sums[v + e] = [e, path]
        sums = next_sums
    best = max(sums.keys())
    return (best, sums[best])

print(best_cutoff_sum(15, [6, 5, 4, 4, 4, 3, 2, 2, 1]))