我是随机算法的新手,通过阅读书籍自己学习。我正在读一本由Mark Allen Wessis撰写的数据结构和算法分析书
假设我们只需要翻硬币;因此,我们必须生成0或1 随机。一种方法是检查系统时钟。时钟 可能会将时间记录为计算秒数的整数 从1970年1月1日开始(至少在Unix系统上)。然后我们可以使用 最低位。问题是如果一个序列,这不能很好地工作 需要随机数。一秒钟是很长一段时间 程序运行时可能根本不会改变。即使是时候 如果程序正在运行,则以微秒为单位记录 本身将产生的数字序列将是远的 从随机的,因为调用发电机之间的时间 每个程序调用基本相同。那么,我们看到了 真正需要的是一系列随机数。这些数字 应该是独立的。如果翻转硬币并出现头部, 下一个硬币翻转应该同样可能会出现在头部或者 尾巴。
以下是关于上述文字摘要的问题。
在上面的文字片段“我们可以使用最低位的计数秒数”,作者提到这不起作用,因为一秒钟很长时间, “时钟可能根本不会改变”,我的问题是,为什么一秒钟很长时间,时钟会每秒都改变,而作者提到的背景是什么 那个时钟不会改变?请求帮助理解简单的例子。
作者如何提及即使是微秒我们也没有获得随机数序列?
谢谢!
答案 0 :(得分:2)
使用随机(或在本例中为伪随机)数字的程序通常需要在短时间内使用它们。这就是为什么简单地使用时钟并不真正起作用的一个原因,因为系统时钟没有像你的代码请求新数字那样快速更新,因此很可能一次又一次地得到相同的结果,直到时钟变化。它在Unix系统上可能更明显,通常的获取时间的方法只能提供第二精度。甚至微秒也没有真正帮助,因为计算机比现在更快。
您要避免的第二个问题是伪随机值的线性依赖性。想象一下,你想要随机地在一个正方形中放置一些点。您将选择 x 和 y 坐标。如果你的伪随机值是一个简单的线性序列(就像你从一个时钟中得到的那样),你会得到一条对角线,在同一个地方有许多点聚集在一起。这确实不起作用。
最简单类型的伪随机数生成器之一,Linear Congruental Generator也有类似的问题,即使它初看起来并不那么明显。由于非常简单的公式
你仍然可以得到相当可预测的结果,虽然只有你在3D空间中选择点,因为所有数字都位于许多不同的平面上(所有伪随机生成器都出现在某个维度上的问题):
答案 1 :(得分:1)
电脑很快。我过度简化,但如果您的时钟速度以GHz为单位测量,它可以在1秒内完成数十亿次操作。相对来说,1秒钟是永恒的,所以它有可能不会改变。
如果您的程序正在进行常规操作,则无法保证随机抽样时钟。因此,您不会得到随机数。
答案 2 :(得分:0)
不要忘记,对于一台电脑来说,一秒钟可以是“永恒的”。程序/算法通常在几毫秒内执行。 (千分之一秒。)
以下伪代码:
for(int i = 0; i < 1000; i++)
n = rand(0, 1000)
使用0到1000之间的随机数填充一千次。在典型的机器上,此脚本几乎立即执行。
虽然您通常只在开头初始化种子:
以下伪代码:
srand(time());
for(int i = 0; i < 1000; i++)
n = rand(0, 1000)
初始化种子一次,然后执行代码,生成一组看似随机的数字。当您多次执行代码时,就会出现问题。让我们说代码在3毫秒内执行。然后代码再次以3毫秒的速度执行,但两者都在同一秒内执行。结果是一组相同的数字。
关于第二点:作者可能假定一台快速计算机。上述问题仍然存在......
答案 3 :(得分:0)
他的意思是,您无法控制计算机或任何其他计算机运行代码的速度。
因此,如果你建议1秒执行远远没有任何东西。如果你试图自己运行代码,你会发现这是在几毫秒内执行的,所以即使这样也不足以确保你得到随机数!