如何在 Scheme 中生成随机数?是否有特殊表格或者我必须创建一个程序?如果是这样,我该怎么做?(我正在尝试创建一个名为 random-choice 的过程,它输入两种策略并随机返回一个。)
3 回答
标准 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)"))))
诸如此类的随机数对于简单的模拟来说已经足够了,但要注意它们不适合加密应用。如果您有兴趣,我的博客上有几个随机数生成器,包括一些适用于加密应用程序的随机数生成器。
令人惊讶的是,该过程被调用random
- 尽管确切的语法可能因使用的 Scheme 解释器而异(阅读文档!),但总体思路如下:
(random)
=> 0.9113789707345018
要返回两个可能值之一,这将在 Racket 中发挥作用:
(define (random-choice a b)
(if (zero? (random 2)) a b))
请注意,2
传递给的参数random
强制它随机返回两个可能值之一:0
或1
。因此,如果(random 2)
评估为0
则a
返回,否则b
返回。
(random-choice 4 2)
=> 4
(random-choice 4 2)
=> 2
由于您的另一个问题是关于在 DrRacket 中实现宇宙飞船游戏,我假设您所说的方案是指 DrRacket 中的一种教学语言。
在 DrRacket 中查找可用功能信息的方法很简单。比如说,random
在交互窗口中写。将光标放在顶部,然后按 F1。
关于 htdp-languages的文档在random
这里:
返回随机值的一种方法:
(list-ref (list "one" "two") (random 2))
这里(随机 2)将返回 0 或 1。因此,list-ref 将返回索引为 0 或索引为 1 的条目。
使用上述方法的优点是很容易扩展到多于两个的值。