数字组合以适应阈值

时间:2014-09-16 08:15:06

标签: python data-structures

我有一组(或一个列表)的数字{1,2.25,5.63,2.12,7.98,4.77},我想找到这个集/列表中最好的数字组合,当添加时最接近10。

我如何使用集合中的元素在python中实现它?

2 个答案:

答案 0 :(得分:1)

如果问题规模允许,您可以使用itertools中的某些朋友快速通过它:

s = {1, 2.25, 5.63, 2.12, 7.98, 4.77}
from itertools import combinations, chain
res = min(((comb, abs(sum(comb)-10)) for comb in chain(*[combinations(s, k) for k in range(1, len(s)+1)])), key=lambda x: x[1])[0]
print res

输出:

(2.25, 5.63, 2.12)

答案 1 :(得分:0)

这是一个NP-Hard问题。如果您的数据不是太大,您可以使用以下代码测试每个解决方案:

def combination(itemList):
    """ Returns all the combinations of items in the list """
    def wrapped(current_pack, itemList):
        if itemList == []:
            return [current_pack]
        else:
            head, tail = itemList[0], itemList[1:]
            return wrapped(current_pack+[head], tail) + wrapped(current_pack, tail)
    return wrapped([], itemList)

def select_best(combination_list, objective):
    """ Returns the element whose the sum of its own elements is the nearest to the objective"""
    def element_sum(combination):
        result = 0.0
        for element in combination:
            result+= element
        return result

    best, weight = combination_list[0], element_sum(combination_list[0])

    for combination in combination_list:
        current_weight =  element_sum(combination)
        if (abs(current_weight-objective) < abs(weight-objective)):
            best, weight = combination, current_weight

    return best


if __name__ == "__main__" : 
    items = [1, 2.25, 5.63, 2.12, 7.98, 4.77]

    combinations = combination(items)
    combinations.sort()
    print(combinations, len(combinations))#2^6 combinations -> 64

    best = select_best(combinations, 10.0)
    print(best)

无论您提供什么输入,此代码都将为您提供更好的解决方案。但是你可以看到组合的数量是2 ^ n,其中n是列表中元素的数量。尝试使用超过50个元素并告别RAM内存。从算法的角度来看,完全正确,你可以等待比你一生更多的事情,以获得真实案例问题的答案。元启发式和约束满足问题算法可以用于更有效的方法。