私は野球のポストシーズンシミュレータを作成して、悪い投手がチームのチャンピオンシップの確率にどのくらい影響するかを確認しようとしています。だから私は基本的にプレーオフのためのシミュレーターを作りました(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の提案によって対処することができます)乱数ではありませんが、のロジックでもある
'(upperbound-lowerbound +1)* rndVariable + lowerbound <= upperbound'このチェックで何を達成しようとしていますか? –
'Application.RandBetween(0,1)'を使うと簡単に使えるようになります。これは50/50%の1/1000の精度に非常に近いので、心配する必要はありません。 –
別のスレッドからwRandomNumberユーザ関数をコピーしてテストし、乱数を作成していた方法が問題であるかどうかを確認しました。だから私は実際にその行の目的が何であるか完全にはわからない。私は間違いなく、ユーザー関数を使用する必要はありませんでした。なぜなら、「結果」変数= Rnd(ランダム化後)に設定することができたからです。 – BigChief