プログラムについて
投稿者 トオリスガリ  (社会人)
投稿日時
2009/10/31 09:46:00
1から100までの数を、5個ランダム(ただし重複不可)に
選ぶっていうのでは駄目なのでしょうか?
それらの数を点数が加算される回数として使うということで。
駄目な場合、どういった条件にしたいかを再度教えてくださいませ。
選ぶっていうのでは駄目なのでしょうか?
それらの数を点数が加算される回数として使うということで。
駄目な場合、どういった条件にしたいかを再度教えてくださいませ。
投稿者 ハル  (学生)
投稿日時
2009/10/31 10:15:41
トオリスガリ様
ご返答ありがとうございます。
上手い説明が出来ずに申し訳ありません。
5個数字をランダムで選択し、その数字分クリックした時に加算。という形にすると、実験参加された方みんなが同じ回数で加算されることになってしまわないでしょうか?
そうならないのであれば良いのですが、何人か実験に参加して下さる方がいるのでその数字も毎回ランダムにしたいと思っています。
乱数発生のプログラムの仕方を先ほど見ていたのですが、
上記プログラムを使うと、最初に言ったような「平均20回で1ポイント加算」条件を作ることが出来るかなと思ったのですが、乱数を発生させてそこから加算させる方法がいまいち分かりかねます。
この考え方が根本的に違うのでしょうか…。
http://jeanne.wankuma.com/tips/vb6/random/next.html
ご返答ありがとうございます。
上手い説明が出来ずに申し訳ありません。
5個数字をランダムで選択し、その数字分クリックした時に加算。という形にすると、実験参加された方みんなが同じ回数で加算されることになってしまわないでしょうか?
そうならないのであれば良いのですが、何人か実験に参加して下さる方がいるのでその数字も毎回ランダムにしたいと思っています。
乱数発生のプログラムの仕方を先ほど見ていたのですが、
' 乱数を格納するための変数を宣言する
Dim iRandom As Integer
' 0 以上 100 未満の乱数を取得する
iRandom = CInt(Math.Rnd() * 100)
' 取得した乱数を表示する
Call MsgBox(CStr(iRandom))
上記プログラムを使うと、最初に言ったような「平均20回で1ポイント加算」条件を作ることが出来るかなと思ったのですが、乱数を発生させてそこから加算させる方法がいまいち分かりかねます。
この考え方が根本的に違うのでしょうか…。
http://jeanne.wankuma.com/tips/vb6/random/next.html
投稿者 あにす  (社会人)
投稿日時
2009/10/31 13:12:33
1回あたり20分の1ポイント前後加算されるようにすればよいのでは。
Public Class Form1
Dim point As Double
Const count As Integer = 20
Dim random As New Random()
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button1.Click
point += (1.0R / count) * random.Next(0, 3)
Label1.Text = Math.Floor(point).ToString()
End Sub
End Class
投稿者 魔界の仮面弁士  (社会人)
投稿日時
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 ステートメントの引数を指定することで、
このシード値を別の値に変更し、異なる乱数系列を得る事ができます。
それぞれの引数の意味については、ヘルプで確認してみてください。
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
投稿者 トオリスガリ  (社会人)
投稿日時
2009/10/31 23:49:05
魔界の仮面弁士さんのおっしゃるとおりかと思います。
平均20回に1回というのを、
20面あるサイコロを振ると思うのと同じと考えるかどうか。
そう考えるならば、とーても運が悪ければ、1点も入りませんね。
神がかりてきに運がよければ、100回やったら100点入りますね。
それでもよいか。通常のサイコロでも同じですよね。
よいのならば、単に0-19の乱数を毎回振り(Randomizeしてねー)、
0(などどれか固定数)が出たときだけ点数1点あげる、ということで
済むはずです。
これこそまさに確率1/20。
100回サイコロを振れば、”平均して”5回あたります。
(でも1回も当たらない確率もあれば100回当たる確率もあります)
(あにすさんの方法だと、最初(または点数加算があった回)の
次の数回は点数加算確率が極端に減ると思うのですが。
(もしかして0?))
いやいや100のうち5回ちょうどなんだよというのであれば
まさにくじ引きですね。(ぴったりな表現です)
> 乱数を発生させてそこから加算させる方法がいまいち分かりかねます
私には「そこから」という表現がいまいち分かりかねます。
「そこで加算」するんですけど。
5個違う乱数を人が変わるたびに作っておいて、それを保存しておきます。
でボタンを押すたびに+1する変数とそれらを比較し、どれかと一致していたら、
「そこで加算」するということです。伝わっておりますでしょうか。
平均20回に1回というのを、
20面あるサイコロを振ると思うのと同じと考えるかどうか。
そう考えるならば、とーても運が悪ければ、1点も入りませんね。
神がかりてきに運がよければ、100回やったら100点入りますね。
それでもよいか。通常のサイコロでも同じですよね。
よいのならば、単に0-19の乱数を毎回振り(Randomizeしてねー)、
0(などどれか固定数)が出たときだけ点数1点あげる、ということで
済むはずです。
これこそまさに確率1/20。
100回サイコロを振れば、”平均して”5回あたります。
(でも1回も当たらない確率もあれば100回当たる確率もあります)
(あにすさんの方法だと、最初(または点数加算があった回)の
次の数回は点数加算確率が極端に減ると思うのですが。
(もしかして0?))
いやいや100のうち5回ちょうどなんだよというのであれば
まさにくじ引きですね。(ぴったりな表現です)
> 乱数を発生させてそこから加算させる方法がいまいち分かりかねます
私には「そこから」という表現がいまいち分かりかねます。
「そこで加算」するんですけど。
5個違う乱数を人が変わるたびに作っておいて、それを保存しておきます。
でボタンを押すたびに+1する変数とそれらを比較し、どれかと一致していたら、
「そこで加算」するということです。伝わっておりますでしょうか。
投稿者 ハル  (学生)
投稿日時
2009/11/1 05:50:33
色々なアドバイスありがとうございました。
あれから色々試行錯誤してみたのですがどうにもうまくいきません。
皆さんが仰っている通り、100回に5回、なので点数が100回押すうちに5点入れば良いという考え方でおります。くじ引きの要領ですね。
1から100までの中からランダムに数字を発生させるのであれば
で出せると思うのですが、これを5個取り出すには何か方法がありますでしょうか。
その方法がわからなかったので、一度20ずつに区切ってみようかと思い、
上記の形でやってみたのですが、IF文なので「加算」が上手くされません。
そのため
Yahooの知恵袋さんでアドバイスを頂き、上記の形でやってみたのですが、5点入ればいいところを6点入ったりしてしまいます。(http://detail.chiebukuro.yahoo.co.jp/qa/question_detail.php?qid=1432413559)
A1 = Int(Rnd * 100) + 1
この設定をうまく変えれば良いのかと思うのですが、どのように変えれば良いのかわかりません。
あれから色々試行錯誤してみたのですがどうにもうまくいきません。
皆さんが仰っている通り、100回に5回、なので点数が100回押すうちに5点入れば良いという考え方でおります。くじ引きの要領ですね。
1から100までの中からランダムに数字を発生させるのであれば
Int(Rnd * 100) + 1
で出せると思うのですが、これを5個取り出すには何か方法がありますでしょうか。
その方法がわからなかったので、一度20ずつに区切ってみようかと思い、
If response = CInt(Int((20 - 1) + 1) * Rnd() + 1) Then
Label1.Text = tokuten + 1
End If
If response = CInt(Int((40 - 21) + 1) * Rnd() + 21) Then
Label1.Text = tokuten + 1
End If
上記の形でやってみたのですが、IF文なので「加算」が上手くされません。
そのため
A1 = Int(Rnd * 100) + 1
A2 = Int(Rnd * 100) + 1
A3 = Int(Rnd * 100) + 1
A4 = Int(Rnd * 100) + 1
A5 = Int(Rnd * 100) + 1
Select Case response
Case A1, A2, A3, A4, A5
Tokuten = Tokuten + 1
End Select
Yahooの知恵袋さんでアドバイスを頂き、上記の形でやってみたのですが、5点入ればいいところを6点入ったりしてしまいます。(http://detail.chiebukuro.yahoo.co.jp/qa/question_detail.php?qid=1432413559)
A1 = Int(Rnd * 100) + 1
この設定をうまく変えれば良いのかと思うのですが、どのように変えれば良いのかわかりません。
投稿者 ハル  (学生)
投稿日時
2009/11/1 06:01:32
連続投稿申し訳ありません。
アドバイスを頂いた中で質問に答えられていない箇所がありましたので補足します。
魔界の仮面弁士様
>VB6 版のサンプルを参考にされたという事は、現行バージョンの VB ではなく、
.NET ではないバージョンの VB をお使いという事のようですね。
ごめんなさい。こちらで使用しているバージョンくらい書いておくのが常識でした。
一応Visual Basic 2008 Express Editionを利用しています。
>1 回押して 2点入ったり、あるいは、マイナスの点数や小数点数が入るのもありですか?
点数は全て+1でマイナスになることはなく、小数点数もありません。
トオリスガリ様
>5個違う乱数を人が変わるたびに作っておいて、それを保存しておきます。
でボタンを押すたびに+1する変数とそれらを比較し、どれかと一致していたら、
「そこで加算」するということです。伝わっておりますでしょうか。
日本語理解に乏しく申し訳ないです…。
仰りたい事は何となくわかります。
乱数を作っておく、ということはいくつかパターンを書き出しておき、それをストックしておいて人によって変えていけばいい。ということでしょうか。
アドバイスを頂いた中で質問に答えられていない箇所がありましたので補足します。
魔界の仮面弁士様
>VB6 版のサンプルを参考にされたという事は、現行バージョンの VB ではなく、
.NET ではないバージョンの VB をお使いという事のようですね。
ごめんなさい。こちらで使用しているバージョンくらい書いておくのが常識でした。
一応Visual Basic 2008 Express Editionを利用しています。
>1 回押して 2点入ったり、あるいは、マイナスの点数や小数点数が入るのもありですか?
点数は全て+1でマイナスになることはなく、小数点数もありません。
トオリスガリ様
>5個違う乱数を人が変わるたびに作っておいて、それを保存しておきます。
でボタンを押すたびに+1する変数とそれらを比較し、どれかと一致していたら、
「そこで加算」するということです。伝わっておりますでしょうか。
日本語理解に乏しく申し訳ないです…。
仰りたい事は何となくわかります。
乱数を作っておく、ということはいくつかパターンを書き出しておき、それをストックしておいて人によって変えていけばいい。ということでしょうか。
投稿者 ハル  (学生)
投稿日時
2009/11/1 08:01:20
度々申し訳ありません。
自己解決致しましたのでご報告にあがらせて頂きました。
上記コードを
このイベント内に入れてしまっていたので、ボタンをクリックする度にランダム数字が変わってしまい、うまく点数加算に結び付かなかったようです。
そのため、5つのランダム数字を設定するコードを外へ出してやったら上手く加算されるようになりました。
ご相談に乗って下さった方々、本当にありがとうございました。
また来る機会があったらよろしくお願いします。
自己解決致しましたのでご報告にあがらせて頂きました。
Randomize()
'1から100の間で5つの数字を取り出す
numA.Text = CInt(Int((20 - 1) + 1) * Rnd() + 1)
numB.Text = CInt(Int((40 - 21) + 1) * Rnd() + 21)
numC.Text = CInt(Int((60 - 41) + 1) * Rnd() + 41)
numD.Text = CInt(Int((80 - 61) + 1) * Rnd() + 61)
numE.Text = CInt(Int((100 - 81) + 1) * Rnd() + 81)
上記コードを
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
krp = True
response = response + 1
result.Text = Str(response)
Label1.Text = Tokuten
Select Case response
Case numA.Text, numB.Text, numC.Text, numD.Text, numE.Text
Tokuten = Tokuten + 1
End Select
このイベント内に入れてしまっていたので、ボタンをクリックする度にランダム数字が変わってしまい、うまく点数加算に結び付かなかったようです。
そのため、5つのランダム数字を設定するコードを外へ出してやったら上手く加算されるようになりました。
ご相談に乗って下さった方々、本当にありがとうございました。
また来る機会があったらよろしくお願いします。
投稿者 (削除されました)  ()
投稿日時
2009/11/1 08:29:09
(削除されました)
投稿者 トオリスガリ  (社会人)
投稿日時
2009/11/1 12:27:45
> 日本語理解に乏しく申し訳ないです…。
> 仰りたい事は何となくわかります。
何となく、ってことは全然伝わってなかったったってことですねえ。
> 乱数を作っておく、ということはいくつかパターンを書き出しておき、それをストックしておいて人によって変えていけばいい。ということでしょうか。
じぇんじぇん違います。
>> 5個違う乱数を人が変わるたびに作っておいて、それを保存しておきます。
もう大丈夫だと思いますが、「人が変わるたびに」っていうのは被験者が
変更になった段階で、ということです。
「それを保存」ということで、もともとのハルさんのコードだと、
毎回ボタンを押す度に変更されていたわけなので、
全然「保存」してませんでしたよねえ。
それを外に出したことで、ボタンを押すという行動から、
数値が保存されているわけです。
これは20区切りにしたからうまくいったとか、そういうことではありません。
もともとの100までのうち5個ってやつでも、まったく同じことです。
20区切りにしたほうがよかったのかは、ハルさんの実験目的にも拠ってきます。
そちらの方がよかったんでしょうか?
20区切りにしたことで、例えば最初の1回目で加算されたら、あと、
続く19回は得点が加算されることはありませんよね。
それが被験者にわかってしまっても、実験の方法・目的からして問題ないか、
どうかということです。
プログラムが動いたからOK、ではなく、やっと実験目的に沿うように
プログラムを組めそうな段階になったわけですから、本来の実験目的に
立ち返って再度考えてみてくださいませ。
> 仰りたい事は何となくわかります。
何となく、ってことは全然伝わってなかったったってことですねえ。
> 乱数を作っておく、ということはいくつかパターンを書き出しておき、それをストックしておいて人によって変えていけばいい。ということでしょうか。
じぇんじぇん違います。
>> 5個違う乱数を人が変わるたびに作っておいて、それを保存しておきます。
もう大丈夫だと思いますが、「人が変わるたびに」っていうのは被験者が
変更になった段階で、ということです。
「それを保存」ということで、もともとのハルさんのコードだと、
毎回ボタンを押す度に変更されていたわけなので、
全然「保存」してませんでしたよねえ。
それを外に出したことで、ボタンを押すという行動から、
数値が保存されているわけです。
これは20区切りにしたからうまくいったとか、そういうことではありません。
もともとの100までのうち5個ってやつでも、まったく同じことです。
20区切りにしたほうがよかったのかは、ハルさんの実験目的にも拠ってきます。
そちらの方がよかったんでしょうか?
20区切りにしたことで、例えば最初の1回目で加算されたら、あと、
続く19回は得点が加算されることはありませんよね。
それが被験者にわかってしまっても、実験の方法・目的からして問題ないか、
どうかということです。
プログラムが動いたからOK、ではなく、やっと実験目的に沿うように
プログラムを組めそうな段階になったわけですから、本来の実験目的に
立ち返って再度考えてみてくださいませ。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2009/11/1 19:36:00
> 一応Visual Basic 2008 Express Editionを利用しています。
であれば、そのサイトで参考にするべきは
http://jeanne.wankuma.com/tips/vb6/random/next.html
ではなく、
http://jeanne.wankuma.com/tips/vb.net/random/next.html
の方であったかと思いますよ。
精度、使いやすさの両面から、「Rnd 関数」の使用はあまりお勧めできません。
VB.NET (2002/2003/2005/2008/2010)では、「Random クラス」を使った方が良いでしょう。
なお、VB 中学校の記事で乱数を扱ったものとしては
http://homepage1.nifty.com/rucio/main/dotnet/ClassLibrary/L002_System.Random.htm
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard5.htm
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard14.htm
などがあるようです。
であれば、そのサイトで参考にするべきは
http://jeanne.wankuma.com/tips/vb6/random/next.html
ではなく、
http://jeanne.wankuma.com/tips/vb.net/random/next.html
の方であったかと思いますよ。
精度、使いやすさの両面から、「Rnd 関数」の使用はあまりお勧めできません。
VB.NET (2002/2003/2005/2008/2010)では、「Random クラス」を使った方が良いでしょう。
なお、VB 中学校の記事で乱数を扱ったものとしては
http://homepage1.nifty.com/rucio/main/dotnet/ClassLibrary/L002_System.Random.htm
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard5.htm
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard14.htm
などがあるようです。
卒業論文を書くのに必要な実験をする予定なのですが、いかんせんVBを使った実験は初めてなもので困っております。
実験は簡単なボタンを押して点数が加算されるようなプログラムです。
ただボタンを押すだけとは何が違うのかと言いますと、ボタンを押した回数分、点数が加算される。というものではなく、何回押せば点数が入るのかはわからず、「点数が入るまでに押した回数が平均して20回になるようにしたい」です。
変動比率スケジュールという形にしたいのですが、そう言ってしまうと分かりづらくなってしまうでしょうか。
例えば、12回押したら1点目、次に押し続けていたら48回目に1点加算される…、これは合計60回押したうち2点加算され、平均して30回に1点入る計算になる、という形です。
同じように100回押し続けて平均20回に1点入るようにするプログラムの組み方はありますでしょうか?
押す回数は規則性(2の倍数など)があると実験してもらう側に推測がされてしまうので避けたいです。
完全に回答が得られずとも、「こういうプログラムがありますよ」という助言でも構いません。
どうぞよろしくお願いします。