mathematica 发表于 2010-2-27 11:38:44

HugeCalc的随机数算法有多可靠?

随机数使用了什么算法?该算法有多可靠?请给出相关的定理。
千万别回答我相当可靠之类的话,我基本上不相信别人,只相信定理。

随机数产生的结果和哪些因素有关?和硬盘之类的因素有关吗?
似乎加密软件的随机数的种子的产生之前,还要不断地晃动鼠标。

还有就是随机数的产生周期之类的问题,似乎MATLAB的产生
重复的随机数的周期特别大,以致于宇宙毁灭掉都不会产生重复
的随机数。

在这里也可以讨论讨论随机数的产生的算法之类的问题

mathematica 发表于 2010-2-27 11:39:40

pari/gp的随机数的产生周期也很长,具体我忘记了

qianyb 发表于 2010-2-27 12:31:02

随机数产生跟晃动鼠标有什么关系吗?
随机数产生跟时间应该有关系吧

wayne 发表于 2010-2-27 12:46:20

随机数的产生跟时间也应该无关系吧
只是我们平时都喜欢把程序运行的当前时间作为种子。。。

KeyTo9_Fans 发表于 2010-2-27 13:21:34

晃动鼠标时,鼠标指针的坐标参数变化是一列性质良好的随机数。

这列随机数的产生速度比抛硬币、投骰子快多了:lol

千万别用C++标准库里自带的rand()函数,这个rand()函数太挫了。

比如下面这段代码……#include<cstdio>
#include<cstdlib>

int rand16()        //生成一个0到15的随机数
{
        return rand()%16;
}

char rand_ch()        //把两个0到15的随机数拼成一个字节
{
        return rand16()*16+rand16();
}

int main(int i)
{
        freopen("d:\\rand.txt","wb",stdout);
        for(i=0;i<16777216;i++)        //输出16M字节
                printf("%c",rand_ch());
        return 0;
}生成的16MB的文件拿winRAR软件压缩一下就只剩522KB了,说明rand()生成的随机数很糟糕。

难怪拿去做各种不确定性试验时,出现一连串雷同的试验结果。

如果说一个随机数列是好的,那么它:

每一项的取值都是分布均匀的;
相邻两项组成的二元组是分布均匀的;
相邻三项组成的三元组是分布均匀的;
……
相邻N项组成的N元组是分布均匀的。

如果上述条件有一个不满足,就说明这个数列的熵值未达到最大,可以用哈夫曼编码进行压缩。

WinRAR软件已经在一定程度上实现了这一功能,所以可以根据WinRAR软件的压缩结果来衡量一个随机数列的好坏。

对于好的随机数列,其熵值一定是最大化的,WinRAR软件是一个字节都压不动的。

要加长随机数列的周期,可以通过添加辅助变量的方法。

把上述代码修改如下:#include<cstdio>
#include<cstdlib>

unsigned int s;        //辅助变量

int rand16()        //生成一个0到15的随机数
{
        s=s*s+s/13+rand();
        return s%16;
}

char rand_ch()        //把两个0到15的随机数拼成一个字节
{
        return rand16()*16+rand16();
}

int main(int i)
{
        freopen("d:\\rand.txt","wb",stdout);
        for(i=0;i<16777216;i++)        //输出16M字节
                printf("%c",rand_ch());
        return 0;
}虽然只做了小小的改动,但生成出来的16MB的文件用winRAR压缩,一个字节都压不动了。

因为添加辅助变量后,即使rand()函数跑完了一个周期,但辅助变量的值与初值不同,所以生成出来的数是不同的。

要等到rand()函数跑完了一个周期的同时,辅助变量恰好回到原始初值,才是一个完整的周期。

显然这个周期远比单独使用rand()函数的周期长。

添加辅助变量需要额外的运算量。

所以要根据实际的需要来选取合适的辅助变量个数以及计算公式,在生成速度与周期长度两者之间进行权衡。

qianyb 发表于 2010-2-27 13:25:18

原来如此,又学到一项新知识了,谢谢

mathematica 发表于 2010-2-27 13:36:42

晃动鼠标时,鼠标指针的坐标参数变化是一列性质良好的随机数。

这列随机数的产生速度比抛硬币、投骰子快多了:lol

千万别用C++标准库里自带的rand()函数,这个rand()函数太挫了。

比如下面这段代码……#incl ...
KeyTo9_Fans 发表于 2010-2-27 13:21 http://bbs.emath.ac.cn/images/common/back.gif


原来winrar的压缩效果还与这个有关,以前只知道加密软件产生随机数的种子的时候需要不断晃动鼠标。看来即使是随机数,里面也有很大的学问呀

gxqcn 发表于 2010-2-27 15:47:26

HugeCalc 的随机数算法部分参考了 Donald E.Knuth 的《计算机程序设计艺术》Vol.2

Frankenstein 发表于 2010-2-28 15:25:15

# unsigned int s;      //辅助变量
#

# int rand16()      //生成一个0到15的随机数
# {
#         s=s*s+s/13+rand();
#         return s%16;
# }


这个办法确实很好啊。以前都没有这方面的思考

mathematica 发表于 2010-2-28 15:33:04

弄了半天,我还是不知道郭的随机数的算法,其实随机数的生成在加密软件中是很重要的。我不知道郭使用什么算法,希望能给出一个有效链接。如果一个随机数很容易被猜到或者循环的周期很短,其实这种随机数的算法是很失败的。
页: [1] 2
查看完整版本: HugeCalc的随机数算法有多可靠?