Abstract
Mit Excel/VBA kann man recht einfach eine Monte Carlo Simulation erzeugen, aber man sollte einige mögliche Fallstricke umgehen:
- Verwende die Klasse SystemState, um das Programm durch Ausschalten von ScreenUpdating und durch Setzen der Calculation auf xlCalculationManual zu beschleunigen.
- Halte den Anwender über den Prozess der Simulation auf dem Laufenden.
- Behandle unbekanntes Dimensionswachstum während des Programms effizient.
- Sei Dir bewusst, dass Excel im Allgemeinen nicht das beste (nicht das schnellste) Simulationstool ist.
Literatur
Ab Excel 2010 scheint es ok zu sein, Excel für Monte Carlo Simulationen zu verwenden, wenn es nicht zu langsam ist:
(Externer Link!) Alexei Botchkarev, Assessing Excel VBA Suitability for Monte Carlo Simulation
Appendix – Programmcode sbMonteCarloSimulation
Bitte beachten: Dieses Programm benötigt (verwendet) die Klasse SystemState.
Bitte den Haftungsausschluss im Impressum beachten.
Option Explicit
Sub Simulate()
'Creates a simple Monte Carlo simulation by counting how long
'it takes to throw a 3 with a die with 10 surfaces (likelihood
'for each to show is 1/10).
'Source (EN): http://www.sulprobil.com/sbmontecarlosimulation_en/
'Source (DE): http://www.bplumhoff.de/sbmontecarlosimulation_de/
'(C) (P) by Bernd Plumhoff 23-Nov-2022 PB V0.2
Dim i As Long
Dim lSimulations As Long
Dim lTries As Long
Dim state As SystemState
With Application.WorksheetFunction
Set state = New SystemState
Randomize
lSimulations = Range("Simulations")
ReDim lResult(1 To 1) As Long 'Error Handler will increase as needed
On Error GoTo ErrHdl
For i = 1 To lSimulations
If i Mod 10000 = 1 Then Application.StatusBar = "Simulation " & _
Format(i, "#,##0") 'Inform the user that program is still alive
lTries = 0
Do
lTries = lTries + 1
Loop Until .RandBetween(1, 10) = 3 'This is the simulation
lResult(lTries) = lResult(lTries) + 1
Next i
On Error GoTo 0
Range("D:F").ClearContents
Range("D1:F1").FormulaArray = Array("3 showed up after this many throws", _
"How often", "Theoretical Value (rounded)")
For i = 1 To UBound(lResult)
Cells(i + 1, 4) = i
Cells(i + 1, 5) = lResult(i)
lTries = .Round(lSimulations * 0.1, 0)
Cells(i + 1, 6) = lTries
lSimulations = lSimulations - lTries
Next i
End With
Exit Sub
ErrHdl:
If Err.Number = 9 Then
'Here we normally get if we breach Ubound(lResult)
If lTries > UBound(lResult) Then
'So we need to increase dimension
ReDim Preserve lResult(1 To lTries)
Resume 'Back to statement which caused error
End If
End If
'Other error - terminate
On Error GoTo 0
Resume
End Sub
Bitte den Haftungsausschluss im Impressum beachten.
sbmontecarlosimulation.xlsm [31 KB Excel Datei, ohne jegliche Gewährleistung]