【发布时间】:2020-09-28 11:26:39
【问题描述】:
我有以下练习:
在许多计算机程序中,我们需要一个随机数生成器。这些生成器产生的数字 并不是真正随机的,但它们似乎是随机的。这就解释了为什么这些生成器有时 称为伪随机发生器。这种类型的最简单的生成器之一是所谓的线性 同余 发生器 .这些生成器使用递归生成一系列数字 X_i X_i+1 = (a · X_i + c) mod m。 必须明智地选择参数 a、c 和 m 的值。如果您对如何选择这些值感兴趣,那么您可能需要阅读https://en.wikipedia.org/wiki/Linear_congruential_generator。
在本练习中,我们选择 X_0 = 2773639、a = 25214903917、c = 11 和 m = 2^45。 给出一个无限列表 random :: [Integer] 的 Haskell 实现,它返回的无限列表 这组参数生成的随机数。随机取 n 的时间复杂度应为 在 n 中是线性的。表达式 take 6 random 应导致: [2773639,25693544934790,35087648281,25863180521136,928172761339,19643099434218]
我是 Haskell 的新手,我不知道如何生成一个无限列表,甚至这个函数的参数应该是什么。此外,递归性使其变得更加困难,因为我不确定如何编写基本案例。到目前为止,我已经尝试过:
random :: Int -> [a]
random 0 = 2773639
random x = [x | x <- (25214903917 * random (x-1) + 11 ) `mod` (2^45)]
这显然是有缺陷的,但我无法提出其他建议,因为我没有足够的 Haskell 经验,甚至无法考虑其他可能性。感谢您的宝贵时间!
【问题讨论】:
-
对于无限列表,没有基本情况。由于 Haskell 的惰性,它不会评估下一个项目,如果它不需要另一个项目。
-
提示:您想编写一个函数,返回所有随机数,其中参数是列表中的第一个随机数。提示2:这意味着它返回第一个随机数(参数),然后是从第二个开始的所有随机数(根据第一个计算)。
-
提示:要生成一个无限列表,您可以简单地在尾部递归。例如。
f n = n : f (n+1)将从n开始生成无限的数字列表。您可以尝试调整这条线路以满足您的需求。 -
提示:
random (x -1)与X_{i-1}不同。您需要访问先前的值,例如使用显式递归函数或 zip。 -
谢谢你,我终于可以做到了!
标签: haskell functional-programming