我一直在寻找一个数学问题的解决方案
我修复了一组数字 [65536,131072,262144,524288,104576,2097152]
我将只有一些以上数字
但我的问题是如何在给定总数中得到数字组合?
请帮帮我PLZ
答案 0 :(得分:1)
我的解决方案与戴维斯非常相似。
假设:这组数字按升序排列。
调用该函数并从最高编号开始,传递一个空的部分解决方案并尝试计算返回总数的所有可能的数字总和。总和作为集合返回。
功能:
numberSetIndex
开始并向下移动):
number > total
然后跳到下一个数字number = total
然后将此部分解决方案添加到列表中并转到下一个数字number < total
那么
total -= number
和部分解决方案的副本,以及当前的数字索引) 注意:我不明白你是否只想使用该组的每个数字一次,所以下面的代码也将计算包含多个数字实例的总和在给定的集合中。
如果您希望每个数字只出现一次,请找到行
Set result = AllSumsForTotalFromSet(total - number, numberSet, index, CopyAndReDimPlus1(partialSolution))
在函数Function AllSumsForTotalFromSet
中,并在递归调用中将index
替换为index-1
。
Sub Test_AllSumsForTotalFromSet()
Dim numberSet, total As Long, result As Collection
numberSet = Array(65536, 131072, 262144, 524288, 104576, 2097152)
total = 366720
Set result = GetAllSumsForTotalFromSet(total, numberSet)
Debug.Print "Possible sums: " & result.count
PrintResult result
End Sub
Function GetAllSumsForTotalFromSet(total As Long, ByRef numberSet As Variant) As Collection
Set GetAllSumsForTotalFromSet = New Collection
Dim partialSolution(1 To 1) As Long
Set GetAllSumsForTotalFromSet = AllSumsForTotalFromSet(total, numberSet, UBound(numberSet), partialSolution)
End Function
Function AllSumsForTotalFromSet(total As Long, ByRef numberSet As Variant, numberSetIndex As Long, ByRef partialSolution() As Long) As Collection
Dim index As Long, number As Long, result As Collection
Set AllSumsForTotalFromSet = New Collection
'break if numberSetIndex is too small
If numberSetIndex < LBound(numberSet) Then Exit Function
For index = numberSetIndex To LBound(numberSet) Step -1
number = numberSet(index)
If number <= total Then
'append the number to the partial solution
partialSolution(UBound(partialSolution)) = number
If number = total Then
AllSumsForTotalFromSet.Add partialSolution
Else
Set result = AllSumsForTotalFromSet(total - number, numberSet, index, CopyAndReDimPlus1(partialSolution))
AppendCollection AllSumsForTotalFromSet, result
End If
End If
Next index
End Function
'copy the passed array and increase the copy's size by 1
Function CopyAndReDimPlus1(ByVal sourceArray As Variant) As Long()
Dim i As Long, destArray() As Long
ReDim destArray(LBound(sourceArray) To UBound(sourceArray) + 1)
For i = LBound(sourceArray) To UBound(sourceArray)
destArray(i) = sourceArray(i)
Next i
CopyAndReDimPlus1 = destArray
End Function
'append sourceCollection to destCollection
Sub AppendCollection(ByRef destCollection As Collection, ByRef sourceCollection As Collection)
Dim e
For Each e In sourceCollection
destCollection.Add e
Next e
End Sub
Sub PrintResult(ByRef result As Collection)
Dim r, a
For Each r In result
For Each a In r
Debug.Print a;
Next
Debug.Print
Next
End Sub
答案 1 :(得分:0)
有趣的思想实验......这是我的解决方案(预警 - 没有代码,只有算法)
您最终应该得到一张代表有效解决方案的树。例如:
set = [50,40,30,20,15,10,5]
total required = 60
Solution tree
root
50 -> 10
40 -> 20
-> 15 -> 5
30 -> 20 -> 10
-> 15 -> 10 -> 5