• ベストアンサー

99BASICプログラムの乱数の計算について

学校で出た問題で、サイコロを2個振り、(乱数生成で代用)出た目の和がどのような 確率で分布するか調べなさい、と出たのですが、問1のプログラムがあっているのかと、問2を ヒントだけでも教えてください。お願いします。 問題↓ 回数を記憶する配列 f( ) を用意 1 r1=rnd(6)+1:r2=rnd(6)+1  2個のサイコロを振るr1、r2は1から6の目を生成 2 r=r1+r2 出た目の和を求める 3 f(r)=f(r)+1 和がrである回数を求める 4 1から3までを50000回繰り返す 5 cint(f(r)/f(2))をr=2からr=12まで順に表示する 問1 アルゴリズムに沿ったプログラムリストを示せ 問2 cint(f(r)/f(2))の表示結果を示し、簡単にその妥当性を検討せよ で、書いたプログラムが 10 dim f(12) 20 for i=1 to 50000 ←ここでサイコロを振る回数を決める? 30 r1=rnd(6)+1:r2=rnd(6)+1 40 r=r1+r2 50 f(r)=f(r)+1 60 next i 70 for i=1 to 6 80 print cint(f(r)/f(2)) 90 next i 100 end で、結果が縦に3が6個ならんだのですが、問1はこれでいいのでしょうか。 問2の妥当性ってどういうことでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.8

あとはcint(f(r)/f(2))の実行結果が何を意味しているか、を書けばおそらくだいたい問題ないでしょう、というかそれがないと何故「従って……」なのか意味不明だったりします。 あと一息ですから、そこは自力で頑張ってくださいね。

sigure7
質問者

お礼

D-Matsuさん、レスが遅くなって申し訳ありませんでした。 無事に解決することが出来ました。 本当に有難うございました。

その他の回答 (7)

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.7

あー、でもこれなら実行結果を確率分布側にあわせたほうがいいですね。 実行結果は1 2 3 4 5 6 5 4 3 2 1で、この総和は36。 従って各出目の確率分布は1/36, 2/36, 3/36, 4/36, 5/36 ...になるので妥当、と。

sigure7
質問者

補足

こう書くことにしてみましたー。 2個のサイコロで各目の和が出る理論上の確率分布は、それぞれ 1/36 2/36 3/36 4/36 5/36 6/36 5/36 4/36 3/36 2/36 1/36になる。 cint(f(r)/f(2))の実行結果は1 2 3 4 5 6 5 4 3 2 1で、この総和は36。 従って各和が出る確率分布は1/36 2/36 3/36 4/36 5/36 6/36 5/36...となるので妥当である。 Σd(≧ω≦) ほとんどD-Matsuさんのまる写し! 書き方こんな感じで良いでしょか。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.6

計算結果としては、一番低い2の回数から見た各出目の回数の比が出る訳です。 これと理論上の確率を比較して妥当かどうか、ってのが検証な訳ですね。 なお#4の例示で3の確率を通分してしまったのが微妙にまずかったのかもしれませんが、6と8の確率は5/36です。 各出目の理論上の確率は 1/36, 2/36, 3/36, 4/36, 5/36, 6/36, 5/36 ... なので、プログラム同様に2の確率である1/36で割ることで分母が取れて1,2,3,4,5,6,5 ...になり、プログラム実行結果と等しいので妥当といえる、と。 #あ、こっちのがわかりやすいでやんのorz

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.5

各出目の確率を2の確率で割ってみましょう。

sigure7
質問者

補足

cint(f(r)/f(2))は、各和の出た回数を2の回数で割り、四捨五入するという意味なので、各和の出た回数を2の回数で割ると、12345654321になる。 2個のサイコロで和が出る確率はそれぞれ1/36 1/18 1/12 1/9 1/7 1/6 1/7 1/9 1/12 1/18 1/36 同じように各和の確率を2の確率で割ると 1/36÷1/36=1 1/18÷1/36=2 1/12÷1/36=3 1/9÷1/36=4 1/7÷1/36=5 1/6÷1/36=6 1/7÷1/36=5 1/9÷1/36=4 1/12÷1/36=3 1/18÷1/36=2 で、cint(f(r)/f(2))の表示結果12345654321と同じなので妥当。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー これで完成でしょうか。。。? 各出目の確率を2の確率で割る数と、cint(f(r)/f(2))の表示結果が同じ になりました!なんか分かったような気がします! アドバイスマジで感謝っす!

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.4

