それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

10分に一回ランダムで表示が変わるような乱数を作る。

表題の通りを実現したい。10分に一回ランダムに表示が切り替わるるようにしたい。

乱数だと、毎回実行時に値が変わってしまう。かといって乱数の結果を10分間キャッシュはちょっと違う。同じURLにアクセスして、同じ結果がでるようにシンプルに設計するには、乱数の出力を10分間同じに固定すればいい。

数分間同じ値を返すには

乱数のシードを10分間同じにする。

そもそも乱数とは、

乱数はシードが同じなら毎回同じパターンの乱数が返ってくる。以下のプログラムを実行すると

  1 <?php
  2
  3
  4 ini_set('date.timezone',"Asia/Tokyo");
  5 $time = strtotime("2012-04-11 11:11:11");
  6 srand($time);
  7
  8 foreach(range(0,9) as $i){
  9     echo rand(0,10) . "\n";
 10 }
 11

実行結果

3回実行しても毎回乱数は同じ。

takuya@air:~/Desktop$ php test.php
1
8
takuya@air:~/Desktop$ php test.php
1
8
8
takuya@air:~/Desktop$ php test.php
1
8
8

何度実行しようが乱数の結果は同じ。「結果。同じ」。コンピューターの世界では大事なことです。冪等性です。

シードが同じ=乱数も同じ

シードが同じなら、毎回同じパターンで乱数が出てくる。これは基本ですよね。

それをちょっと応用して、1分間毎にシードをかえると、1分ごとにランダムに表示が変わるってことが出来る。

1分ごとに乱数のシードを入れ替える

1分ごとに乱数のシードを入れ替えれば、1分間同じ結果が返ります。

  1 <?php
  2
  3
  4 ini_set('date.timezone',"Asia/Tokyo");
  5 $date_str = date('Y-m-d H:i:00');# 1分間毎に変わる。
  6 echo $date_str;
  7 $time = strtotime($date_str);
  8 srand($time);
  9
 10 foreach(range(0,9) as $i){
 11     echo rand(0,10) . "\n";
 12 }
 13

そもそも、乱数というのはコンピューターは苦手で、あるシード値に対して値を生成して乱数を”作る”わけだから、
シード値が同じなら乱数は同じですね。

phpの場合は

srand 関数でシードを固定するようです。

感想

昔つかってた音楽プレーヤーのランダム再生が同じパターンで再生を繰り返すランダムだった。同じCDならランダムは毎回同じ順から始まるのだった。パイオニア製品の設計者はランダムの意味をわかってなかったんだろうなと思う。

ランダムが乱数にならないのであれば、とても恐ろしいことです。

ネトゲや、スマホのクリックゲーの乱数生成で、シードがわかれば、出現確率がわかりますよね。