乱数の発生
CindyScriptで乱数を発生する方法について考えます。
乱数の発生に関係する関数は、CindyScriptに次の6つが用意されています。
random() : 引数なし 0から1までの一様乱数を発生
randomnormal() : 引数なし (0,1)正規乱数を発生。正規乱数とは、発生した乱数の分布が正規分布に従うもの。
randombool() : 引数なし true または false を発生
random(数) : 0から引数までの実数の一様乱数
randomint(数):0から引数までの整数の一様乱数
seedrandom(数) : 引数に与えた数に対して、実行するたびに同じ乱数列が発生
ここでは、「1,2,3のどれかが同じ確率で出現する乱数」を発生させてみましょう。整数値が欲しいので、randomint()を使います。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
n1=0;
n2=0;
n3=0;
repeat(100,
a=randomint(3)+1;
if(a==1,n1=n1+1);
if(a==2,n2=n2+1);
if(a==3,n3=n3+1);
);
println(n1+","+n2+","+n3);
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
n1,n2,n3 はカウンタです。1,2,3の数が何回現れたかを数えます。最初は0です。
5行目で1,2,3のいずれかの数を発生します。randomint(3)は0から3までの整数の一様乱数を発生しますが、「3まで」がちょっとくせ者で、式で書くと 0≦x<3 なのです。3はできません。すなわち実際にできるのは0,1,2の3通りなのです。そこで、1を加えて1,2,3のどれかになるようにしています。
そのあと、発生した乱数aが1か2か3かによって、カウンタn1,n2,n3の値を1つ増やします。
これを100回繰り返して、最後にコンソールに表示します。
うまくいっているように見えますが、実際には実行するたびにかなりばらつきが出ます。とはいえ、これはしかたのないことです。1000回、10000回と回数を増やせば確率3分の1に近くなります。これは「一様乱数」のもともとの性質です。
これで「確率3分の1で数「1」を発生する」というコードが書けます。
目的は達成できましたが、CindyScriptでちょっと遊んでみましょう。
上のスクリプトでは、発生した乱数を変数aに代入し、その値を if で判断してカウンタを動かしています。これに対し、「リスト」を使えば if による判定がいらなくなるのです。
リストは、「ものを集めたもの」です。3つの数のリストは [2,4,6] のように表現されます。2と4と6からなるリストです。ここで、n1,n2,n3 というカウンタをリストにするのです。[n1,n2,n3]です。最初は全部0なので [0,0,0]です。
さて、乱数aができたら、それが整数で1,2,3のいずれかであることを利用します。どういうことかというと、1,2,3という数はそのまま「番号」として使えるからです。たとえば、1がでたらそれは1番目ということにします。そこで、リストの1番目の要素に1を足します。すこし具体的に例をあげてみましょう。
最初は何もない [0,0,0]
乱数1が出た [1,0,0]
また1が出た [2,0,0]
次に3が出た [2,0,1]
さて、リストのn番目の要素は _n で指定できます。_はアンダーバーです。すると、次のスクリプトで先ほどと同じことができます。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
n=[0,0,0];
repeat(100,
a=randomint(3)+1;
n_a=n_a+1;
);
println(n);
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー