kai*_*ong 6 c++ random-seed mt19937
<random>C++中有确定性随机数生成器吗?
有问题的一点是我的 Windows 机器上的以下代码:
#include<iostream>
#include<random>
int main(){
std::mt19937 g;
std::normal_distribution<double> d;
for(int i=0;i<100;++i){
g.seed(65472381);
std::cout << "List[65472381] = " << d(g) << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
产生以下结果:
List[65472381]=0.972683
List[65472381]=-0.773812
List[65472381]=0.972683
List[65472381]=-0.773812
List[65472381]=0.972683
List[65472381]=-0.773812
...
Run Code Online (Sandbox Code Playgroud)
我的困惑在于,尽管使用了之前每次0.972683 != -0.773812重置的种子。65472381g
我的处理器是Zen 2,操作系统是 Windows 10 Pro,版本 22H2。编译器是GCC(x86_64-w64-mingw32/12.2.0)。但通过在不同的虚拟机和编译器上在线测试代码,结果似乎在您的计算机上也可能是相同的。
我真正寻求的是一种从任意固定通用列表中获取第 i 个数字的方法,该通用列表长度为 4,294,967,295,随机分布的数字在 SPACETIME O(1) 中,这意味着该列表中没有任何元素被存储。
tbx*_*are 12
分发对象具有内部状态。因此,在重新设置随机数引擎种子后,必须重置分布以清除其内部状态。对于标准库中的所有引擎和发行版都是如此。一般来说,当您为引擎播种时,您还应该重置发行版。
#include<iostream>
#include<random>
int main() {
std::mt19937 g;
std::normal_distribution<double> d;
for (int i = 0; i < 10; ++i) {
g.seed(65472381);
d.reset();
std::cout << "List[65472381] = " << d(g) << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
List[65472381] = -0.773812
Run Code Online (Sandbox Code Playgroud)
discard功能?此 Stack Overflow 问题的答案解释了 Mersenne Twister 有一个“快速跳转”算法。这意味着高效的discard功能是可能的。不幸的是,C++ 标准并不强制要求实现使用它。
您可能会发现您的系统具有高效的discard. 但是,您不能假设每个系统都会这样做。
如果您决定使用discard,请务必随后重置发行版。否则,不能保证分布生成的值是可重复的。
std::mt19937便携式的吗?正如我在下面的评论中指出的,C++ 标准要求std::mt19937可移植。它必须在每次实现时生成相同的随机数序列。
我使用以下程序从 生成 10 个值std::mt19937。我用最新版本的 MSVC 运行它。如果您在您的系统上运行它,您应该得到相同的输出。
#include<iostream>
#include<random>
int main() {
std::mt19937 g;
unsigned seed{ 65472381u };
g.seed(seed);
std::cout << "Seed : " << seed << "\n\n";
for (int i = 0; i < 10; ++i) {
std::cout << "g() : " << g() << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
这是输出。
Seed : 65472381
g() : 3522518833
g() : 1238868101
g() : 1353561095
g() : 3289615924
g() : 1455032182
g() : 573730142
g() : 700682001
g() : 2371867773
g() : 3721872455
g() : 2742745620
Run Code Online (Sandbox Code Playgroud)
无论好坏,C++ 标准并不要求std::normal_distribution每个实现中的分布都相同。一般来说,它们不便于携带。
| 归档时间: |
|
| 查看次数: |
127 次 |
| 最近记录: |