如何在Scheme中生成随机数?有特殊形式还是我必须创建一个程序?如果是这样,我该怎么做? (我正在尝试创建一个名为random-choice的过程,它输入两个策略并随机返回一个。)
答案 0 :(得分:6)
标准方案不提供随机数生成器,虽然大多数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)
。
有时你想要一个范围内的随机整数。下面显示的randint
函数会将 lo (包括)范围内的随机整数返回到 hi (不包括); 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)"))))
这些随机数对于简单模拟来说已经足够了,但要注意它们不适合加密应用程序。如果您有兴趣,我会在my blog有几个随机数生成器,包括一些适用于加密应用程序的生成器。
答案 1 :(得分:5)
令人惊讶的是,random
调用了该过程 - 尽管确切的语法可能会有所不同,具体取决于使用的Scheme解释器(请阅读文档!),但总体思路如下:
(random)
=> 0.9113789707345018
如果要返回两个可能值中的一个,这将在Racket中完成:
(define (random-choice a b)
(if (zero? (random 2)) a b))
请注意,传递给2
的{{1}}参数会强制它随机返回两个可能值中的一个:random
或0
。因此,如果1
评估为(random 2)
,则会返回0
,否则会返回a
。
b
答案 2 :(得分:1)
由于您的另一个问题是关于在DrRacket中实施太空飞船游戏,我将假设,您通过Scheme表示DrRacket中的一种教学语言。
在DrRacket中查找有关可用功能的信息的方法很简单。比如说,在交互窗口中写random
。将光标置于顶部,然后按F1。
htdp-languages中random
的文档在这里:
返回随机值的一种方法:
(list-ref (list "one" "two") (random 2))
这里(随机2)将返回0或1。 因此list-ref将返回条目 使用列表的索引0或索引1。
使用上述方法的优点 是很容易扩展到更多的价值观 不止两个。