乱数:メルセンヌツイスター

参考にさせていただいたページ。
http://sicp.g.hatena.ne.jp/hyuki/20060503/mt


systime使っているけどメルセンヌツイスターになっているのだろうか?
僕にはよーわかりません。

gosh> (use math.mt-random)
#<undef>
gosh> (define mt (make <mersenne-twister> :seed (sys-time)))
mt
gosh> (mt-random-integer mt 1000)
430
gosh> (mt-random-integer mt 1000)
39

思ったよりずっとあっさり出来てしまった。

ついでに剰余も

gosh> (modulo (mt-random-integer mt 100) 24)
15
gosh> (modulo (mt-random-integer mt 100) 24)
0
gosh> (modulo (mt-random-integer mt 100) 24)
19

考えてみれば剰余はいらないことに気がつく(Cの癖が出てしまった)。

gosh> (modulo (mt-random-integer mt 100) 24)

とするぐらいなら

gosh> (mt-random-integer mt 24)

とすればいいのでした。

とりあえず、終端記号のa〜zまでをランダムに出力するコード

シンプルなコード↓(mixiで教えていただきました)

(use math.mt-random)

(define mt (make <mersenne-twister> :seed (sys-time)))

(define (terminal)
  (let ((rdm (mt-random-integer mt 26) ))
    (string-ref "abcdefghijklmnopqrstuvwxyz" rdm)))

もしくは

(use math.mt-random)

(define mt (make <mersenne-twister> :seed (sys-time)))

(define (terminal)
  (let ((rand (mt-random-integer mt 26) ))
    (integer->char (+ rand 97))))          ;97はa

最初に考えたコード↓

(use math.mt-random)

(define mt (make <mersenne-twister> :seed (sys-time)))

(define (terminal)
  (let ((rand (mt-random-integer mt 26) ))
    (cond ((eq? rand 0) 'a)
          ((eq? rand 1) 'b)
          ((eq? rand 2) 'c)
          ((eq? rand 3) 'd)
          ((eq? rand 4) 'e)
          ((eq? rand 5) 'f)
          ((eq? rand 6) 'g)
          ((eq? rand 7) 'h)
          ((eq? rand 8) 'i)
          ((eq? rand 9) 'j)
          ((eq? rand 10) 'k)
          ((eq? rand 11) 'l)
          ((eq? rand 12) 'm)
          ((eq? rand 13) 'n)
          ((eq? rand 14) 'o)
          ((eq? rand 15) 'p)
          ((eq? rand 16) 'q)
          ((eq? rand 17) 'r)
          ((eq? rand 18) 's)
          ((eq? rand 19) 't)
          ((eq? rand 20) 'u)
          ((eq? rand 21) 'v)
          ((eq? rand 22) 'w)
          ((eq? rand 23) 'x)
          ((eq? rand 24) 'y)
          (else 'z))))

冗長かも、ループ使って短く出来そうな…
だれか、突っ込みあったらお願いします。

とりあえず、非終端記号をランダムに出力するコード

  • 現在の非終端記号
    • car, cdr, cons, quote, set!, cond, define, eq?, list?
(use math.mt-random)

(define mt (make <mersenne-twister> :seed (sys-time)))

(define (non-terminal)
  (let ((rdm (mt-random-integer mt 9) ))
    (cond ((eq? rdm 0) 'car)
          ((eq? rdm 1) 'cdr)
          ((eq? rdm 2) 'cons)
          ((eq? rdm 3) 'quote)
          ((eq? rdm 4) 'set!)
          ((eq? rdm 5) 'cond)
          ((eq? rdm 6) 'define)
          ((eq? rdm 7) 'eq?)
          (else 'list?)))))

初期集団の木構造の生成(Initialization)を考慮した、非終端記号をランダムに出力するコード

  • 現在の非終端記号
    • car, cdr, cons, quote, define, if, eq?, list?
      • condをifに、代入演算(バインド)はset!を削ってdefine単体のみとする。condは引数の数を決定できないうえに、構文的束縛が強いのでランダムに木構造を作るのは難しい。atomatomかlistをバインドする場合、最初はdefineでなければ不可能、set!はバインドの変更はできるが、新しいバインドを作れない。
(use math.mt-random)

(define mt (make <mersenne-twister> :seed (sys-time)))

(define (non-terminal)
  (let ((rand (mt-random-integer mt 8) ))
    (cond ((eq? rand 0) 'car)
          ((eq? rand 1) 'cdr)
          ((eq? rand 2) 'cons)
          ((eq? rand 3) 'quote)
          ((eq? rand 4) 'define)
          ((eq? rand 5) 'if)
          ((eq? rand 6) 'eq?)
          (else 'list?)