> 70でRが2だから80で(f(2)/f(2))となって、f(2)が1372だから > 1372を1372で割ってみると1になったので、これが結果の1と > いうことでしょうか。 まぁそういうことです。「各目の回数を2の回数で割る」ってことですね。 一方、2が出る確率は1/36、3が出る確率は1/18…… ってことで、あとはどうすれば検証になるかはわかりますね?

sigure7
質問者

補足

プログラムででた数値と、サイコロを2個振ったときに出る目の和の確率 の分布は似てるからおっけー、でいいんでしょうか。 ウィキペディアの確率分布の項目の、サイコロを二つ振ったときの確率 と同じ数字だったので、、、 今まで考えていたんですが、やっぱり分かりませんでした。。。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.3

> 問2はグラフ書けばいいのかな? グラフを書く必要はないでしょう。出てきた値の検証だけで十分です。 f(r)/f(2)(2≦r≦12)の式が何を表してるかがわかれば、各rに対しどんな結果が出ていれば良さそうなのかはわかるはずです。

sigure7
質問者

補足

>f(r)/f(2)(2≦r≦12)の式が何を表してるか 今気付いたのですが、問題5のあとに書いてある文字を入れ忘れてました すいません。cint(X)でXを四捨五入 って書いてありました。 10 dim f(12) 20 for i=1 to 50000  サイコロを振る回数 30 r1=rnd(6)+1:r2=rnd(6)+1 2つのサイコロを振る 40 r=r1+r2  出た目の和を求める 50 f(r)=f(r)+1  和がrである回数を数える 60 next i 70 for r=2 to 12 r=2からr=12まで 80 print cint(f(r)/f(2))  四捨五入??? 85 print "和"r,"和が出た回数"f(r)"回" 90 next r 100 end と書いて実行してみると、結果が12345654321と出ました。 70でRが2だから80で(f(2)/f(2))となって、f(2)が1372だから 1372を1372で割ってみると1になったので、これが結果の1と いうことでしょうか。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.2

70~90のforループで ・カウンタがiであるにも関わらずfの添え字がrなので、同じf(r)(最後に出たr1とr2の合計値の回数)を表示するだけ ・2~12まで表示する、とあるのに1~6になっている のは明らかにおかしいですね。 問2はプログラム実行結果が実際の確率分布に沿っているかどうかを見るのが目的でしょう。

sigure7
質問者

お礼

プログラム自体がいまいち理解できてなかったので助かりました。 70 for i=1 to 6を変えれば良かったんですね。 問2はグラフ書けばいいのかな? D-Matsuさん、解答ありがとうございます!

  • don_go
  • ベストアンサー率31% (336/1059)
回答No.1

>5 cint(f(r)/f(2))をr=2からr=12まで順に表示する ↑はどこに有りますか?

sigure7
質問者

お礼

3 f(r)=f(r)+1アタリから混乱してました。 don_goさん、解答ありがとうございます!

