投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/10/31 20:22:11
> http://jeanne.wankuma.com/tips/vb6/random/next.html
VB6 版のサンプルを参考にされたという事は、現行バージョンの VB ではなく、
.NET ではないバージョンの VB をお使いという事のようですね。


> 同じように100回押し続けて平均20回に1点入るようにするプログラムの組み方はありますでしょうか?
1 回押して 2点入ったり、あるいは、マイナスの点数や小数点数が入るのもありですか?
また、「平均20回」というのは「ジャスト20回」の意味ですか? それとも確率の話ですか?


もしも、「平均で20回に1点入るという "確率"」にしたいという意味なのであれば、
ボタンを押す回数が 20回であろうと 100回であろうと 5000回であろうと、
乱数の扱い方に変化はありません。1回辺りの確率を 1/20 に固定するだけです。

# 『サイコロ』の論理。たとえば、三の目が出る確率は何回振り続けても常に 6分の1 の確率ですね。


その一方で、「約20回ではなく、平均値が必ずジャスト20回になるようにする」という
意味であるならば、それはいわゆる『くじ引き』の方法を使うのが良いでしょう。

たとえば、もしも各回の加算点が 0点 または 1点 のいずれかしかありえない仕様だとすれば、
100 回試行して平均20回という事は、100回のうち、5回ヒットすれば良い事になります。
トオリスガリさんが提示された方法ですね。


また、下記のスレッドも参考にしてみてください(こちらは VB.NET の物ですが)。
http://rucio.groupsite.jp/commu/ThreadDetail.aspx?ThreadId=9206


> 実験参加された方みんなが同じ回数で加算されることになってしまわないでしょうか?
そうなるようにすることも、そうならないようにすることもできます。
そのため、擬似乱数生成器では『シード値』と呼ばれるものが重要となってきます。

このシード値によって、異なる乱数系列が生成されているのですが、実は
何回目に何という値が来るかは、このシード値によって決定されます。
そのため、シード値が同一であれば同じ結果が返されます。


の場合、初回のシード値には Single 型の固定値が使われていますので、
そのままですと、常に同じ乱数系列が選択されてしまいます。
そのため、単に Rnd 関数を呼ぶだけでは同じ結果になってしまいますが、
ここで Rnd 関数の引数あるいは Randomize ステートメントの引数を指定することで、
このシード値を別の値に変更し、異なる乱数系列を得る事ができます。

それぞれの引数の意味については、ヘルプで確認してみてください。

Option Explicit

Private Sub Command1_Click()
    'Lable1~4 は異なる値になるが、何回ボタンを押しても同じ結果になる。 
    Rnd -1
    Randomize 1
    Label1.Caption = CStr(Rnd())
    Label2.Caption = CStr(Rnd())

    Rnd -1
    Randomize 0
    Label3.Caption = CStr(Rnd())
    Label4.Caption = CStr(Rnd())
End Sub

Private Sub Command2_Click()
    'Lable1と2、Lable3と4はそれぞれ同じ値になり、何回ボタンを押しても同じ結果になる。 
    Randomize
    Label1.Caption = CStr(Rnd(-1))
    Label2.Caption = CStr(Rnd(-1))
    Label3.Caption = CStr(Rnd(1))
    Label4.Caption = CStr(Rnd(0))
End Sub

Private Sub Command3_Click()
    'Lable1~4は異なる値となり、ボタンを押すたびに違う結果にはなっているが、 
    '「アプリ起動後、Command3 のみを n 回押した結果」は常に一定となる。 
    Label1.Caption = CStr(Rnd())
    Label2.Caption = CStr(Rnd())
    Label3.Caption = CStr(Rnd())
    Label4.Caption = CStr(Rnd())
End Sub

Private Sub Command4_Click()
    'Lable1~4 は異なる値となり、ボタンを押すたびに違う結果になる。 
    'また、Command3 とは異なり、n 回目の結果が同じになる事も無い。 
    Randomize
    Label1.Caption = CStr(Rnd())
    Label2.Caption = CStr(Rnd())
    Label3.Caption = CStr(Rnd())
    Label4.Caption = CStr(Rnd())
End Sub