2017-07-06 6 views
2

Ich versuche, einen Baseball-Post-Saison-Simulator zu erstellen, um zu sehen, wie sehr ein schlechter Pitcher die Gewinnchancen eines Teams beeinflusst. Also habe ich im Grunde genommen einen Simulator für die Playoffs erstellt (3 Runden, die erste ist die beste von 5, die nächsten beiden sind die beste von 7). Und ich kann sehen, wie sehr ein SP dem Team schaden würde, wenn er jedes dritte Spiel schlägt und die Gewinnchance um 10% verringert.VBA Zufallszahl in Simulation

Um sicherzustellen, dass ich dies geschrieben habe, habe ich zuerst meine Simulation ohne jegliche Anpassung durchgeführt, so dass jedes Team eine 50% ige Gewinnchance hätte ... (ein Team hätte also eine 12,5% Chance, die Welt zu gewinnen Serie in einem 3 Runde Playoff), aber ich wurde konstant höher als 12,5.

Ich habe das Gefühl, das Problem war mit der Rnd-Funktion, also spielte ich damit ein bisschen (fügte eine Funktion hinzu, versuchte, die Zeit ect.), Jetzt kommt meine Simulation < 12.5% ​​heraus. Ich habe dann versucht, Probleme zu machen und habe bemerkt, dass in jeder Runde nicht 50% der Zeit gewonnen wurde ... was immer der Fall war, wenn ich die Simulation erneut durchführte (Wie Runde 1 hätte einen 47% Erfolg dann Runde 2 51 % in rund drei 58% ... dann der nächste Durchlauf würde 46% zurückkehren, 52%, 59%.

ist ich etwas falsch machen, oder ist das nur etwas die RND-Funktion bei der Handhabung nicht groß?

Public Function wRandomNumber(lowerbound, upperbound, Optional rndType = 1) As Double 
Dim rndVariable As Double 
'Const ms As Double = 0.000000011574 

Randomize Timer 
'Application.Wait Now + ms * 1 
rndVariable = Rnd 
If rndType = 1 Then 
    wRandomNumber = Int((upperbound - lowerbound + 1) * rndVariable + lowerbound) 
ElseIf rndType = 2 Then 
    If (upperbound - lowerbound + 1) * rndVariable + lowerbound <= upperbound Then 
     wRandomNumber = (upperbound - lowerbound + 1) * rndVariable + lowerbound 
    Else 
     Do While (upperbound - lowerbound + 1) * rndVariable + lowerbound > upperbound 
      rndVariable = Rnd 
      If (upperbound - lowerbound + 1) * rndVariable + lowerbound <= upperbound Then 
       wRandomNumber = (upperbound - lowerbound + 1) * rndVariable + lowerbound 
      End If 
     Loop 
    End If 
End If 
End Function 

Public Sub Playoff_sim() 

Dim game_num As Integer 
Dim lds_wins_stros As Integer 
Dim lds_loss_stros As Integer 
Dim lcs_wins_stros As Integer 
Dim lcs_loss_stros As Integer 
Dim ws_wins_stros As Integer 
Dim ws_loss_stros As Integer 
Dim p As Double 
Dim outcome1 As Single 
Dim outcome2 As Single 
Dim outcome3 As Single 
Dim i As Double 
Dim iter As Double 
Dim CHAMPS As Double 
Dim Loser As Double 
Dim p_bad As Double 
Dim p_norm As Double 
Dim lds_champs As Double 
Dim lcs_champs As Double 
Dim r As Double 
Const ms As Double = 0.000000011574 

iter = 100000 
CHAMPS = 0 
Loser = 0 
lds_champs = 0 
lcs_champs = 0 
p_bad = 0.5 
p_norm = 0.5 
r = 0 
For i = 1 To iter 

game_num = 1 
lds_wins_stros = 0 
lds_loss_stros = 0 
lcs_wins_stros = 0 
lcs_loss_stros = 0 
ws_loss_stros = 0 
ws_wins_stros = 0 

Do Until lds_wins_stros = 3 Or lds_loss_stros = 3 

outcome1 = wRandomNumber(0, 1, 2) 
    If game_num = 3 Then 
     p = p_bad 
    Else 
     p = p_norm 
    End If 

    If p > outcome1 Then 
     lds_wins_stros = lds_wins_stros + 1 
    Else 
     lds_loss_stros = lds_loss_stros + 1 
    End If 
    r = r + 1 
    'Worksheets("Playoff_Sim").Cells(r, 15).Value = outcome1 

game_num = game_num + 1 
Loop 

If lds_wins_stros = 3 Then 

    outcome2 = wRandomNumber(0, 1, 2) 
    lds_champs = 1 + lds_champs 
    Do Until lcs_wins_stros = 4 Or lcs_loss_stros = 4 

    If game_num = 3 Or 6 Or 9 Or 12 Or 15 Or 18 Or 21 Then 
     p = p_bad 
    Else 
     p = p_norm 
    End If 

    If p > outcome2 Then 
     lcs_wins_stros = lcs_wins_stros + 1 
    Else 
     lcs_loss_stros = lcs_loss_stros + 1 
    End If 

    game_num = game_num + 1 

    Loop 

    If lcs_wins_stros = 4 Then 
     lcs_champs = lcs_champs + 1 

     outcome3 = wRandomNumber(0, 1, 2) 
     Do Until ws_wins_stros = 4 Or ws_loss_stros = 4 

      If game_num = 3 Or 6 Or 9 Or 12 Or 15 Or 18 Or 21 Then 
       p = p_bad 
      Else 
       p = p_norm 
      End If 

      If p > outcome3 Then 
       ws_wins_stros = ws_wins_stros + 1 
      Else 
       ws_loss_stros = ws_loss_stros + 1 
      End If 
     'r = r + 1 
     game_num = game_num + 1 
     'Worksheets("Playoff_Sim").Cells(r, 15).Value = outcome3 
     Loop 

     If ws_wins_stros = 4 Then 
      CHAMPS = CHAMPS + 1 
     Else 
      Loser = Loser + 1 
     End If 

    Else 
     Loser = Loser + 1 
    End If 

Else 
    Loser = Loser + 1 
End If 

Next i 

Worksheets("Playoff_Sim").Cells(2, 1).Value = CHAMPS 
Worksheets("Playoff_Sim").Cells(2, 2).Value = Loser 
Worksheets("Playoff_Sim").Cells(2, 3).Value = lds_champs 
Worksheets("Playoff_Sim").Cells(2, 4).Value = lcs_champs 

End Sub

+0

'Wenn (Obergrenze - Untergrenze + 1) * rndVariable + Untergrenze <= Obergrenze 'Was willst du mit diesem Check erreichen? –

+1

Hinweis: Sie können das Leben mit 'Application.RandBetween (0,1)' erleichtern. Es ist ziemlich nah an 50/50%, zu einer 1/1000 Präzision, also sollten Sie sich nicht darum kümmern. –

+0

Ich habe die Benutzerfunktion wRandomNumber aus einem anderen Thread kopiert, um zu testen, ob die Art, wie ich meine Zufallszahl erstellt habe, das Problem war. Ich bin mir also nicht ganz sicher, wozu diese Aufgabe dient. Ich brauchte definitiv keine Benutzerfunktion, da ich einfach meine "outcome" Variable = auf Rnd setzen konnte (nach der Randomisierung). – BigChief

Antwort

0

Das Problem ist nicht nur in den Zufallszahlen ist (die durch die Anregung von @ASH angesprochen werden kann Application.RandBetween verwenden), sondern ist auch in der Logik deine Simulation. Das zweimal wiederholt Codefragment

If game_num = 3 Or 6 Or 9 Or 12 Or 15 Or 18 Or 21 Then 
    p = p_bad 
Else 
    p = p_norm 
End If 

entspricht die einzelne Zeile p = p_bad. Dies liegt daran, dass die Bedingung game_num = 3 Or 6 Or 9 Or 12 Or 15 Or 18 Or 21 immer True ergibt, da Sie nur game_num mit 3 vergleichen, aber dann VBA zwingen, die verbleibenden Zahlen (6,9,15,18,21) als True zu interpretieren, indem Sie den Operator Or mit ihnen verwenden. Stattdessen tun gerade:

If game_num Mod 3 = 0 Then 
    p = p_bad 
Else 
    p = p_norm 
End If 

Es könnten auch andere Probleme sein, wie gut, obwohl dies genug sein sollte, um loszulegen.