関連するQ&A

  • Basicでのプログラムなのですが・・・

    配列変数についてなのですが、 『20個のデータを入力し、大きい順に並べて表示するプログラム。』 なのですが… 言語:【BASIC】 ソフト:【N88】 を使用しています。 とりあえず、 10 DIM A(20) 20 FOR I=1 TO 20 30 INPUT A(I) 40 NEXT I まではわかるのですが、ここから先がわかりません。 ここから先はどのようにすればいいでしょうか。 どなたかご教授いただけると幸いです。

  • 乱数について(Rnd関数)

    すみません。質問があります。 VBAを用いてパチスロシミュレータを作成しているのですが 乱数が偏っている気がしてなりません。 乱数はRnd関数を用いて0~65535の範囲で生成しています。 もちろん初期化時にRandomizeも用いています。 毎ゲーム開始時にそのゲームで必要な乱数を4つ r1 = Int(Rnd() * 65536) r2 = Int(Rnd() * 65536) r3 = Int(Rnd() * 65536) r4 = Int(Rnd() * 65536) というように生成しています。 それらの乱数を用いて複雑なモード移行などを行っているのですが、 ある条件下でr1のあるビットが1になりやすいというような現象が起こります。 乱数に法則性があることは不思議ではないんですが、Rnd関数による乱数っていうのは多少複雑な処理をしただけでこのような不具合が出る可能性があるのでしょうか。 私のプログラムに問題があるとは思うのですが、「もしかして、乱数のせいかも?」という疑念を抱いてデバッグするのはつらいものがあるので。 ですので、 ・変な使い方をすれば目に見えて偏る可能性もある。 という意見の方はその「変な使い方」というのを具体的に教えていただけないでしょうか? また、そのような意見の方がしばらくいらっしゃらない場合はRnd関数による乱数は実用上問題なく使えると解釈したいと思います。 よろしくおねがいします。

  • 正規分布するプログラムを教えてください。

    正規分布する乱数プログラムを作りたいのですが、うまく作れません・・。 プログラムソースは長くなりますので見ていただかなくても結構なのですが、下記のようなプログラムを実行したところ、実行結果下記になり、正規分布にはなりませんでした・・。 色々ネットで調べたものの理解できないのでどなたか教えていただけないでしょうか>< 正規分布を利用して、例えば50~100位の間に分布する乱数を生成したりしたいのです。。。 #include <math.h> #include <time.h> #include <stdlib.h> #include <stdio.h> #define PI 3.14159265358979323846264 double p_nor(){ double rnd,t,u,r1,r2; rnd=rand()%10000/10000.0; t=sqrt(-2.0 * log(1-rnd)); u=2*PI*rnd; r1=t*sin(u); return r1; } int main(){ int i,bunpu[30]={}; double p,min=0,max=0,total=0; srand((unsigned)time(NULL)); for(i=0;i<100000;i++){ p=p_nor(); for(int j=0;j<30;j++){ if(p>-2.0+0.1*j && p<=-1.9+0.1*j) bunpu[j]++; } if(min>p)min=p; if(max<p)max=p; total+=p; } printf("min:%f max%f 平均%f\n",min,max,total/100000); for(int j=0;j<30;j++){ for(i=0;i<bunpu[j]/200;i++){ printf("*"); } printf("\n"); } return 0; } 実行結果 min:-1.711381 max0.803275 平均-0.247841 **************** ************************************ ******************** **************** ************** ************ *********** ********** ********** ********* ********* ******** ******** ******** ******** ******** ******** ******** ************************************* ************************* *********************** *********************** ************************ **************************** ******************************** **************************************************************** ***********

  • 十進BASICのプログラムについて

    十進BASICのプログラムについて 小町算のプログラムですが、 100 DIM s(9) 110 FOR i=1 TO 9 120 LET s(i)=-1 130 NEXT i 140 DO 150 LET sum=0 160 LET num=0 170 LET sign=1 180 FOR i=1 TO 9 190 IF s(i)<>0 THEN 200 LET sum=sum+sign*num 210 LET sign=s(i) 220 LET num=i 230 ELSE 240 LET num=10*num+i 250 END IF 260 NEXT i 270 LET sum=sum+sign*num 280 IF sum=100 THEN 290 FOR i=1 TO 9 300 IF s(i)= +1 THEN PRINT " + "; 310 IF s(i)= -1 THEN PRINT " - "; 320 PRINT i; 330 NEXT i 340 PRINT " = 100" 350 END IF 360 LET i=9 370 LET sign=s(i)+1 380 DO WHILE ( sign > 1 ) 390 LET s(i)=-1 400 LET i=i-1 410 LET sign=s(i)+1 420 LOOP 430 LET s(i)=sign 440 LOOP WHILE ( s(1) < 1) 450 END というものですが、このプログラム中にあるsum、num、signとはどういう意味があるのでしょうか?

  • 重複しない乱数発生

    初めて投稿させて頂きます。 サイコロを振って、一度出た目はもう出ないような ゲームをプログラミングしています。 Dim i As Integer Dim j As Integer Dim t As Integer Dim r(6) As Integer 'コンピュータ Dim b As Integer 'プレイヤー Private Sub Command1_Click() b = Val(Text2.Text) Randomize r(6) = Int(Rnd * 6 + 1) '1~6までの乱数発生 Text1.Text = r(6) For i = 1 To n r(i) = i 'r(i)~r(n)に1~nの値を格納 Next i For i = n To 2 Step -1 j = Int((i - 1) * Rnd() + 1) '1~i-1の範囲の乱数 t = r(i): r(i) = r(j): r(j) = t 'r(i)とr(j)の交換 Next i For i = 1 To n Text1.Text = r(i) Next i If r(i) < j Then Label2.Caption = "あなたの勝ちです" Else Label2.Caption = "あなたの負けです" End If 幾つか考えてこれで落ち着いたのですが、これでは まだ重複してしまいます。 どこが問題なのかご指摘頂けるようお願いします。 一度出た目は出ないようにするので、全部で6回試行 することになります。またその6回分の結果を表示したいのですが、 Text3.Text = r(1) Text4.Text = r(2) Text5.Text = r(3) Text6.Text = r(4) Text7.Text = r(5) Text8.Text = r(6) としてしまうと全てに0が表示され、結果が表示されません。 これについても回答をお願いします。 まだ初心者ですが、よろしくお願いします。

  • このプログラムで計算を実行すると・・・

    10:S=0 20:FOR I=0 TO 6 STEP 2 30:FOR L=0 TO I 40:S=S+L 50:NEXT I 60:NEXT L 70:PRINT S 80:END 90: このプログラムを実行すると、「34」とプログラムの計算結果が表示されるのですが、実際に自分で計算すると「22」になってしまいます。 どこが違うのとか・・・基本的なとこが間違ってるのか? あとプログラムの動きを解説して頂けるとうれしいです! それでは、お願い致します。

  • VBAの乱数について質問

    乱数 x (0<x<1)を0.1刻みで発生させたいんですが うまくいきません。 プログラム例 Sub 一様乱数() Dim bin#(10) n = 1000 For m = 1 To 10 bin#(m) = 0 Next m For J = 1 To n x = Rnd(1) ix = Int(10 * Rnd(1)) bin#(ix) = bin#(ix) + 1 Next J Cells(4, 1) = " I" Cells(4, 2) = "Bin#(I)度数分布" For I = 0 To 10 Cells(I + 5, 1).Value = I Cells(I + 5, 2).Value = bin#(I) Next I End Sub ここで、9行目ix = Int(10 * Rnd(1))で0.1刻みになり 15行目のFor I = 0 To 10を0 to 1に変えればできると思ったんですが できませんでした。 どこが問題なのかヒントでもいいので教えてください。

  • サイコロの目を出す計算について疑問

    よろしくお願いします。 VB6.0でサイコロの目1-6を出す計算式として、 Int(Rnd() * 6) + 1 というものをよく見かけますが、これだと均等に1-6が出現しないような気がします。 Rnd()は0-1の値を返して、その値は全くランダムに返されるのだから、 戻り値が0<=かつ<0.1の場合はサイコロの目は1となり 0.1<=かつ<0.2ならサイコロの目は1となり 戻り値が0.2<=かつ<0.3なら目は2 0.3<=かつ<0.4なら2 戻り値が0.4<=かつ<0.5なら目は3 それなら次の、戻り値が0.5<=かつ<0.6なら目は3かと思えば、そうでなく4になってしまいます。 以下、 戻り値0.6台なら目は4 戻り値0.7台なら目は5 戻り値0.8台なら目は5 戻り値0.9台なら目は6 となり、これではぜんぜん均等にばらけないではないか?と思ったのですが、 実際に100000回計算させてそれぞれの出現回数を調べるとほぼ均等にばらけて いるように見えます。 一体どうしてなのでしょうか?

  • 計算表を作っています

    Partial Class Form1 Private Sub botan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles botan.Click Dim a, b, c, d, r, f, g, h, i, j, k As Integer a = CInt(TextBox1.Text) b = CInt(TextBox2.Text) c = CInt(TextBox3.Text) d = CInt(TextBox4.Text) r = CInt(TextBox5.Text) f = CInt(TextBox6.Text) g = CInt(TextBox7.Text) h = CInt(TextBox8.Text) i = CInt(TextBox9.Text) j = CInt(TextBox10.Text) a = a * 10000 b = b * 5000 c = c * 2000 d = d * 1000 r = r * 500 f = f * 100 g = g * 50 h = h * 10 i = i * 5 j = j * 1 If a < 0 And b < 0 And c < 0 And d < 0 And r < 0 And f < 0 And g < 0 And h < 0 And i < 0 And j < 0 Then hyouzi.Text = "エラー" End If k = a + b + c + d + r + f + g + h + i + j goukei.Text = CStr(k) End Sub End Class こんな表計算を作成しました。 しかし、これでは数字を入れないとエラーが起きてしまいます。 空白=0ということにしたいのですがどうしたらいいですか? アドバイスよろしくお願いします!

  • BASIC プログラム教えてください

    RND関数を用いて1,2,3,4のいずれかの値がランダムに与えられた4つの添字付き変数 a(1), a(2), a(3), a(4) と,MAT INPUT文により入力された b(1), b(2), b(3), b(4) に対し, a(i)=b(i) が成り立つ i の個数 h をカウントして, h=4 となるまで「×」と表示させ,h=4 となったら「○」と表示させて終了するプログラム a(1), a(2), a(3), a(4) を FOR ~NEXT構文で表示させる方法 DO(UNTIL)~ LOOP構文でこのプログラムを作る方法が分かりません

専門家に質問してみよう