Скажем, у меня есть набор чисел, и я хочу суммировать их, чтобы они соответствовали когортам на основе заранее определенного распределения. Простым примером будет, если совокупное количество набора чисел равно 100, а распределение равно 0,2, 0,3, 0,5 для когорт 1,2 и 3 соответственно, тогда я бы хотел найти подмножество чисел, сумма которых равна 20, другое уникальное подмножество, сумма которого равна 30, и последнее уникальное подмножество, сумма которого равна 50. Очевидно, что оно не обязательно должно быть точным, оно просто должно достаточно близко соответствовать распределению.
У меня есть способ в vba, в котором я могу использовать надстройку решателя, чтобы найти лучший способ взять подмножество чисел в наборе чисел и приблизиться (скажем, в пределах 3000) к заранее определенному распределению. Это включает использование суперпродукта с ограничением двоичного 0,1 и списка чисел, а затем поиск разницы между общей суммой, требуемой в этой когорте, и описанным суппродуктом.
Как только это будет сделано, любое число в этом подмножестве будет удалено, и мы выполним метод решателя с сокращенным подмножеством. Я приложил изображение эволюции процедуры, которое, я надеюсь, понятно, цвета соответствуют итерации. Первая (зеленая) итерация, у нас есть полный список, и переменные, которые меняются, - это переменные в соответствующем зеленом столбце, содержащем 0/1, чтобы получить сумму, близкую к 142 449,09
Обратите внимание, что в этом примере сумма полного списка: 1 424 490,85.
![enter image description here](https://i.stack.imgur.com/0GxKb.png)
Линия «Разница» является решающей задачей, и после каждой итерации целью является сдвиг столбца вправо. (Я установил его так, чтобы, если разница была в пределах 1000, тогда она отображала ноль - как это казалось, чтобы ускорить метод). Имитация - это то, что рассчитывается по соответствующему цветному субпродукту, а теоретическая - это просто вероятность, умноженная на общую сумму всех чисел.
![enter image description here](https://i.stack.imgur.com/XItL5.png)
Я приложил приведенный ниже код, но на самом деле этот метод не эффективен по времени, особенно если мне приходится делать это по нескольким наборам данных, что является реальной проблемой. Я хотел бы иметь возможность перевести этот проект на более эффективный язык, такой как R (с которым у меня был опыт - хотя и не в высшей степени), так как я считаю, что он мог бы сделать этот процесс быстрее и эффективнее?
Я также знаю, что в моем алгоритме есть недостатки, так как некоторые из более поздних когорт будут не такими точными, как мы наблюдаем меньший набор данных. Похоже, что в сумму суммы включены нули, чего я не хочу (см. Серую колонку). Также я хочу, чтобы все числа использовались, и иногда число будет опущено, поскольку его включение означает, что оно находится далеко от теоретического распределения. Я не уверен, как сделать вышеупомянутое, поэтому я был бы признателен за некоторые советы по этому вопросу.
Кто-нибудь делал такое в R?
Я также понимаю, что это может быть проблемой для Cross Validated - я действительно не был уверен, поэтому не стесняйтесь двигаться. Я приложил код и таблицы в текстовой форме ниже.
Заранее спасибо,
Sub solversimple()
Dim wb As Workbook
Dim ws As Worksheet
Dim rCell, rIter, rSum
Dim i as Integer
Set wb = Application.ThisWorkbook
Set ws = wb.Sheets("Output")
For i = 1 To 5
rCell = ws.Range("q8").Offset(0, i - 1).Address
rChange = ws.Range("h4:h36").Offset(0, i - 1).Address
rSum = ws.Range("I5:I39").Offset(0, i - 1).Address
solverreset
SolverOk SetCell:=rCell, MaxMinVal:=2, ValueOf:=0, ByChange:=rChange, _
Engine:=3, EngineDesc:="Evolutionary"
SolverAdd CellRef:=rChange, Relation:=5, FormulaText:="binary"
SolverAdd CellRef:=rSum, Relation:=5, FormulaText:="binary"
SolverSolve True
Next i
End Sub
Full List List after 1st It List after 2nd List after 3rd List after 4th 1 2 3 4 5
49000.21 49000.21 49000.21 49000.21 49000.21 0.00 0.00 0.00 0.00 1.00
51591.99 51591.99 51591.99 51591.99 51591.99 0.00 0.00 0.00 0.00 1.00
18390.18 18390.18 0.00 0.00 0.00 0.00 1.00 1.00 0.00 1.00
45490.39 45490.39 45490.39 45490.39 45490.39 0.00 0.00 0.00 0.00 1.00
37506.41 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 1.00
1460.11 1460.11 1460.11 0.00 0.00 0.00 0.00 1.00 1.00 0.00
136564.86 136564.86 136564.86 136564.86 0.00 0.00 0.00 0.00 1.00 1.00
41581.29 0.00 0.00 0.00 0.00 1.00 0.00 1.00 0.00 0.00
6138.26 6138.26 6138.26 0.00 0.00 0.00 0.00 1.00 0.00 0.00
23831.37 23831.37 23831.37 23831.37 0.00 0.00 0.00 0.00 1.00 1.00
4529.44 4529.44 0.00 0.00 0.00 0.00 1.00 1.00 1.00 1.00
1291.53 1291.53 1291.53 0.00 0.00 0.00 0.00 1.00 0.00 0.00
1084.88 1084.88 1084.88 0.00 0.00 0.00 0.00 1.00 0.00 0.00
33516.76 33516.76 0.00 0.00 0.00 0.00 1.00 0.00 1.00 0.00
43393.83 43393.83 0.00 0.00 0.00 0.00 1.00 1.00 0.00 0.00
81000.69 81000.69 81000.69 0.00 0.00 0.00 0.00 1.00 0.00 0.00
25397.64 25397.64 0.00 0.00 0.00 0.00 1.00 0.00 0.00 1.00
29473.54 29473.54 29473.54 0.00 0.00 0.00 0.00 1.00 1.00 1.00
39097.70 0.00 0.00 0.00 0.00 1.00 0.00 0.00 1.00 1.00
59669.99 59669.99 0.00 0.00 0.00 0.00 1.00 1.00 1.00 1.00
18639.97 18639.97 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00
97198.13 97198.13 97198.13 0.00 0.00 0.00 0.00 1.00 0.00 1.00
5558.69 5558.69 0.00 0.00 0.00 0.00 1.00 1.00 1.00 0.00
16298.63 16298.63 0.00 0.00 0.00 0.00 1.00 0.00 1.00 1.00
67621.61 67621.61 67621.61 0.00 0.00 0.00 0.00 1.00 0.00 0.00
69388.09 69388.09 0.00 0.00 0.00 0.00 1.00 1.00 1.00 0.00
193524.89 193524.89 193524.89 193524.89 0.00 0.00 0.00 0.00 1.00 1.00
12455.61 0.00 0.00 0.00 0.00 1.00 1.00 0.00 0.00 1.00
7261.88 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00
77879.68 77879.68 0.00 0.00 0.00 0.00 1.00 1.00 0.00 1.00
53891.97 53891.97 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00
70602.68 70602.68 70602.68 70602.68 70602.68 0.00 0.00 0.00 0.00 1.00
4157.96 0.00 0.00 0.00 0.00 1.00 1.00 1.00 0.00 1.00
Cohort 1.00 2.00 3.00 4.00 5.00
Probability 0.10 0.30 0.20 0.25 0.15
Theoretical 142449.09 427347.26 284898.17 356122.71 213673.63
Simulated 142060.85 426554.86 285268.75 353921.12 216685.28
Difference 0.00 0.00 0.00 2201.59 3011.65