虽然我熟悉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
感谢所有贡献的人!
答案 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
和<= 1
和int
所以我们只有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
前提条件:
我的最终结果:
答案 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打数字的列表,那么组合太多了。