只有 std::mt19937 的实例在 c++11 中重复值
Only instance of std::mt19937 repeats values in c++11
在程序中,通常在不同的类中生成随机数。所以我想创建一个返回生成器 std::mt19937 的单个实例的类。我还考虑到一些编译器无法使用 std::random_device(为此,请检查熵的值(。我创建了一个单例类。
#include <iostream>
#include <random>
#include <chrono>
class RandomGenerator
{
public:
static RandomGenerator& Instance() {
static RandomGenerator s;
return s;
}
std::mt19937 get();
private:
RandomGenerator();
~RandomGenerator() {}
RandomGenerator(RandomGenerator const&) = delete;
RandomGenerator& operator= (RandomGenerator const&) = delete;
std::mt19937 mt;
};
RandomGenerator::RandomGenerator() {
std::random_device rd;
if (rd.entropy() != 0) {
mt.seed(rd());
}
else {
auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
mt.seed(seed);
}
}
std::mt19937 RandomGenerator::get() {
return mt;
}
int main() {
std::mt19937 &mt = RandomGenerator::Instance().get();
std::uniform_real_distribution<double> dist(0.0, 1.0);
for (std::size_t i = 0; i < 5; i++)
std::cout << dist(mt) << "n";
std::cout << "n";
std::mt19937 &mt2 = RandomGenerator::Instance().get();
std::uniform_real_distribution<double> dist2(0.0, 1.0);
for (std::size_t i = 0; i < 5; i++)
std::cout << dist2(mt2) << "n";
return 0;
}
但是当我离开课堂生成器 std::mt19937 时,随机数开始重复。如何避免?
0.389459
0.68052
0.508421
0.0758856
0.0137491
0.389459
0.68052
0.508421
0.0758856
0.0137491
附言有没有比时间更好的方法来初始化生成器?
溶液
在以下编译器下对此进行了测试:Visual Studio,MinGW,DevC ++。
#include <iostream>
#include <random>
#include <chrono>
class RandomGenerator
{
public:
static RandomGenerator& Instance() {
static RandomGenerator s;
return s;
}
std::mt19937 & get();
private:
RandomGenerator();
~RandomGenerator() {}
RandomGenerator(RandomGenerator const&) = delete;
RandomGenerator& operator= (RandomGenerator const&) = delete;
std::mt19937 mt;
};
RandomGenerator::RandomGenerator() {
std::random_device rd;
if (rd.entropy() != 0) {
mt.seed(rd());
}
else {
auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
mt.seed(seed);
}
}
std::mt19937 & RandomGenerator::get() {
return mt;
}
int main() {
std::mt19937 &mt = RandomGenerator::Instance().get();
std::uniform_real_distribution<double> dist(0.0, 1.0);
for (std::size_t i = 0; i < 5; i++)
std::cout << dist(mt) << "n";
std::cout << "n";
std::mt19937 &mt2 = RandomGenerator::Instance().get();
std::uniform_real_distribution<double> dist2(0.0, 1.0);
for (std::size_t i = 0; i < 5; i++)
std::cout << dist2(mt2) << "n";
return 0;
}
std::mt19937 get();
返回一个副本。每次调用get()
时,您都会复制引擎的初始状态。 mt19937
是一个伪随机引擎,每个状态都会产生一个预定的序列。如果两个实例的状态相同,它们将生成相同的序列。使函数返回引用,以便使用生成的每个新数字更新单一实例的状态。
std::mt19937 & RandomGenerator::get() {
return mt;
}
相关文章:
- 在Visual Studio中单实例Qt应用程序版本5.11.1中,在所有其他窗口的顶部打开Qt MainWindow
- 防止复制构造函数实例化 C++11 类"deleting"
- 静态库中只有一个C 11 Singleton的实例
- C++11 列出 push_back() 实例化错误
- 只有 std::mt19937 的实例在 c++11 中重复值
- 如何使用 C++11 unique_ptr实例化我的代码
- 错误:"Class"在其自己的定义中隐式实例化。C++11
- C 11枚举类实例化
- 如何在 C++11 中创建结构的编译时常量实例
- 每个线程一个类实例,C++11
- 如何使用带有实例方法的C++11线程
- C++11风格的SFINAE和模板实例化上的函数可见性
- 释放 C++11 中动态分配的uv_timer_t (libuv) 实例
- 无法使用 c++11 实例化抽象类
- C++11 :从当前实例(此)进行unique_ptr的解决方法
- 如果使单一实例构造函数受到保护,缺点是什么 - 继承 - C++11.
- C++11 相当于 Java 的实例是什么
- 模板实例化 - 使用 C++11 的大小时没有匹配函数...() 具有某些类的运算符
- 是否可以在C++11中创建每个实例的mixin
- Visual studio 2015上可能的c++11实例模板错误