2017-07-06 60 views
2

我想創建一個棒球賽季後模擬器,看看有多少壞的投手影響球隊的奪冠賠率。所以我基本上創建爲淘汰賽模擬器(3輪,第一個是最好的5,接下來的兩個是最好的7)。我能看到多少,如果他每間距第三場比賽,他減少了10%勝算一個SP會傷害球隊。VBA隨機數在模擬

爲了確保我這樣做的寫,我第一次跑我的模擬沒有任何調整,每場比賽兩隊將有獲勝的機率爲50%。(團隊將因此擁有贏得世界的12.5%的機會在3輪季後賽中),但是,我一直高於12.5。

我有一個感覺問題是與Rnd函數,所以我玩了一下(增加了一個函數,試圖改變時間等),現在我的模擬出來是< 12.5%。然後我試圖排除麻煩,並注意到在每一輪中都沒有贏得50%的時間......這是每次我重新運行模擬時的情況(第一輪比第一輪有47%的成功,然後是第二輪51 %,那麼第三輪58%......那麼接下來的運行將返回46%,52%,59%。

難道我做錯了什麼,或者這只是事情的RND功能是不是在處理大?

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 

結束子

+0

'如果(upperbound - lowerbound + 1)* rndVariable + lowerbound <= upperbound'你試圖用這個檢查來實現什麼? –

+1

請注意,您可以使用'Application.RandBetween(0,1)'使生活更輕鬆。它接近50/50%,達到1/1000精度,所以你不應該擔心。 –

+0

我複製了另一個線程的wRandomNumber用戶函數,以測試我創建隨機數的方式是否是問題。所以我實際上並不完全確定這條線的目的是什麼。我絕對沒有需要使用用戶的功能,因爲我可以剛剛把我的「結果」變量=以賽第一輪(隨機化後)。 – BigChief

回答

0

的問題是不只是在隨機數(其可以由@ASH的建議來解決使用Application.RandBetween),但也是邏輯你的模擬。兩次重複的代碼片段

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 

相當於單行p = p_bad。這是因爲條件game_num = 3 Or 6 Or 9 Or 12 Or 15 Or 18 Or 21結果始終爲True,因爲你只比較game_num3但隨後迫使VBA使用Or運營商,他們來解釋其餘的數字(6,9,15,18,21)爲True。相反,只是這樣做:

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

可能還有其他問題,儘管這應該足以讓你開始。