乱数を扱うには

◆PROCESSING 逆引きリファレンス

 カテゴリー:演算処理

乱数を扱うには

【解説】

GAMEなどで敵の出現位置を決めたり、怪物や主人公のパラメータを決める処理で、適切な乱数を発生させることは、とても重要な処理となります。

PROCESSINGでも、擬似乱数を扱うことが可能です。PROCESSINGには、random() と noise() という2種類の乱数発生機能があります。

またPROCESSINGはJavaをベースにした言語であるため、Javaの乱数発生機能を利用することも可能です。

noise() については、「パーリンノイズを扱うには」で説明します。

 

【構文】

PROCESSINGでrandom命令を使う

●シードを変更します
void  randomSeed( int  seed ) ;

●疑似乱数を発生させます
float  r1  =  random( float high ) ;
float  r2  =  random( float  low,  float  high ) ;

r1には 0.0 から hight まで(hightは含まない)範囲の値が返却されます。
r2には low から hight まで(hightは含まない)範囲の値が返却されます。

 

JavaでRandomクラスを使う※

●乱数操作用インスタンスを生成します
Random  rs  =  new  Random(  )  ;
Random  rs  =  new  Random( long  seed )  ;

●シードを変更します
void  rs . setSeed( long seed ) ;

●疑似乱数を取得します
float  r3  =  rs . nextFloat( ) ;
int r4  =  rs . nextInt( int  hight ) ;

r3 には、0.0 から 1.0まで(1.0は含まない)範囲の値が返却されます。
r4 には、0 から hight まで(hightは含まない)範囲の値が返却されます。

※代表例のみ掲載しています。詳しくは以下を参照してください。

 

JavaでMath.randomを使う

●疑似乱数を発生させます
double  r5  =  Math . random( );

0.0 から 1.0まで(1.0は含まない)範囲の値が返却されます。

 

【注意】

JavaのRandomクラスやPROCESSINGのrandam()命令では、seedと呼ばれる乱数の「種(たね)」を与えることで、同じ系列の乱数を得ることが可能です。

seedを指定すると、常に同じ順番で同じ値が得られます。

上記結果は以下の通りです。


この結果は、プログラムを終了して再起動しても変わりません。なぜなら、seedがいつも一緒(この例では0)だからです。

結果だけを見ると、どうやらPROCESSINGのrandom() 命令は、JavaのRandomクラスと等価なようですね(笑)。

一方で、JavaのRandomクラスをNewする際に引数を省略した場合や、PROCESSINGでrandomSeed() 命令を使わずにいきなりrandom() 命令を使うと、seedは毎回自動的に割り当てられます。


上記処理では、共に seed を指定していない(おかかせ状態)ので、new Random() される、あるいは random() 命令が実行されるたびに新しい seed が採用され、毎回異なる値が表示されます。

ただしPROCESSINGの random() では、一度 seed を指定すると、これを取り消す事(PROCESSINGにおまかせにする事)ができません。ここは注意ですね。

またJavaのMath.random( ) では seed を指定する事ができません。Math.random( )は、命令が実行される毎に、毎回異なる seed がJavaにより自動的に割り当てられます。

乱数については、ウンチクを「コラム:乱数について」にまとめました。よろしければ参考としてください。

 

【関連記事】

 


サンプルプログラム

PROCESSINGのrandomを利用する例:

直径10の円を左から右に向かって、順番に描きます。円を描く上下の位置を乱数で取得しています。

<出力サンプル>

 

JavaのRandomクラスを利用する例:

先程の例を、JavaのRandomクラスを使って実装したものです。

<出力サンプル>

 

JavaのMath.randomを利用する例:

JavaのMath.randomを利用しています。Math.randomは double 型の値を戻すため、floatにキャストしています。

<出力サンプル>

 

sfmtライブラリを使う例:

和田維作のホームページ 様に紹介されている Sfmt.java が組み込まれている事が前提です。

プログラム実行時のミリセカンドを seedとして与えています。

<出力サンプル>

 


 

コラム:乱数について

乱数はとても奥が深い要素です。コンピュータで、完全にバラツキのある予測不能な値を返すのは、とても難しいようです。

上記で挙げた命令はすべて、「擬似乱数(乱数のように見える値)」を返すものになります。

JavaのMath . random( )で発生させる乱数、JavaのRandomクラスを利用した乱数、PROCESSINGのrandom()命令で発生させる乱数は、すべて線形合同法と呼ばれる手法で乱数を発生させています。

このため、値に偏りがあり、同じ数値が現れるまでの周期が短いなどの欠点を持っているため、厳密な用途で使う(統計処理、科学技術計算、暗号化処理など)には向きません。

特に、JavaのRandomクラスとPROCESSINGのrandom()命令については、連続して出る値にかなりの偏りがあるため、バラバラである事が重要な意味をもつゲームなどでも、利用は避けたほうが良いでしょう。

じゃぁ、Javaで精度の高いバラツキがある乱数が欲しい時はどーするのさ?・・・という事になりますが、真面目にやるならメルセンヌ・ツイスタ法、または XorShift 法を使うのがオススメです。

ゲームなどライトな用途で使う場合でも、標準のrandom命令よりは、Math.randomを使うほうがマシでしょう(汗)。

また暗号化処理などに使うのであれば、java.security.SecureRandom クラスを用いるのが良いと言われています。

参考までに、参照させていただいたサイト様を紹介しておきます。

●乱数全般について

●メルセンヌ・ツイスタ法

メルセンヌ・ツイスタ法とXorShift 法については、各言語から利用できるソースプログラムが、上記「和田維作のホームページ 様」に紹介されています。大変助かります。ありがとうございます。

上記で紹介されていた メルセンヌ・ツイスタ法を用いた SfmtライブラリとXorShift ライブラリを試してみましたが、PROCESSINGでもちゃんと動作しました(笑)。

PROCESSINGでSfmtライブラリ等を使う方法については、「コラム:Sfmtライブラリを使う」を参照してください。

 

コラム:Sfmtライブラリを使う

(1)まずライブラリをダウンロードします。

和田維作のホームページ 様」に行き、smft.zip :ライブラリ一式をダウンロードします。

解凍すると SfmtJAVA というフォルダに Sfmt.java というソースコードがありますので、これをエディタで開いて全行コピーします。

(2)PROCESSINGで新規クラスを作成します。

PROCESSINGの標準エディタを開き、スケッチ名のタブの右横にある▼をクリックします。メニューが開くので「新規タブ」を選択します。


タブ名を入力する窓が表示されるので、好きな名前(例:Sfmt)を入力し、OKボタンを押します。

(3)できたタブにSfmt.java の内容を貼り付けます。

 


PROCESSING逆引きリファレンス一覧 へ戻る

本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。