6

如何在 Scheme 中生成随机数?是否有特殊表格或者我必须创建一个程序?如果是这样,我该怎么做?(我正在尝试创建一个名为 random-choice 的过程,它输入两种策略并随机返回一个。)

4

3 回答 3

9

标准 Scheme 不提供随机数生成器,尽管大多数 Scheme 实现都提供了一个,但它们的细节往往不同。如果你想编写一个可移植的 Scheme 程序,构建自己的随机数生成器很容易;这是由于 Knuth 的一种方法:

(define random
  (let ((a 69069) (c 1) (m (expt 2 32)) (seed 19380110))
    (lambda new-seed
      (if (pair? new-seed)
          (set! seed (car new-seed))
          (set! seed (modulo (+ (* seed a) c) m)))
      (/ seed m))))

调用(random)返回 0(包括)和 1(不包括)之间的随机分数。随机分数以周期m循环。调用(random seed)重置随机数生成器的种子,这样从同一个种子开始的两个随机序列将是相同的;YYYYMMDD 形式的日期是很好的种子(上面是 Knuth 的生日)。如果你想掷硬币,说:(if (< (random) 1/2) 'heads 'tails)

有时你想要一个范围内的随机整数。下面显示的函数返回lo(包括)到hirandint (不包括)范围内的随机整数;lo默认为 0:

(define (randint . args)
  (cond ((= (length args) 1)
          (floor (* (random) (car args))))
        ((= (length args) 2)
          (+ (car args) (floor (* (random) (- (cadr args) (car args))))))
        (else (error 'randint "usage: (randint [lo] hi)"))))

诸如此类的随机数对于简单的模拟来说已经足够了,但要注意它们不适合加密应用。如果您有兴趣,我的博客上有几个随机数生成器,包括一些适用于加密应用程序的随机数生成器。

于 2013-02-03T17:25:19.910 回答
6

令人惊讶的是,该过程被调用random- 尽管确切的语法可能因使用的 Scheme 解释器而异(阅读文档!),但总体思路如下:

(random)
=> 0.9113789707345018

要返回两个可能值之一,这将在 Racket 中发挥作用:

(define (random-choice a b)
  (if (zero? (random 2)) a b))

请注意,2传递给的参数random强制它随机返回两个可能值之一:01。因此,如果(random 2)评估为0a返回,否则b返回。

(random-choice 4 2)
=> 4
(random-choice 4 2)
=> 2
于 2013-02-03T15:48:11.770 回答
1

由于您的另一个问题是关于在 DrRacket 中实现宇宙飞船游戏,我假设您所说的方案是指 DrRacket 中的一种教学语言。

在 DrRacket 中查找可用功能信息的方法很简单。比如说,random在交互窗口中写。将光标放在顶部,然后按 F1。

关于 htdp-languages的文档在random这里:

http://docs.racket-lang.org/htdp-langs/beginner.html?q=random#(def.htdp-beginner. ( (lib._lang/htdp-beginner..rkt)._random))

返回随机值的一种方法:

(list-ref (list "one" "two") (random 2))

这里(随机 2)将返回 0 或 1。因此,list-ref 将返回索引为 0 或索引为 1 的条目。

使用上述方法的优点是很容易扩展到多于两个的值。

于 2013-02-03T18:40:57.010 回答