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 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 回答
3

事实上,该random过程只被调用一次,因为您没有input_stream再次递归调用,这就是为什么流中的所有随机数实际上都是相同的数字。您必须保证每次cons'ed 新值时都会调用伪随机数生成器,例如:

(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))

例如,要访问前三个元素:

(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 回答