是否有一个Excel函数来查找数字的组合

我不熟悉excel的所有function和数据工具,尽pipe我对excel很熟悉。 我的问题是,我在电子表格上有一个数字,它是列表中许多不同数字的组合。

例如:

一个列表包含:100,200,250,500和1000,我需要解释的数字是:800

答案是500,200,100

在我的脑海中用简单的数字做一个简单的列表并不困难,但是我处理了超过1500个货币单元格($ xxxx.xx),这些货币单元格总数( 并不是全部使用,所以SUM没用 ) – 我需要了解哪些数字用于创build总数( 这不是一个公式,这是一个硬编码的数字 )。

问题:是否有一个函数或VBA系统地将给定范围内的数字组合在一起,直到确定哪些数字可以加在一起构成总数?

我只是想在挖掘之前就知道,自己开始编写一个蛮力algorithm。

========

编辑:我创build的解决scheme,附在下面

链接到我为此创build的文件: https : //drive.google.com/file/d/0B8nE67gSOkewWXR2WnRuQTc2MEU/view?usp =分享

谢谢大家谁贡献!

你可以在excel中使用SOLVER来得到结果。

你可以在ADD-INS激活它,它应该显示在DATA选项卡中。

您可以像这样设置电子表格:

在一列你有数字列表你想检查下一列是全零(0)第三列是第一*第二(例如100 * 0),所以在开始时它的所有行的零

比你添加第三列的总结,它也应该是零。 举例说明这些数据的外观如何:

 100 0 0 200 0 0 500 0 0 50 0 0 60 0 0 80 0 0 120 0 0 90 0 0 TOTAL 0 

现在,您运行solver表单data选项卡,并获取您必须提供参数的接口:

目标值是所有乘法和的CELL值您正在查找确切值(input800)

通过更改cels:在第二列中select零的范围

添加三个附加的限制( addbutton):零的范围必须>= than 0<= 1 >= than 0 <= 1 ,因此我们只有0和1的结果(每次添加另一个限制时都必须重新select范围)

现在按solve ,一段时间后(取决于你的数据集的范围从几秒到几分钟),它会改变一些零到1,指示哪些数字在哪里用来产生你的结果。

如果有很多可能的结果,它会select一个他没有发现有更多的结果,但再次运行它可能会产生不同的结果。

这是我得到的结果:

 100 1 100 200 0 0 500 1 500 50 0 0 60 0 0 80 1 80 120 1 120 90 0 0 TOTAL 800 

帮助正在进行中。

您可以将此function粘贴到模块中并根据需要进行调整。

 Function GetCombination(CoinsRange As Range, SumCellId As Range) As String Dim Nb As Integer Dim Com As String Dim Sum As Double Dim r As Range Set r = CoinsRange Sum = SumCellId.Value For Each cell In r.Cells If Sum / cell.Value >= 1 Then Com = Com & Int(Sum / cell.Value) & " of " & cell.Value & " " Sum = Sum - (Int(Sum / cell.Value)) * cell.Value End If Next GetCombination = Com End Function 

前提条件:

  1. 硬币或帐单必须按降序排列

我的最终结果: 在这里输入图像说明

好的,找出最适合我的解决scheme:

首先 ,我发现一些vba可以让你创build无限的二进制string(而不是Excel内置的9位)。 然后,我使用这个代码为此创build一个UDF …因为我正在处理20-40“比特”的块,所以这是绝对必要的。

其次 ,我做了一个增加了1的计数器循环,然后改变二进制串来反映新的数字。 (1,10,11,100,101,110,111等)

第三 ,我写了一个公式,将二进制string分开,并将每个1或0分配给相邻的单元格中的相应数字。 (只需使用LEN()RIGHT()MID()函数来识别1和0)。

第四 ,我将每个值乘以它旁边的1或0,然后将所有相乘的数字的总和与我正在查找的目标值进行比较。

100%的时间,如果给予干净的数据,这find了一个解决scheme,如果存在的话。 (大部分时间是一个因素,因为这是一个指数函数,所以你有更多的位,循环它们需要的时间越长)

这在4分钟内运行约300万组合,取决于几个因素

我redid的工作表,并加倍了5列,每增加一个,并使计数器增加5(而不是1)的速度。

我一直在做一个Windows应用程序来做到这一点。 我接近一个我认为能够满足大多数人需求的解决scheme。

组合的数量是大多数algorithm的问题,因此关键是尽可能多地忽略不可行的组合。

列表中的25个数字大约是3300万个组合。 列表中的50个数字是一百万个组合。 所以,用vba这样做对大多数人来说可能不是一个可行的select,解决者也不会很好地处理这个问题。

蛮力不起作用,因为如果你正在做一个超过2到3打数字的列表,组合太多了。