为资产A,B,C,D构建投资组合资产分配器,并希望将其扩展为n
资产。有四个资产,可以运行四个嵌套循环。问题是创建n个嵌套循环,然后应用下面详述的约束和中间嵌套,它将数组分配给当前资产分布。约束是(A + B + C + ... + n)<> 100即所有资产的100%分配。
资产步长是任意的(5或1),但每个n
资产都有最小和最大界限。
资产总和为100约束会导致许多迭代失败。
在这个问题中有趣的是,AllocArray需要每个{A,B,C,...,nAsset}的位置,即每个嵌套循环的位置。我认为这是一个令人兴奋的难题。
下面是nAssets = 4,即{A,B,C,D}:
MinMaxStepParam = Range("A1:C4")
Min Max Step
A 5 100 5
B 5 100 5
C 5 100 5
D 5 100 5
Dim Sim As Long: Sim = 1
Dim AllocArray() As Variant
ReDim AllocArray(1 To nSim, 1 To nAsset + 1)
Dim A As Double
Dim B As Double
Dim C As Double
Dim D As Double
For A = AMin To AMax Step AStep
For B = BMin To BMax Step BStep
'If (A + B) > 100 Then GoTo endB ' not required as middle nest bound catches all
For C = CMin To CMax Step CStep
'If (A + B + C) > 100 Then GoTo endC ' ditto
For D = DMin To DMax Step DStep
'Constraints
If (A + B + C + D) <> 100 Then GoTo endD
Debug.Print Sim; A; B; C; D
AllocArray(Sim, 1) = Sim
AllocArray(Sim, 2) = A
AllocArray(Sim, 3) = B
AllocArray(Sim, 4) = C
AllocArray(Sim, 5) = D
Sim = Sim + 1
endD:
Next D
endC:
Next C
endB:
Next B
Next A
PrintArray AllocArray, ActiveWorkbook.Worksheets("Output").[A1]
Sub PrintArray(Data As Variant, Cl As Range)
Cl.Resize(UBound(Data, 1), UBound(Data, 2)) = Data
End Sub
我已将其作为动态循环生成,但存在错误。 VBA可以使用数组位置处理循环的最小值,最大值和步长吗?还有其他选择吗?
Sub ConfigureArrayDylan()
Dim Param() As Variant: Param = Range("M3:O6") ' a 4x3 with...Min Max Step... {5 100 5; 5 100 5; 5 100 5; 5 100 5}.
Dim nAsset As Long: nAsset = UBound(Param) ' Count {A, B, ... , D } = 4
Debug.Print nAsset
Dim Asset As Double
Dim Value As Double
Dim Sim As Long: Sim = 1
Dim nSim As Long: nSim = 1
Dim nSimStep As Long
For i = 1 To nAsset Step 1
nSimStep = (1 + (Param(i, 2) - Param(i, 1)) / Param(i, 3)) '(1 + (AMax - AMin) / AStep) *
Debug.Print i; nSimStep
nSim = nSim * nSimStep
Next i
Debug.Print nSim
Dim AllocArray() As Variant
ReDim AllocArray(1 To nSim, 1 To nAsset + 1)
For Asset = 1 To nAssets Step 1
For Value = Param(Asset, 1) To Param(Asset, 2) Step Param(Asset, 3)
Debug.Print Value; ' FAILURE HERE
AllocArray(Sim, Asset) = Value
Sim = Sim + 1
Next Value
Next Asset
Debug.Print Sim;
PrintArray AllocArray, ActiveWorkbook.Worksheets("Test").[L18]
'Range("D30").Resize(NumRows, NumCols).Value = AllocArray
End Sub