rand()* rand()不会为你做任何事情。它不会像你想象的那样扩展,它确实改变了分布。事实上
double norm_rand(){
double r=0;
for(unsigned i=0;i!=12;++i)
r+=rand()/static_cast(RAND_MAX);
return (r/12)-6;
}
是一种模拟正态分布的常用方法,均值为0,方差为1;
获取大型随机数的最佳方法是使用随机数设备,如/ dev / urandom或RtlGenRandom。
即
typedef unsigned long long big_type;
std::vector rnums;
std::vector buf(numtoread);
std::ifstream rnds("/dev/urandom");
rnds.read(reinterpret_cast(&buf[0],buf.size()*sizeof(big_type));
std::transform(buf.begin(),buf.end(),std::back_inserter(rnums),
[](big_type const& i){
return (i*100000000000.)/(std::numeric_limits::max());
});
冒着为你做功课的风险,一种完全不同的方法是使用C ++附带的库。
#include
#include
#ifndef _MSC_VER //then assume Linux
#include
#else
#include
#endif
#include
#include
#include
#include
int main(int argc, char** argv)
{
assert(argc==3);
unsigned const numentries=boost::lexical_cast(argv[1]);
unsigned const k=boost::lexical_cast(argv[2]);
std::cout<
assert(k<=numentries);
std::vector nums(numentries);
std::tr1::uniform_real<> rng(0.,10000000000.);
std::tr1::minstd_rand generator(42u);
std::tr1::variate_generator<:tr1::minstd_rand std::tr1::uniform_real> >
uni(generator, rng);
std::generate_n(nums.begin(),nums.size(),uni);
std::cout<
std::copy(nums.begin(),nums.end(),std::ostream_iterator(std::cout,"t"));
std::sort(nums.begin(),nums.end());
std::cout<
return 0;
}
(如果你在课堂上只是要求制作一系列兰特数字并将其交给他们,他们可能会让你失望)
我在实践中做的是结合这两种方法。这用于代替上面使用的线性conguentual rng(minstd_rand):
template
struct randeng {
typedef bigtype result_type;
randeng(unsigned x) :
m_samplesrequired(x), m_samples(x), m_lastused() {
std::ifstream rand;
rand.open("/dev/urandom");
assert(rand);
rand.read(reinterpret_cast (&*(m_samples.begin())),
m_samplesrequired * sizeof(unsigned));
}
result_type operator()() const {
assert(m_lastused
return m_samples[m_lastused++];
}
result_type max() const {
return std::numeric_limits::max();
}
result_type min() const {
return 0;
}
unsigned m_samplesrequired;
std::vector m_samples;
mutable unsigned m_lastused;
};
这似乎总能给出更好的结果。