Excel中背包的变化

所以,我需要find10个数据点列表的组合总数,加起来至less为100.所有解决这个问题的例子我都find了等于一个数的组合数。 我怎样才能总计高于100的组合? Excel中没有VBA,这是可行的吗?

另一个想法是计算组合总数(10!)并减去1000以下的数字。 但是,又如何find一个范围内的组合总数呢?

问题陈述:10个数据点(65,52,48,44,42,41,39,38,30,18)总共可以有多less个组合至less100个?

我试过的来源(我不能发布超过2个链接) http://www.tushar-mehta.com/excel/templates/match_values/index.html

找出在一个集合中的数字的组合加起来给定的总数

  1. A1J1中input10个项目
  2. K1中input公式=IF(ROW()<512,"0" & DEC2BIN(ROW(),9),"1" & DEC2BIN(ROW()-512,9))
  3. 复制第1行到第1023行
  4. 将列K和PasteSpecialValues复制到列L中
  5. 使用TextToColumns将列Lparsing成列MV
  6. W1中input=SUMPRODUCT((A1:J1)*(M1:V1))并复制下来

W列包含所有可能组合的总和。

最后在另一个单元格中input:

 =COUNTIF(W:W,">=" & 100) 

在这里输入图像说明

编辑#1:

要生成一个36位二进制模式,我使用:

 =DEC2BIN(INT(ROW()/2^27),9)&DEC2BIN(INT(MOD(ROW(),2^27)/2^18),9)&DEC2BIN(INT(MOD(ROW(),2^18)/2^9),9)&DEC2BIN(MOD(ROW(),2^9),9) 

所以对于20位,只需使用:

 =RIGHT(DEC2BIN(INT(ROW()/2^27),9)&DEC2BIN(INT(MOD(ROW(),2^27)/2^18),9)&DEC2BIN(INT(MOD(ROW(),2^18)/2^9),9)&DEC2BIN(MOD(ROW(),2^9),9),20) 

在这里输入图像说明

编辑#2:

要使用VBA执行类似TextToColumns的操作 ,请select单元格并运行此macros:

 Sub PseudoTextToColumns() Dim r As Range, L As Long, i As Long, t As String For Each r In Selection t = r.Text L = Len(t) For i = 1 To L r.Offset(0, i).Value = Mid(t, i, 1) Next i Next r End Sub 

注意:

这不适用于21个项目。

VBA蛮力解决scheme

我会分享下面的蛮力解决scheme,检查所有可能的组合。 对于最多15个条目的小arrays来说,速度足够快。 它解决了您的问题,您可以将其作为任何暴力计算的模型,也可以作为优化和应用更快algorithm的起点。 它也可以作为testing任何优化后的algorithm的基础。

 Option Explicit ' Main function. Computes the all combinations and prints those that exceed the target ' Each combination is specified by a mask of bits that specifies whether to take o to leave the entry Function CombinationsByBruteForce(inputArray() As Double, target As Double) As Long Dim mask As Long, count As Long For mask = 1 To 2 ^ (1 + UBound(inputArray)) - 1 If SumByMask(inputArray, mask) > target Then count = count + 1 PrintByMask inputArray, mask End If Next Debug.Print "Total number of successful combinations: " & count CombinationsByBruteForce = count End Function ' computes the sum for a given combination. The combination is specified by a mask of bits ' that tells which entries belong to the combination (the 1 bits) Function SumByMask(inputArray() As Double, mask As Long) As Double Dim bit As Long For bit = 0 To UBound(inputArray) If (mask And (2 ^ bit)) <> 0 Then SumByMask = SumByMask + inputArray(bit) Next End Function ' Prints out the entries belonging to a combination specified by a mask Sub PrintByMask(inputArray() As Double, mask As Long) Dim bit As Long For bit = 0 To UBound(inputArray) If (mask And (2 ^ bit)) <> 0 Then Debug.Print inputArray(bit), Next Debug.Print End Sub 

 ' For testing. An array of doubles and a target are specified. ' The variant array is copied into a Double array to improve speed Sub testing() Dim target As Double: target = 350 ' target number to exceed Dim test: test = Array(65, 52, 48, 44, 42, 41, 39, 38, 30, 18) 'convert to explicit array of Double ReDim inputArray(UBound(test)) As Double Dim i As Long For i = LBound(test) To UBound(test): inputArray(i) = test(i): Next ' Launsh the brute force computation CombinationsByBruteForce inputArray, target End Sub 

上述testing的输出

  65 52 48 44 42 41 39 38 65 52 48 44 42 41 39 30 65 52 48 44 42 41 38 30 65 52 48 44 42 39 38 30 65 52 48 44 41 39 38 30 65 52 48 42 41 39 38 30 65 52 44 42 41 39 38 30 65 52 48 44 42 41 39 38 30 65 52 48 44 42 41 39 38 18 65 52 48 44 42 41 39 30 18 65 52 48 44 42 41 38 30 18 65 52 48 44 42 39 38 30 18 65 52 48 44 41 39 38 30 18 65 52 48 42 41 39 38 30 18 65 52 44 42 41 39 38 30 18 65 48 44 42 41 39 38 30 18 52 48 44 42 41 39 38 30 18 65 52 48 44 42 41 39 38 30 18 Total number of successful combinations: 18 

作为求解器的入口点,您可以尝试一个BIP模型,其中决策variables是掩码的位。 求解器应该应用一些分支和界限或类似的技术来find一个组合。 但是用解算器打印出所有成功的组合似乎要困难得多,因为这不是一个优化问题。