我在生成随机数时遇到问题,我在SO上阅读了关于这个主题的大多数帖子,但没有一个解决方案似乎有效。 请在将其标记为重复之前仔细阅读
我有一个仿函数来生成介于0.5和-0.5之间的随机数:
struct randomize
{
__host__ void operator()( double &x ) const {
x=(double) (rand() % 1000000) / 1000000 - 0.5;
}
};
我正在通过for_each
呼叫,如此:
thrust::for_each(myVector.begin(),myVector.end(),randomize());
反过来在类的构造函数中调用(比如myClass),它被称为:
myObjs=std::vector<myClass>(20,myClass(no_of_inputs));
问题在于所有myVector
myVectors中的所有myClass' objects are filled with the same set of values.
These values change with each run but are the same across all
我知道rand()
是一个伪随机数生成器,由它生成的数字不能说是真正随机的。但这太巧合了。
只是为了澄清:
srand(time(NULL))
一次。答案 0 :(得分:2)
问题是所有myClass对象中的所有myVectors都填充了相同的值集。
那是因为std::vector<myClass>(20, myClass(no_of_inputs))
可以获得一个临时对象的20个副本。
如果您为myClass
提供默认值,则可以跳过vector
- ctor的第二个参数。
您也可以push_back
myClass
- 一个接一个的对象。
这给我们提出了建议:
我看到您的randomize::operator()
已标记为__host__
,因此没有理由使用thrust::for_each
支持std::for_each
。
我不能使用c ++ 11(现在)或者提升(根本不是)
但您可以使用tr1-extensions,它还提供<random>
- 标题:
#include <tr1/random>
template <typename T>
struct twisterize {
const T min;
const T max;
twisterize(const T & min, const T & max) : min(min), max(max) {}
void operator()(T & x) {
typedef std::tr1::mt19937 rng_t;
typedef std::tr1::uniform_real<T> dist_t;
static rng_t rng( ((std::tr1::random_device())) ());//most vexing parse, yikes
static dist_t dist(min, max);// [min,max) for real distributions
static std::tr1::variate_generator<rng_t, dist_t> bound_dist(rng, dist);//not necessary in c++11
x = bound_dist();//using the c++11 way `dist(rng)` produces unexpected results with tr1
}
};
由于仿函数现在具有状态,因此最好为其创建变量,并将其传递给for_each
:
twisterize<double> rand_functor(-0.5, 0.5);
如果你真的想要在gpu look here
上生成随机数答案 1 :(得分:1)
myObjs=std::vector<myClass>(20,myClass(no_of_inputs));
您是否为myClass
定义了一个随机化数据的副本构造函数? (但在我看来,这会违反复制构造函数的目的)
如果没有,那么您将相同的myClass
20次复制到myObj
中,vector<myClass>
将通过调用每个元素的默认复制构造函数来构建,而myVector
将依次为只需复制{{1}}中的数据。
答案 2 :(得分:0)
在ENTIRE代码中不止一次调用srand
,永远不会做得更好[除非你真的想用相同的随机数序列重复另一次运行,当然]。
您获得的实际数字取决于种子。由于time()
仅从一秒钟到下一秒钟稍有变化,即使您等待几分钟,也只会改变最后几位数字。您可能会发现使用不同的时间源(例如,给出毫秒或更短的时间)并将其与time
的结果相结合可以获得更好的随机数。但是,如果您需要非常便携的代码,这将有点尴尬。
[当然有许多聪明的方法可以获得一个不涉及时间的“随机种子”,但它们往往更复杂,不便携和/或慢 - 例如你可以发送“今天日期”到谷歌的搜索页面,并对返回的HTML进行哈希处理。几乎可以肯定每次都会产生不同的结果]。
答案 3 :(得分:-2)
我只调用一次srand(time(NULL))。
不,你说你在类构造函数中调用它,所以每次创建实例时都会调用 。每次发生时,伪随机序列都会被重置(到相同的序列,因为这一切都在一秒钟内运行,因此种子不会改变),并且会发生这种情况。
在整个程序中只调用一次 。