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

时间:2015-01-26 08:29:16

标签: excel vba excel-vba solver

虽然我熟悉excel,但我并不熟悉excel的所有功能和数据工具。我的问题是我在电子表格上有一个数字,它是列表中许多不同数字的组合。

例如:

  

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

     

答案是500,200,100

在我的头脑中用简单的数字做一个简短的清单并不难,但我正在处理超过1500个货币单元($ xxxx.xx),它们总计(而不是全部使用,所以{ {1}}无用) - 我需要了解哪些数字用于创建总数(哪个不是公式,它是硬编码的数字)。

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

在我深入挖掘并开始自己编写蛮力算法之前,我只想知道。

======

编辑:我创建的解决方案,附在

下面

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

感谢所有贡献的人!

4 个答案:

答案 0 :(得分:4)

您可以在Excel中使用SOLVER来获得结果。

您可以在ADD-INS中激活它,它应该显示在DATA标签中。

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

在一列中您有要查看的数字列表 下一列全为零(0) 第三列是First * Second(例如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 您正在寻找确切的值(输入800)

通过更改cels:在第二列中选择零范围

添加其他限制(add按钮): 零范围必须为>= than 0<= 1int所以我们只有0和1可能的结果 (每次添加其他限制时都必须重新选择范围)

现在按solve并在一段时间后(取决于数据集的范围从几秒到几分钟),它会将一些零更改为1,表示用于生成结果的数字。

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

以下是我得到的结果:

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

答案 1 :(得分:2)

帮助正在进行中。

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

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. 硬币或账单必须按降序排列
  2. 我的最终结果: enter image description here

答案 2 :(得分:0)

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

首先,我找到了一些vba,可以让你创建无限的二进制字符串(而不是Excel内置的9位)。然后,我使用此代码为此目的创建一个UDF ...因为我正在使用20-40&#34; bit&#34;的块,所以这是绝对必要的。

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

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

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

100%的时间,如果给出干净的数据,则会找到解决方案(如果存在)。 (大多数时间是一个因素,因为这是一个指数函数,所以你拥有的位越多,循环它们所需的时间就越长)

这在4分钟内达到约300万种组合,根据一些因素给予或接受

我重新编写了工作表,并通过使 5 列增加了一倍,每列增加1,并使计数器增加5(而不是1)。

答案 3 :(得分:0)

我一直在使用Windows应用程序来执行此操作。我接近一个我认为能满足大多数人需求的解决方案。

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

列表中的25个数字约为3300万种组合。 列表中的50个数字是数百万个组合。 因此,对于大多数人来说,在vba中执行此操作可能不是一个可行的选择,并且求解者也不会很好地处理这个问题。

蛮力不起作用,因为如果您正在执行超过2到3打数字的列表,那么组合太多了。