如何计算总和为给定值的值的倍数?

时间:2019-05-08 03:47:53

标签: python combinations mathematical-optimization

我遇到了一个优化问题,我试图找到合计特定$值的最佳产品数量。必须选择所有项目,并允许重复。例如:

desired total >= 12 and <= 13
hat $3
shoes $5
tie $2

结果可能是:

1 hat, 1 shoes, 2 tie
2 hat, 1 shoes, 1 tie

这是工作而不是家庭作业中的发现问题。我在另一个线程中找到了该解决方案,但无法完全解决该问题。

import itertools
numbers = [1, 2, 3, 7, 7, 9, 10]
result = [seq for i in range(len(numbers), 0, -1) for seq in itertools.combinations(numbers, i) if sum(seq) == 10]
print result

它适用于一堆随机数,但是当我从例如1025并将输入位数更改为浮点数0 < x <= 1.5无效。

非常感谢您对如何进行此工作的任何指导。谢谢

1 个答案:

答案 0 :(得分:0)

让我先澄清您的要求:

  1. 所有项目必须至少选择一次
  2. 找到所有可能的结果总和> = lower_bound和<= upper_bound
  3. 项目可以重复使用
  4. 找到所有组合而不是排列(不在乎顺序)

您可以使用回溯来获取想要的东西:

def find_all(data, lower, upper):
    total = sum([d[1] for d in data])
    lower -= total
    upper -= total      # all items must be selected at least once
    if upper < lower or lower < 0:
        return []

    results = []
    def backtrack(end, lower, upper, path):
        if end < 0: return
        if lower <= 0 <= upper:  # satified the condition
            results.append(path)
            return

        if upper >= data[end][1]:
            new_path = path[:]
            new_path[end] += 1
            backtrack(end, lower - data[end][1], upper - data[end][1], new_path)    # choose the last one
        backtrack(end - 1, lower, upper, path)      # don't choose the last one

    backtrack(len(data) - 1, lower, upper, [1] * len(data))
    return results

测试:

def print_results(results, data):
    for result in results:
        for count, d in zip(result, data):
            print(f'{count}*{d[0]}', end=', ')
        print()
    print()


data1 = [('hat', 3), ('shoes', 5), ('tie', 2)]
print_results(find_all(data1, 12, 13), data1)

data2 = [('hat', 3), ('shoes', 5), ('tie', 2), ('cloth', 10)]
print_results(find_all(data2, 25, 28), data2)

输出

1*hat, 1*shoes, 2*tie, 
2*hat, 1*shoes, 1*tie, 

1*hat, 1*shoes, 4*tie, 1*cloth, 
2*hat, 1*shoes, 3*tie, 1*cloth, 
1*hat, 2*shoes, 2*tie, 1*cloth, 
2*hat, 1*shoes, 2*tie, 1*cloth, 
1*hat, 2*shoes, 1*tie, 1*cloth, 
3*hat, 1*shoes, 1*tie, 1*cloth, 

希望对您有所帮助,如果还有其他问题,请发表评论。 :)