c+中的均匀随机数发生器+; 我试图用C++ Tr1在C++中产生真随机数。 然而,当再次运行我的程序时,它会产生相同的随机数
我需要为每次运行尽可能随机的真实随机数c+中的均匀随机数发生器+; 我试图用C++ Tr1在C++中产生真随机数。 然而,当再次运行我的程序时,它会产生相同的随机数,c++,random,tr1,C++,Random,Tr1,我需要为每次运行尽可能随机的真实随机数 std::tr1::mt19937 eng; std::tr1::uniform_real<double> unif(0, 1); unif(eng); std::tr1::mt19937英语; std::tr1::uniform\u real unif(0,1); unif(英语); 必须使用种子初始化引擎,否则将使用默认种子: eng.seed(static_cast<unsigned int >(time(NULL)))
std::tr1::mt19937 eng;
std::tr1::uniform_real<double> unif(0, 1);
unif(eng);
std::tr1::mt19937英语;
std::tr1::uniform\u real unif(0,1);
unif(英语);
必须使用种子初始化引擎,否则将使用默认种子:
eng.seed(static_cast<unsigned int >(time(NULL)));
eng.seed(静态_cast(时间(空));
然而,真正的随机性是在没有额外输入的确定性机器上无法实现的。每一个伪随机数生成器在某种程度上都是周期性的,这是一个不确定数所不能期望的。例如,std::mt19937
的迭代周期为219937-1次。真正的随机性是很难实现的,因为你必须监控一些看起来不确定的东西(用户输入、大气噪音)。见和
如果您不想要基于时间的种子,可以使用,如中所示。您甚至可以使用
std::random\u device
作为生成器,这是仅使用标准库方法最接近真实随机性的生成器。这些是伪随机数生成器。它们永远不会产生真正的随机数。为此,您通常需要特殊的硬件(例如,通常需要测量热二极管中的噪声或放射源的辐射)
要在不同的运行中从伪随机生成器获得不同的序列,通常需要基于当前时间对生成器进行种子设定
但这会产生相当可预测的结果(即,其他人可以相当容易地找出您使用的种子。如果您需要防止这种情况,大多数系统都会提供一些至少相当随机的数字源。在Linux上,/dev/random,在Windows上,CryptGenRandom
)
但后者的速度往往相当慢,因此您通常希望将其用作种子,而不仅仅是从中检索所有随机数。下面是一个种子引擎的示例(使用C++11而不是TR1) (这取决于您的标准库实现。例如,libc++默认使用/dev/uradom,但在VS11中,随机_设备是确定性的)
当然,你从mt19937中得到的任何东西都不能满足你对“真正随机数”的要求,我怀疑你并不真的需要真正的随机性。这个答案是一个维基。我正在.NET中开发一个库和示例,请随意添加你自己的任何语言 没有外部“随机”输入(如监测街道噪音),作为确定性机器,计算机无法生成真正的随机数: 由于我们大多数人没有资金和专业知识来利用特殊设备来提供混沌输入,因此有一些方法可以利用操作系统、任务调度器、流程管理器和用户输入(例如鼠标移动)的不可预测性来产生改进的伪随机性 遗憾的是,对于C++ Tr1,我不知道它是否有能力做到这一点。 编辑 正如其他人所指出的,通过在RNG中植入不同的输入,您可以获得不同的数字序列(最终会重复,因此它们不是真正随机的)。因此,在改进生成方面,您有两种选择:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace RandomParallel
{
class RandomParallel
{
static int[] _randomRepository;
static Queue<int> _randomSource = new Queue<int>();
static void Main(string[] args)
{
InitializeRepository(0, 1, 40);
FillSource();
for (int i = 0; i < 24; i++)
{
for (int j = 0; j < 40; j++)
Console.Write(GetNext() + " ");
Console.WriteLine();
}
Console.ReadLine();
}
static void InitializeRepository(int min, int max, int size)
{
_randomRepository = new int[size];
var rand = new Random(1024);
for (int i = 0; i < size; i++)
_randomRepository[i] = rand.Next(min, max + 1);
}
static void FillSource()
{
Thread[] threads = new Thread[Environment.ProcessorCount * 8];
for (int j = 0; j < threads.Length; j++)
{
threads[j] = new Thread((myNum) =>
{
int i = (int)myNum * _randomRepository.Length / threads.Length;
int max = (((int)myNum + 1) * _randomRepository.Length / threads.Length) - 1;
for (int k = i; k <= max; k++)
{
_randomSource.Enqueue(_randomRepository[k]);
}
});
threads[j].Priority = ThreadPriority.Highest;
}
for (int k = 0; k < threads.Length; k++)
threads[k].Start(k);
}
static int GetNext()
{
if (_randomSource.Count > 0)
return _randomSource.Dequeue();
else
{
FillSource();
return _randomSource.Dequeue();
}
}
}
}
根据系统运行方式,定期使用某种混沌输入重新设定RNG的种子,或使RNG的输出不可靠
前者可以通过创建通过检查系统环境显式生成种子的算法来实现。这可能需要设置一些事件处理程序、委托函数等
后者可以通过糟糕的并行计算实践来实现:即设置许多RNG线程/进程以“不安全的方式”竞争,以创建每个后续随机数(或数字序列)。这隐式地增加了系统上活动总数的混乱,因为每一分钟的事件都会影响在调用“GetNext()”类型方法时写入并最终读取哪个线程的输出。下面是.NET 3.5中的粗略概念证明。注意两件事:1)即使每次使用相同的编号对RNG进行播种,也不会创建24行相同的行;2) 性能受到明显影响,资源消耗明显增加,这是改进随机数生成时的一个特点:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace RandomParallel
{
class RandomParallel
{
static int[] _randomRepository;
static Queue<int> _randomSource = new Queue<int>();
static void Main(string[] args)
{
InitializeRepository(0, 1, 40);
FillSource();
for (int i = 0; i < 24; i++)
{
for (int j = 0; j < 40; j++)
Console.Write(GetNext() + " ");
Console.WriteLine();
}
Console.ReadLine();
}
static void InitializeRepository(int min, int max, int size)
{
_randomRepository = new int[size];
var rand = new Random(1024);
for (int i = 0; i < size; i++)
_randomRepository[i] = rand.Next(min, max + 1);
}
static void FillSource()
{
Thread[] threads = new Thread[Environment.ProcessorCount * 8];
for (int j = 0; j < threads.Length; j++)
{
threads[j] = new Thread((myNum) =>
{
int i = (int)myNum * _randomRepository.Length / threads.Length;
int max = (((int)myNum + 1) * _randomRepository.Length / threads.Length) - 1;
for (int k = i; k <= max; k++)
{
_randomSource.Enqueue(_randomRepository[k]);
}
});
threads[j].Priority = ThreadPriority.Highest;
}
for (int k = 0; k < threads.Length; k++)
threads[k].Start(k);
}
static int GetNext()
{
if (_randomSource.Count > 0)
return _randomSource.Dequeue();
else
{
FillSource();
return _randomSource.Dequeue();
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
名称空间随机化并行
{
类随机并行
{
静态int[]_;
静态队列_randomSource=新队列();
静态void Main(字符串[]参数)
{
初始化假设(0,1,40);
FillSource();
对于(int i=0;i<24;i++)
{
对于(int j=0;j<40;j++)
Write(GetNext()+“”);
Console.WriteLine();
}
Console.ReadLine();
}
静态无效初始值假定(最小整数、最大整数、大小整数)
{
_randomRepository=新整数[大小];
var rand=新随机数(1024);
对于(int i=0;i
{
int i=(int)myNum*_.Length/threads.Length;
int max=((int)myNum+1)*\u.Length/threads.Length)-1;
对于(int k=i;k 0)
返回_randomSource.Dequeue();
其他的
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace RandomParallel
{
class RandomParallel
{
static int[] _randomRepository;
static Queue<int> _randomSource = new Queue<int>();
static void Main(string[] args)
{
InitializeRepository(0, 1, 40);
FillSource();
for (int i = 0; i < 24; i++)
{
for (int j = 0; j < 40; j++)
Console.Write(GetNext() + " ");
Console.WriteLine();
}
Console.ReadLine();
}
static void InitializeRepository(int min, int max, int size)
{
_randomRepository = new int[size];
var rand = new Random(1024);
for (int i = 0; i < size; i++)
_randomRepository[i] = rand.Next(min, max + 1);
}
static void FillSource()
{
Thread[] threads = new Thread[Environment.ProcessorCount * 8];
for (int j = 0; j < threads.Length; j++)
{
threads[j] = new Thread((myNum) =>
{
int i = (int)myNum * _randomRepository.Length / threads.Length;
int max = (((int)myNum + 1) * _randomRepository.Length / threads.Length) - 1;
for (int k = i; k <= max; k++)
{
_randomSource.Enqueue(_randomRepository[k]);
}
});
threads[j].Priority = ThreadPriority.Highest;
}
for (int k = 0; k < threads.Length; k++)
threads[k].Start(k);
}
static int GetNext()
{
if (_randomSource.Count > 0)
return _randomSource.Dequeue();
else
{
FillSource();
return _randomSource.Dequeue();
}
}
}
}
#include <random>
...
std::mt19937_64 re;
std::random_device rd;
re.seed(rd());
...
std::cout << re();