2017-07-06 9 views
2

私は野球のポストシーズンシミュレータを作成して、悪い投手がチームのチャンピオンシップの確率にどのくらい影響するかを確認しようとしています。だから私は基本的にプレーオフのためのシミュレーターを作りました(3ラウンド、最初は5のベスト、次の2つは7のベストです)。そして、3回ごとの試合にピッチを当てればSPがどれほど傷つけるのか、そして10%の勝利の可能性を減らすことができます。シミュレーションでのVBA乱数

私はこれを書いたことを確認するために、まず調整なしでシミュレーションを実行したので、両方のチームが50%の勝利確率を持つようになりました(したがって、チームは世界に勝つチャンスは12.5%シリーズ3ラウンドプレーオフ)しかし、私は一貫して12.5より高くなっていた。

私はRnd関数に問題があったと感じています。そのため、ちょっと(関数を追加して時間を変えようとしました)演奏しましたが、今シミュレーションは< 12.5%になります。私はトラブルシューティングを試み、各ラウンドでは50%の時間に勝っていないことに気付きました。シミュレーションを再実行するたびにそうでした(ラウンド1は47% %は、次の3つの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 

End Subの問題だけで(Application.RandBetweenを使用する@ASHの提案によって対処することができます)乱数ではありませんが、のロジックでもある

+0

'(upperbound-lowerbound +1)* rndVariable + lowerbound <= upperbound'このチェックで何を達成しようとしていますか? –

+1

'Application.RandBetween(0,1)'を使うと簡単に使えるようになります。これは50/50%の1/1000の精度に非常に近いので、心配する必要はありません。 –

+0

別のスレッドからwRandomNumberユーザ関数をコピーしてテストし、乱数を作成していた方法が問題であるかどうかを確認しました。だから私は実際にその行の目的が何であるか完全にはわからない。私は間違いなく、ユーザー関数を使用する必要はありませんでした。なぜなら、「結果」変数= Rnd(ランダム化後)に設定することができたからです。 – BigChief

答えて

0

あなたのシミュレーション。 2回繰り返されるコードフラグメント

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に相当します。これは、と3を比較しているに過ぎないため、演算子を使用して残りの数字(6,9,15,18,21)をTrueと解釈させるために、VBAはTrueと解釈するため、常に条件game_num = 3 Or 6 Or 9 Or 12 Or 15 Or 18 Or 21Trueと評価されるためです。代わりに、単に実行します。これは、あなたが始めるのに十分でなければならないのに

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

を、同様に他の問題がある可能性があります。