我的任务是帮助一些会计师解决他们遇到的一个常见问题-给定交易清单和总存款,哪些交易是存款的一部分?例如,说我有这个数字列表:
1.00 2.50 3.75 8.00
而且我知道我的总存款是10.50,我可以很容易地看出这是由8.00和2.50交易组成的。但是,考虑到一百笔交易和几百万笔存款,很快就会变得困难得多。
10.50
8.00
2.50
在测试蛮力解决方案(花费太长的时间才能付诸实践)时,我有两个问题:
在大约60个数字的列表中,似乎可以找到十二个或更多组合来构成任何合理的总数。 我期望单个组合可以满足我的全部需求,或者可能会满足一些可能性,但是似乎总是有很多组合。 有没有数学原理可以描述为什么?似乎给定了即使是中等大小的随机数集合,您也可以找到多个组合,这些组合加起来几乎等于您想要的总数。
我为该问题构建了一个蛮力解决方案,但显然是O(n!),并且很快就失去了控制。除了明显的捷径(排除大于总数的数字)之外,还有没有办法缩短计算时间的方法?
我当前(超慢)解决方案的详细信息:
明细金额列表按最大到最小排序,然后以下过程递归运行:
这样,它可以快速排除较大的数字,从而将列表缩减为仅需要考虑的数字。但是,它仍然是n!而且更大的列表似乎从未完成,因此我对加快速度可能会遇到的任何捷径感兴趣- 我怀疑即使从列表中删减1个数字也可以将计算时间缩短一半。
谢谢你的帮助!
背包问题的这种特殊情况称为子集和。