c++中的线性同余生成器
Linear congruential generator in C++
我写了一个简单的程序(试图实现线性同余生成器实际上),但我不太确定它应该像它一样工作。
我想用我的生成器从[0,1]生成250个数字。然而,我得到的似乎不是随机数,而是相等的值。
如何改进它/我做错了什么?
代码如下:
#include <iostream>
#include <cmath>
static const double A = 0.001342;
static const double C = 0.00025194;
static const double RAND_MAX = 1.0;
double rand()
{
static double prev = 0;
prev = A * prev + fmod(C, RAND_MAX);
return prev;
}
int main(int argc, char **argv)
{
for(int i=0; i<6; i++)
std::cout << rand() << "n";
return 0;
}
输出:
0.00025194
0.000252278
0.000252279
0.000252279
0.000252279
0.000252279
切换到int
而不是double
,但是会得到一些不错的结果:
#include <iostream>
#include <cmath>
static const int A = 5;
static const int C = 3;
static const int RAND_MAX = 8;
double rand()
{
static int prev = 1;
prev = A * prev + (C % RAND_MAX);
return prev;
}
int main(int argc, char **argv)
{
for(int i=0; i<100; i++)
std::cout << rand() << "n";
return 0;
}
输出:8
43
218
1093
5468
27343
136718
683593
3.41797e+06
1.70898e+07
8.54492e+07
4.27246e+08
2.13623e+09
2.09122e+09
1.86615e+09
7.40836e+08
-5.90786e+08
1.34104e+09
...
但是我需要它来生成大于等于0小于等于1的随机双位数:(
不是程序的问题,而是数字的选择。
prev
一开始等于0,所以第一个数字变成C
。
则prev
= C
,优先于A*C + C
。然而,A*C
太小了,当把它作为浮点数加到前一个浮点数上时,有效数字被移出,剩下的就是之前的数字。
你可以阅读更多关于浮点运算的知识
首先,不要对LCG使用浮点运算。浮点本质上是不精确的,并且可能导致不期望的行为,例如定点收敛或交错的短子周期。使用整数算法,数论可以告诉您哪些参数保证实现完整循环,即在0到M-1(其中M是您的模数)之间的每个值将获得。关于lcg的全周期参数要求和常用参数表,请参阅Wikipedia文章。
第二,你误解了LCG公式。应该是:
prev = (A * prev + C) % M;
第三,在你当前选择的参数下,你不会遇到这种情况,但通常你的中间计算应该用long
来完成,以避免溢出。%
运算将把答案带回int
,但如果你坚持使用int
运算,乘法可能不会产生数学上正确的值,从而保证完整的周期长度和正确的分布行为。
相关文章:
- 向量上的线性搜索
- 二叉搜索如何比线性搜索更快?
- 线性丢番图方程 - 求给定区间内的解数和解
- 查找自动生成键并具有线性内存消耗的小型关联数组
- 为什么字符串比较的 == 运算符相对于任一字符串长度线性时间(似乎)?
- 线性优化目标函数中的绝对值
- 犰狳C++:带有模量计算的线性组合
- C++(线性搜索和排序)
- 一般采用可索引/可调用的线性组合
- C++线性搜索算法,确定数组中元素的数量
- 如何在 c++ 中线性搜索两个数组?
- 生成线性随机整数C++
- 使用本征求解线性方程组
- 在 SEAL 中重新线性化一个密文
- 如何在C++中实现线性探测?
- C++ 本征线性系统求解,数值问题?
- 曼哈顿距离比曼哈顿距离+线性冲突效果更好
- 变量未在此范围内声明 数组线性搜索
- 线性全余生成器的分析是错误的吗?
- c++中的线性同余生成器