兰德() : 奇怪的行为
rand() : weird behavior
本文关键字:兰德 更新时间:2023-10-16
我正在对一个问题进行数值模拟,我需要首先生成一个包含 N/2 0 和其他 1 的 N 个元素数组。每次迭代时,数组被洗牌,下一个数组元素从上一次迭代中随机选择,直到只剩下 0 或 1。我正在记录 T 次试验中的迭代次数。为了生成随机整数,我正在使用rand()
的丢弃模方法(从这里得到这个想法(。
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <fstream>
#include <algorithm>
#include <array>
using namespace std;
//generate random integer between 0 and MAX
int randomn(int MAX);
int main()
{
const int N = 10000;
const int T = 100; //Number of trials
srand((unsigned)time(0));
ofstream writefile ("Observation.out");
for (int indexT = 0; indexT < T; indexT++) {
//initializing myArray
array<bool, N> myArray;
array<bool, N> newArray;
auto middle = myArray.begin() + myArray.size() / 2;
fill(myArray.begin(), middle, false);
fill(middle, myArray.end(), true);
int counterIt = 0; //desired Iteration number
for (;;) {
int counterF = 0;
int randompos = 0;
bool savedata = true;
//suffling myArray using Fisher–Yates shuffle
for (int indexN = N-1; indexN > 0; indexN--) {
randompos = randomn(indexN);
savedata = myArray[randompos];
myArray[randompos] = myArray[indexN] ;
myArray[indexN] = savedata;
}
//next Iteration
for (int indexN = 0; indexN < N; indexN++) {
randompos = randomn(N-1);
savedata = myArray[randompos];
newArray[indexN] = savedata;
if (savedata == false){
counterF += 1;
}
}
copy(begin(newArray), end(newArray), begin(myArray));
//updating Iteration number
counterIt += 1;
if ((counterF == 0)|| (counterF == N)) {
break;
}
}
writefile << indexT+1 <<"t"<<counterIt <<endl;
}
writefile.close();
return 0;
}
int randomn (int MAX){
int temp;
for (;;){
temp = rand();
if ( temp < RAND_MAX - RAND_MAX%(MAX+1) )
return temp%(MAX+1);
}
}
输出非常有趣。输出中的前几个数字(每次试验的迭代次数(不同,但无论我运行多少次,它都会收敛为振荡。 下面是输出的两个示例:
1st run 2nd run
1 28278 1 13583
2 7754 2 7308
3 11308 3 22580
4 5093 4 6307 ** oscillation starts
5 4952 5 42060
6 5017 6 10485
7 10400 7 8525
8 6307 ** 8 31061
9 42060 9 6307 ** 1st period
10 10485 10 42060
11 8525 11 10485
12 31061 12 8525
13 6307 ** 13 31061
14 42060 14 6307 ** 2nd period
15 10485 15 42060
现在我知道rand()
不是这项工作的最佳函数(更好的选择是 c++11 中的<rand>
库(。 但是它是如何从任何初始随机数收敛到这个确切周期的6307 - 42060 - 10485 - 8525 - 31061
?
观察:程序在该时间段内精确地使用2^31
随机数,即随机数生成函数的周期。但是怎么做呢?
rand()
不应该用于任何严肃的事情。它的质量可能很差。
例如,我用它做了一个模拟,我知道确切的答案。随着rand()
,模拟收敛到一个与确切答案略有不同的数字。我用更好的东西替换了rand()
,并且:
- 仿真速度提高 3 倍
- 仿真收敛到精确的解决方案。
一个常见的建议是改用梅森纳捻线机。然而,即使是MT也有其缺点,它没有通过BigCrush测试。
然而,这个简单的随机生成器通过,而且非常快(xorshift128+(:
uint64_t s[2]; // seed this
uint64_t next(void) {
uint64_t s1 = s[0];
const uint64_t s0 = s[1];
const uint64_t result = s0 + s1;
s[0] = s0;
s1 ^= s1 << 23; // a
s[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5); // b, c
return result;
}
查看 http://xoroshiro.di.unimi.it/,以及他们最新的发电机xoroshiro128+
相关文章:
- 为什么兰德每次都给我几乎相同(但略有不同)的数字
- 如何使用兰德随机化模拟点击
- 兰德() : 奇怪的行为
- 我如何确保我的随机数在兰德生成的0和1之间不是0
- 兰德()创造一个奇怪的结果
- 兰德()使我的IDE崩溃
- 如何给兰德()提供条件
- 难道博兰德C++不C++吗?
- 库达库兰德"An illegal memory access was encountered"
- ASIO::async_write和斯特兰德
- 兰德产生相同的数字
- 兰德函数,生成3个值的概率(用于简单的老虎机)
- 博兰德C++链接器错误c文件包括
- 海湾合作委员会中的博兰德风格__closure
- 杜兰德-克纳方法寻找非线性方程的根
- 斯堪夫在博兰德C++建造者
- C++中的"兰德"功能?
- 兰特、乌兰德和伊朗在 C/C++ 中有什么区别?
- 为什么兰德种子没有改变结果?
- 兰德函数不"defined"