在不使用内置函数的情况下生成随机数 [关闭]

Posted

技术标签:

【中文标题】在不使用内置函数的情况下生成随机数 [关闭]【英文标题】:Generating random number without using built-in functions [closed] 【发布时间】:2014-08-03 05:41:45 【问题描述】:

我正在为内置函数生成 sn-ps 以了解它们是如何执行的,这也是我研究的一部分。我成功完成了一些字符串处理函数,拆分、子字符串、反向等。但我陷入了随机数,它们是如何生成的? RNDRandom 函数是如何工作的?

提前致谢

【问题讨论】:

在您最喜欢的算法教科书中查找伪随机数生成。流行的例子包括线性反馈移位寄存器、进位乘法和 Mersenne Twister。 “提前感谢您参与本次讨论” - *** 是一个问答网站,而不是论坛...... 有很多方法可以生成伪随机数或(真)随机数。请阅读教科书,或***,或其他东西。如果您想了解 Java 随机数生成器的工作原理,可以阅读源代码。 Google 会为您找到它。 【参考方案1】:

当前最流行的算法可能是Mersenne twister,这是***文章中的伪代码(Google 提供了许多实现)。

另一个众所周知的算法是Blum Blum Shub,它有一个证明可以将其安全性降低到计算模平方根的计算难度,这个问题的难度被假定为与因式分解等价。但是 Blum Blum Shub 非常慢。

最后,here 是一大堆额外的伪随机数生成器。特定语言使用的算法各不相同。

【讨论】:

"algorthm ...varies" 不适用于 Java。请参阅 java.util.Random 中的 javadoc,方法 next。 @Laune 但 c++ 可能使用也可能不使用不同的算法。在你引用的那些词之间是“一种特定的语言使用”。另外,我可以用java写一个新的prng。 请原谅,但发帖者添加了选择语言的标签,Java 就是其中之一。请参阅 javadoc 中的这句话:“为了 Java 代码的绝对可移植性,Java 实现必须使用此处显示的类 Random 的所有算法。” - 请注意,我评论“不是真的 for Java”(而不仅仅是“不是真的”)。 @laune 是的。但是 SecureRandom 和 Math.rand() 是 java 中的替代品。不是我的意思。【参考方案2】:

以下是我在一些项目中最常使用的两种算法:

1.0到1范围内的均匀分布数

result = getRidOfIntegerPart(A * prevResult)

A 是种子。

可能的实现(C++):

int main() 

    double A = 12.2345; //seed
    double prevResult = 1; //You can assign any value here
    double result;
    double intPart;

    //This will give you 10 uniform distributed numbers
    for(unsigned i = 0; i < 10; ++i)
    
        double r = A * prevResult;

        result = modf(r, &intPart); // To get rid of integer part

        prevResult = result;

        cout<<"result "<<i<<" = "<<result<<endl;
    

2。正态(高斯)分布

这是一个原始公式: http://en.wikipedia.org/wiki/Normal_distribution

但我使用了一些不同的简化公式:

表示从12个均匀分布数之和得到新的正态分布数(Sj)

可能的实现(C++):

class RandomNumberGenerator

public:
    RandomNumberGenerator()
    
        uniformPrevResult = 1;
        uniformResult = 0;
        uniformIntPart = 0;
    

    double generateUniformNumber(double seed)
    
        double r = seed * uniformPrevResult;

        uniformResult = modf(r, &uniformIntPart); // To get rid of integer part

        uniformPrevResult = uniformResult;

        return uniformResult;
    

    double generateNormalNumber(double seed)
    
        double uniformSum = 0;

        for(unsigned i = 0; i < 12; ++i)
        
            uniformSum += generateUniformNumber(seed);
        

        double normalResult = uniformSum - 6;

        return normalResult; // 6 is a magic number
    

private:
    double uniformPrevResult;
    double uniformResult;
    double uniformIntPart;
;

int main() 

    const double seed = 12.2345;

    RandomNumberGenerator rndGen;

    for(unsigned i = 0; i < 100; ++i)
    
        double newNormalNumber = rndGen.generateNormalNumber(seed);

        cout<<"newNormalNumber = "<<newNormalNumber<<endl;
    

    return 0;

希望对你有帮助!

【讨论】:

【参考方案3】:

JAva 语言使用 java.util.Random 中记录的算法。它还声明所有实现都必须使用此算法

seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (int)(seed >>> (48 - bits));

因此对于 Java 来说,“特定语言使用的算法不同”是不正确的。

【讨论】:

以上是关于在不使用内置函数的情况下生成随机数 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 OpenCV 中的内置函数翻转的情况下进行翻转?

如何在不使用任何内置高斯函数的情况下对图像进行高斯模糊?

在不使用javascript中的内置函数的情况下逐字反转字符串

如何在不使用内置函数的情况下计算数字的平方根? [重复]

如何在不使用 c# 中的内置函数的情况下获得投球手的最低和最高分数

如何在不指定列名的情况下使用 bigquery 对表中的每一列调用内置函数?