1

0 から 9 までの数字の無限ランダム ストリームを作成するのに問題があります。

(#%require (only mzscheme random))
(define (input_stream) (cons (random 9) (delay input_stream)))

唯一の問題は、(random 9)一度だけ開始されるように見えることです。ストリームは確かにランダムですが、ストリームの値は一定のままです。

私は得る7, 7, 7, 7, 73, 3, 3, 3, 3

無限ループが最初からやり直すたびにランダム関数を開始する方法についてのアイデアはありますか? 私はオンラインで検索しましたが、これに取り組む方法が見つかりませんでした。

4

2 に答える 2

3

そのままでは、random再帰的に再度呼び出していないため、プロシージャは 1 回だけ呼び出されますinput_stream。これが、ストリーム内のすべての乱数が実際には同じ数である理由です。新しい値が作成されるたびに疑似乱数ジェネレーターが呼び出されることを保証する必要がありますcons。たとえば、次のようになります。

(define (random-stream n)
  (cons (random n) (delay (random-stream n))))

これで、このストリームには 0 ~ 9 の範囲の乱数が含まれます。

(define input_stream (random-stream 10))

注:n生成されたストリームをパラメーター化できるように、パラメーター jut として定義しました。固定値でも同様に機能します。

(define (random-stream)
  (cons (random 10) (delay (random-stream))))

(define input_stream (random-stream))

たとえば、最初の 3 つの要素にアクセスするには、次のようにします。

(car input_stream)
=> 9 ; random number between 0-9
(car (force (cdr input_stream)))
=> 7 ; random number between 0-9
(car (force (cdr (force (cdr input_stream)))))
=> 8 ; random number between 0-9

mまたは一般的に、 0 (含む) から (含まない) までのランダムな要素のリストを生成するにはn:

(define (stream-take s m)
  (if (zero? m)
      '()
      (cons (car s)
            (stream-take (force (cdr s)) (sub1 m)))))

(stream-take (random-stream 10) 20)           ; n=10, m=20
=> '(3 3 3 7 0 7 3 2 3 7 6 0 6 4 1 4 6 1 6 9) ; 20 random numbers between 0-9
于 2013-07-02T16:52:49.063 に答える
3

(random n) を繰り返し呼び出すだけで同じ効果が得られるため、ランダムなストリームを作成することがどれほど意味があるかはわかりません。

しかし、ストリームを作成する良い方法は、stream-consを使用することです:

#lang racket

;;; infinite stream of random numbers
(define (random-stream n)
  (stream-cons 
   (random n) 
   (random-stream n)))

ストリームをどのように消費するかは重要です。間違えると毎回最初の数を取得する可能性があるためです。

(define S (random-stream 10))

;;; right 
(for/list ((i (range 5)))
  (stream-ref S i))
=> '(7 1 4 8 4)

;;; right
; primitive to take the first n elements of a stream
(define (stream-take s n)
  (for/list ((e s) (i (in-range n)))
    e))
(stream-take S 20)  
=> '(7 1 4 8 4 3 9 8 6 8 4 8 1 1 1 7 0 3 9 4)

;;; wrong
(for/list ((i (range 5)))
  (stream-take S 1))
=> '((7) (7) (7) (7) (7))
于 2013-07-02T18:13:05.127 に答える