我有一个程序使用boost :: random的mt19937随机数生成器.我需要做一个random_shuffle,并希望为此生成的随机数来自这个共享状态,这样它们就可以确定为mersenne twister之前生成的数字.
我试过这样的事情:
void foo(std::vector<unsigned> &vec, boost::mt19937 &state)
{
struct bar {
boost::mt19937 &_state;
unsigned operator()(unsigned i) {
boost::uniform_int<> rng(0, i - 1);
return rng(_state);
}
bar(boost::mt19937 &state) : _state(state) {}
} rand(state);
std::random_shuffle(vec.begin(), vec.end(), rand);
}
Run Code Online (Sandbox Code Playgroud)
但是我得到一个模板错误,用rand调用random_shuffle.但是这有效:
unsigned bar(unsigned i)
{
boost::mt19937 no_state;
boost::uniform_int<> rng(0, i - 1);
return rng(no_state);
}
void foo(std::vector<unsigned> &vec, boost::mt19937 &state)
{
std::random_shuffle(vec.begin(), vec.end(), bar);
}
Run Code Online (Sandbox Code Playgroud)
可能是因为它是一个实际的函数调用.但显然这并没有使国家不受最初的mersenne twister影响.是什么赋予了?有没有办法在没有全局变量的情况下做我想做的事情?
我用C++编写了一个模拟,它从特定的概率分布中生成(1,000,000)^ 2个数字,然后用它们做一些事情.到目前为止,我使用了指数,正常,伽玛,均匀和泊松分布.以下是其中一个的代码:
#include <boost/random.hpp>
...main...
srand(time(NULL)) ;
seed = rand();
boost::random::mt19937 igen(seed) ;
boost::random::variate_generator<boost::random::mt19937, boost::random::normal_distribution<> >
norm_dist(igen, boost::random::normal_distribution<>(mu,sigma)) ;
Run Code Online (Sandbox Code Playgroud)
现在我需要为Beta发行版运行它.到目前为止,我所做的所有发行都需要10-15个小时.Beta发行版不在boost/random包中,所以我不得不使用boost/math/distributions包.我在StackOverflow上找到了这个提出解决方案的页面.这是(复制粘贴):
#include <boost/math/distributions.hpp>
using namespace boost::math;
double alpha, beta, randFromUnif;
//parameters and the random value on (0,1) you drew
beta_distribution<> dist(alpha, beta);
double randFromDist = quantile(dist, randFromUnif);
Run Code Online (Sandbox Code Playgroud)
我复制它并且它有效.我的模拟的运行时间估计是线性的并且可以准确地预测.他们说这将持续25天.我看到了两种可能性:1.提出的方法不如我以前用于其他发行版的方法2. Beta分布更难以从中生成随机数
请记住,我对C++编码的理解很少,所以我问的问题可能很愚蠢.我不能等待一个月来完成这个模拟,所以我能做些什么来改善它?也许使用我正在使用的初始方法并修改它以使用boost/math/distributions包?我甚至不知道这是否可能.
另一条可能有用的信息是,我需要生成的所有(1,000,000)^ 2个数字的参数相同.我这样说是因为Beta发行版确实有一个讨厌的PDF,也许参数修复的知识可以某种方式用于简化过程?只是随机猜测.
似乎有一些关于使用mt19937的神话,特别是一旦播种器产生的'某些'位数应该被忽略,以便尽可能接近伪随机性.
我见过的代码示例如下:
boost::mt19937::result_type seed = 1234567; //taken from some entropy pool etc
boost::mt19937 prng(seed);
boost::uniform_int<unsigned int> dist(0,1000);
boost::variate_generator<boost::mt19937&,boost::uniform_int<unsigned int> > generator(prng,dist);
unsigned int skip = 10000;
while (skip--)
{
generator();
}
//now begin using for real.
....
Run Code Online (Sandbox Code Playgroud)
我的问题是:
这是神话还是有一些真理呢?
如果它可行,那么应该忽略多少位?因为我看到的数字
似乎是随意的
我正在使用boost mt19937实现进行模拟.
模拟需要是可重复的,这意味着以后存储并可能重复使用RNG种子.我正在使用windows crypto api生成种子值,因为我需要种子的外部源,而不是因为任何特殊的随机性保证.任何模拟运行的输出都会有一个包含RNG种子的注释 - 因此种子需要相当短.另一方面,作为模拟分析的一部分,我将比较几次运行 - 但为了确保这些运行实际上是不同的,我需要使用不同的种子 - 所以种子需要足够长避免意外碰撞.
我已经确定64位播种应该足够了; 在大约2 ^ 32次运行后,碰撞的几率将达到50% - 这个概率足够低,以至于它造成的平均误差对我来说可以忽略不计.仅使用32位种子很棘手; 在2 ^ 16次运行后,碰撞的可能性已达到50%; 这对我的口味来说有点太可能了.
不幸的是,增强实现要么是带有完整状态向量的种子 - 这太长,太长 - 或者是一个32位无符号长 - 这并不理想.
如何为超过32位但小于满状态向量的发生器播种?我试着填充矢量或重复种子来填充状态向量,但即使粗略地看一下结果也会显示结果不佳.
我想boost::random::discrete_distribution
用一个初始化std::vector<double>
.
我的问题是,如果我用数组初始化它,就像在官方示例中一样:
double probabilities[] = {
0.5, 0.1, 0.1, 0.1, 0.1, 0.1
};
boost::random::discrete_distribution<> dist(probabilities);
Run Code Online (Sandbox Code Playgroud)
然后它完美地运作.
但是,如果我用a初始化它std::vector
,那么它的行为就像它只有一个概率为1.0的元素.
你能告诉我boost::random::discrete_distribution<>
用矢量初始化一个正确的方法吗?
考虑使用g++ -std=c++11
(GCC 4.7.2)编译此函数:
boost::uuids::uuid getID()
{
static boost::uuids::random_generator generator;
return generator();
}
Run Code Online (Sandbox Code Playgroud)
getID
从多个线程调用安全吗?
正如提到这里的局部静态对象定义在所述第一线是根据C ++ 11标准线程安全的。问题是,第二行boost::uuids::random_generator::operator()
对同一对象的调用generator
是否也是线程安全的。返回的UUID在单个线程中是否唯一?
我正在尝试使用boost随机生成随机64位无符号整数,但我使用uniform_int得到断言失败.
struct timeval tv;
boost::mt19937 randGen(tval.tv_usec);
boost::uniform_int<> uInt64Dist(0, std::numeric_limits<uint64_t>::max());
boost::variate_generator<boost::mt19937&, boost::uniform_int<> > getRand(randGen, uInt64Dist);
uint64_t clock_seq_= getRand();
Run Code Online (Sandbox Code Playgroud)
这是第3行的输出结果.
main:/usr/include/boost/random/uniform_int.hpp:48: boost::uniform_int<IntType>::uniform_int(IntType, IntType) [with IntType = int]: Assertion `min_arg <= max_arg' failed.
Run Code Online (Sandbox Code Playgroud)
编辑:根据您的答案,我试图用下面的方式指定大小:
boost:uniform_int<uint64_t> ....
Run Code Online (Sandbox Code Playgroud)
但是我得到以下编译错误:
spec.cpp: In member function ‘void Specifier::initialize()’:
spec.cpp:58: error: no matching function for call to ‘boost::variate_generator<boost::mt19937&, boost::uniform_int<int> >::variate_generator(boost::mt19937&, boost::uniform_int<long unsigned int>&)’
/usr/include/boost/random/variate_generator.hpp:97: note: candidates are: boost::variate_generator<Engine, Distribution>::variate_generator(Engine, Distribution) [with Engine = boost::mt19937&, Distribution = boost::uniform_int<int>]
/usr/include/boost/random/variate_generator.hpp:87: note: boost::variate_generator<boost::mt19937&, boost::uniform_int<int> >::variate_generator(const boost::variate_generator<boost::mt19937&, boost::uniform_int<int> >&)
make: *** [spec.o] Error …
Run Code Online (Sandbox Code Playgroud) 对于 C++ Web 服务器,我必须生成会话 ID。我考虑使用某种随机数和哈希值,以及会话的初始 IP 地址和时间戳。
这会产生一个合理且不可猜测的 ID 吗?什么是一种好的随机生成器算法(最优选由 boost-random 实现的算法)?
亲切的问候托斯顿
我的解决方案现在看起来像:
std::string secure_session_generator::operator()( const char* /* network_connection_name */ )
{
std::stringstream out;
out << std::hex << distribution_( generator_ );
return out.str();
}
Run Code Online (Sandbox Code Playgroud)
成员是默认构造的:
boost::random::random_device generator_;
boost::random::uniform_int_distribution< boost::uint_least64_t > distribution_;
Run Code Online (Sandbox Code Playgroud) 我需要一个“随机”数字生成器,对于Windows,Mac,Linux,iOS和Android上的给定种子,其生成的结果相同。现在我想std::rand
和boost::random_int_generator
同boost::mt19937
,但遗憾的是,结果是Windows和Mac之间的不同。
有谁知道在所有平台上都能可靠运行的(C ++)实现吗?
编辑1:
更具体地说,boost::mt19937
在Windows和Mac上的数字之间存在差异,这表明在Windows上还会生成(2)个其他数字块。看起来真的很奇怪,因为大多数数字都是相同的,这些块仅出现在Windows上。
编辑2:
boost::mt19937
在所有平台上都能可靠运行。我们的问题不是那里的错误。
我有一个循环,应该通过insering一个openmp pragma很好地并行化:
boost::normal_distribution<double> ddist(0, pow(retention, i - 1));
boost::variate_generator<gen &, BOOST_TYPEOF(ddist)> dgen(rng, ddist);
// Diamond
const std::uint_fast32_t dno = 1 << i - 1;
// #pragma omp parallel for
for (std::uint_fast32_t x = 0; x < dno; x++)
for (std::uint_fast32_t y = 0; y < dno; y++)
{
const std::uint_fast32_t diff = size/dno;
const std::uint_fast32_t x1 = x*diff, x2 = (x + 1)*diff;
const std::uint_fast32_t y1 = y*diff, y2 = (y + 1)*diff;
double avg =
(arr[x1][y1] + arr[x1][y2] + …
Run Code Online (Sandbox Code Playgroud) 如果已经讨论过,请原谅我.我有一个模板函数,它根据模板参数使用boost :: uniform_int和boost :: uniform_real,并且应该返回相同的类型:
template <typename N> N getRandom(int min, int max)
{
timeval t;
gettimeofday(&t,NULL);
boost::mt19937 seed((int)t.tv_sec);
boost::uniform_int<> dist(min, max);
boost::variate_generator<boost::mt19937&, boost::uniform_int<> > random(seed, dist);
return random();
}
//! partial specialization for real numbers
template <typename N> N getRandom(N min, N max)
{
timeval t;
gettimeofday(&t,NULL);
boost::mt19937 seed( (int)t.tv_sec );
boost::uniform_real<> dist(min,max);
boost::variate_generator<boost::mt19937&, boost::uniform_real<> > random(seed,dist);
return random();
}
Run Code Online (Sandbox Code Playgroud)
现在我用int,float和double测试了这个函数.它适用于int,它可以正常使用double,但它不适用于浮点数.就好像它将float转换为int,或者存在一些转换问题.原因我说这是因为当我这样做时:
float y = getRandom<float>(0.0,5.0);
Run Code Online (Sandbox Code Playgroud)
我总是得到一个回归.但是,就像我说的那样,它适用于双打.有什么我做错了或错过了吗?谢谢 !
我有一个特定的情况,我有一个对象,我想使用增强随机数生成器,它导致一个更大的问题,我似乎无法回答.这是我正在尝试制作的示例代码.
首先,我的标题:
Class MyObject {
protected:
double some variable;
boost::random::mt19937 rgenerator;
boost::uniform_real<double> dist_0_1;
boost::variate_generator< boost::mt19937&, boost::uniform_real<double> > rand01
}
Run Code Online (Sandbox Code Playgroud)
现在我想做的是:
Class MyObject {
protected:
double some variable;
boost::random::mt19937 rgenerator(std::time(0)); //initialize to a "random" seed
boost::uniform_real<double> dist_0_1(0,1); //set the distribution to 0-1
boost::variate_generator< boost::mt19937&, boost::uniform_real<double> > rand01(rgenerator, dist_0_1);//tell it to use the above two objects
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为它在标题中.我以为我可以使用MyObject的构造函数以某种方式调用各个子对象上的构造函数(分布,生成器,但我无法弄清楚如何.当调用MyObject的构造函数时,子对象的默认值已经调用了构造函数,我还没有发现它们有成员方法来重置这些属性......除此之外,这不是我感到困惑的地方.现在也许有太多事情发生了,我令人困惑的问题,但据我所知,我的问题减少到以下,幼稚的例子:
Class Tree {
Tree();
Tree(int);
protected:
fruit apples(int);
}
Tree::Tree() {
apples(0); //won't work because we can't call the constructor again?
}
Tree::Tree(int fruit_num) …
Run Code Online (Sandbox Code Playgroud)