在c++中使用随机数生成一系列可重复的数字
Using a random number to generate a series of repeatable numbers in C++
我有一个unsigned int存储一个随机数。我需要使用这个数字来生成一系列"类似随机"的数字,并让它在这个原始随机数再次出现时生成完全相同的数字。
。
随机编号:123456789
第一个"随机类数":3
第二个"随机类数":7
第三个"随机类数":1
第四个"随机类数":9
等等
下次出现随机数时,需要从它生成完全相同的数字。
非随机数可以重复和/或环绕(如果使用的任何算法的数字耗尽,它可以重新开始)。只要每次都生成相同的数字。
我意识到这正是rand()所做的(用随机数播种),但是我不能使用rand。因此,也许一个更简洁的问题是,我如何复制一个"迷你"rand函数(它不必是任何复杂的东西,只要出来的数字看起来有点随机)。
我也不能使用boost(不幸的是)。
指针/建议吗?
我不知道确切的为什么你不能使用rand
本身,但如果不是,那么你可以只是滚动你自己的。使用你的整数来播种一个数字,然后使用标准的Xn+1 = a * Xn + c mod m
。
维基百科关于线性同余方法的页面有a
, c
和m
的一些样本值。
现在LCM不是世界上最大的随机数生成器,但是,如果你只是想要"看起来有点随机"的数字,它应该足够了。
作为LCM算法的一个示例,下面的函数基于上面链接页面的Microsoft Visual/Quick C/C++
条目:
// LCM pseudo-random number generator.
// Outputs numbers from 0..32767 inclusive.
// With protection against identical sequences.
// due to full 32-bit cycle but only returning 15 bits.
uint32_t myRand (void) {
const static uint32_t a = 214013U;
const static uint32_t c = 2531011U;
// m is, of course, 2^32 since the values will wrap.
static uint32_t seed = 1;
seed = seed * a + c;
return (seed >> 16) & 0x7FFF;
}
有一个32位数字的完整范围的循环时间,但每次只返回种子的某些位,这减少了相同序列的出现。
如果你想要一个c++类来做这件事,这样所有的随机数生成器都是相互独立的(正如TomZ所建议的),你可以使用这样的东西:
class myRand {
public:
myRand ();
myRand (unsigned int newSeed);
~myRand ();
void setSeed (unsigned int newSeed);
unsigned int getSeed (void);
unsigned int next (void);
private:
unsigned int seed;
const static unsigned int a = 214013U;
const static unsigned int c = 2531011U;
};
myRand::myRand () { seed = 1; }
myRand::myRand (unsigned int newSeed) { setSeed (newSeed); }
myRand::~myRand () { }
void myRand::setSeed (unsigned int newSeed) { seed = newSeed; }
unsigned int myRand::getSeed (void) { return seed; }
unsigned int myRand::next (void) {
seed = (seed * a + c) & 0xffffffff;
return (seed >> 16) & 0x7fff;
}
,
#include <iostream>
int main (void) {
myRand r (5);
std::cout << r.next() << "n"; // 54
std::cout << r.next() << "n"; // 28693
unsigned int saveSeed = r.getSeed();
std::cout << r.next() << "n"; // 12255
std::cout << r.next() << "n"; // 24449
r.setSeed (saveSeed);
std::cout << r.next() << "n"; // 12255
std::cout << r.next() << "n"; // 24449
return 0;
}
您可以从<random>
(或<tr1/random>
)中选择任何伪随机数生成引擎,并使用它为均匀整数分布提供燃料。
只要为引擎分配相同的数字,得到的整数序列将是相同的。
的例子:
#include <random>
std::mt19937 rng; // everyone's favourite engine: fast, long period
std::uniform_int_distribution<uint32_t> uniformUINT32(0, 99); // numbers in the range [0, 100)
int main()
{
static const unsigned long int seed = 123;
rng.seed(seed);
int val;
val = uniformUINT32(rng); // a predictable random number (69)
val = uniformUINT32(rng); // ditto (71)
}
创建一个实现线性同余生成器的类:
http://en.wikipedia.org/wiki/Linear_congruential_generator您可以查找A和C的合适值,并使用2^32作为M(模)数值配方中的例子:A = 1664525, C = 1013904223
正如文章所述,使用2^32作为模数在32位字长上是"自由的"。
这与rand()的大多数版本使用的算法相同。
请注意,这是不安全的。
种子值为x,使用相同的种子将生成相同的序列
对于您的情况,您可以使用伪随机数生成器(适合做一些快速花哨的东西,但不适用于安全/科学相关领域)
Rn = Rn * 1664525 + 1013904223
Rn的数据类型为uint32_t,用于支持类型环绕。初始值Rn作为种子
- 在C++的一系列数字中查找重复模式
- 将一系列数字映射到 CPP 中的值的简单方法
- 如何非常快速地将数字添加到 Vector 中的一系列元素中
- 根据用户输入从一系列数字中找到一个完美的数字
- 为什么这4个不同的随机数生成器函数会产生相同的一系列数字
- 将目标数字拆分为一系列数字(递归任务)
- 代码打印出一系列无意义的数字
- C++ - 计算一系列数字的数字
- 在一系列数字的间隔内计算数字
- c++程序输出一系列的数字而不是cout
- 我正在尝试创建一个程序,用户在其中输入一系列数字,并且我想列出范围之间的质数
- 用O(1)表示法求一系列数字的平均值——常数时间
- 使用一系列数字有效地初始化 std::set
- C++中一系列数字的组合
- 我怎样才能在一系列数字中找到一个缺失的数字
- 给定一系列数字报告,哪些重复和重复了多少次
- 读取一系列数字
- 在c++中使用随机数生成一系列可重复的数字
- Boost Spirit语法用于识别从一行到向量的一系列数字
- 打印一系列数字优化第1部分