python - 使用python解决一道数学题: sum up to a value as close as possible

标签 python list math sum

我有一个数字列表。现在,如果我设置一个固定值V,python是否可以将列表分为几组,使得每组的总和不小于V(尽可能多地获取这些组)?

例如:如果列表是 [1,2,3,4,5] 并且 V 是 6,那么结果应该是 [[1,5],[2,3,4]]。分组意味着您不能多次使用同一个原始项目。

每个子列表可以包含的项目数量没有限制,而且数字不按顺序排列(可以是一些随机数)。有人可以帮我吗?到目前为止,我的解决方案是总结所有组合并比较总和。但我很确定应该有更有效的解决方案。谢谢!

我的解决方案:我有点先使用它,然后通过我的想法完成其余的工作,所以它不值得进一步开发。

import itertools
import math

stuff = list(range(10))
v = 6

for L in range(0, len(stuff)+1):
    for subset in itertools.combinations(stuff, L):
        if math.fsum(subset) > v: 
            print(subset,math.fsum(subset))

最佳答案

我的解决方案的时间复杂度为 O(n^2)。您可以按升序对列表进行排序。然后从末尾迭代列表。如果您想要最大数量的子集,则将每个大于 V 的值添加到数组中。在其他情况下,从左右角收集值,同时实现子集之和等于 V:

def get_value_in_dict(d):
    return d.get(list(d)[0])

# Implementation for a list of dictionaries like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}]
def sum_up_to_value(stuff, val):
    new_stuff = []
    sorted_stuff = list(sorted(stuff, key=lambda el: get_value_in_dict(el)))
    n = len(stuff)
    pointer_r = n - 1
    pointer_l = 0
    queue = list()

    while pointer_r >= pointer_l:
        if get_value_in_dict(sorted_stuff[pointer_r]) >= val:
            new_stuff.append([sorted_stuff[pointer_r]])
        else:
            subsum = get_value_in_dict(sorted_stuff[pointer_r])
            substuff = []
            while pointer_l < pointer_r and subsum < val:
                # get from queue
                while len(queue) and subsum < val:
                    temp = queue.pop(0)
                    subsum += get_value_in_dict(temp)
                    substuff.append(temp)
                # get from input
                else:
                    if subsum < val:
                        subsum += get_value_in_dict(sorted_stuff[pointer_l])
                        substuff.append(sorted_stuff[pointer_l])
                        pointer_l += 1
            substuff.append(sorted_stuff[pointer_r])
            # returns back smallest elements
            while subsum - get_value_in_dict(substuff[0]) >= val:
                temp = substuff.pop(0)
                queue.append(temp)
                subsum -= get_value_in_dict(substuff[0])

            if subsum < val:
                # add substuff to last element of new_stuff
                temp = new_stuff.pop()
                new_stuff.append(temp + substuff)
            else:
                new_stuff.append(substuff)
        pointer_r -= 1
    return new_stuff  # list(map(lambda el: sorted(el, key=lambda el_d: get_value_in_dict(el_d)), new_stuff)) for sorted by value elements in resulting list

关于python - 使用python解决一道数学题: sum up to a value as close as possible,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53380134/

相关文章:

python - 非常基本的格式问题

通过数字检查列表中相似性的算法

python 微框架和请求库

python - 从数据中查找峰值

c# - 如何将项目添加到 IEnumerable<T> 集合?

python - python 中的轨迹相交

algorithm - O(1) 在变化的固定大小数组中的最小值

math - 哈希冲突的可能性

python - 找到 3 个具有相同(近似)基尼系数的子样本

list - 如何在 Scala 中展平不同类型的列表?