简体   繁体   English

对象数组构造函数中的随机数

[英]Random numbers in a constructor of an object array

Firstly, sorry if it's a silly question, but I have recently learn how to deal with classes.首先,对不起,如果这是一个愚蠢的问题,但我最近学习了如何处理课程。 My problem is that I've created a constructor which gives every data member a random number, with the following syntax:我的问题是我创建了一个构造函数,它为每个数据成员提供一个随机数,语法如下:

#include <random>

... ...

//Constructor
cSystem::cSystem(void)
{
//Range of random numbers
double lower_bound = -100;
double upper_bound = 100;
std::uniform_real_distribution<double> unif(lower_bound,upper_bound);
std::default_random_engine re;

/*Initialization of data members*/
sMass=1.0014;
sPositionX= unif(re);
sPositionY= unif(re);
}

But then, I want to create an array of these "systems" in my main function但是,我想在我的主函数中创建这些“系统”的数组

int main (void)
{
cSystem systems[numsist]; //numsist is a constant defined to be 1000

//Function that writes its characteristics in a file using a method that returns positions
getPositions(systems);

return 0;
}

But in the file, I just get但在文件中,我只是得到

-73.6924    -8.26997
-73.6924    -8.26997
-73.6924    -8.26997

I thought that I was going through the constructor for every element of the array, giving it a different random value, but it seems like a single value is given at the beginning and then it is repeated throughout the vector.我以为我正在为数组的每个元素遍历构造函数,给它一个不同的随机值,但似乎在开始时给出了一个值,然后在整个向量中重复。 What can I do to get a constructor that initializes every element in a random way?我该怎么做才能获得一个以随机方式初始化每个元素的构造函数?

Note: I also get the same values everytime I run the program, I suppose that the seed does not change, why is that the case?注意:我每次运行程序时也得到相同的值,我认为种子没有改变,为什么会这样?

You get the same values of sPositionX and sPositionY for each instance of cSystem since you are creating the std::uniform_real_distribution<double> and the std::default_random_engine every time the constructor is called.你得到的值相同sPositionXsPositionY为每个实例cSystem因为你正在创建std::uniform_real_distribution<double>std::default_random_engine每一个构造函数被调用时。

You need to create them once and reuse them in the constructor.您需要创建一次并在构造函数中重用它们。 One way to do that would be to create class scoped static objects.一种方法是创建类范围的static对象。

struct cSystem
{
   ...

   static std::uniform_real_distribution<double> unif;
   static std::default_random_engine re;
};

and just use them in the constructor.并在构造函数中使用它们。

Here's a complete program.这是一个完整的程序。

#include <random>
#include <iostream>

struct cSystem
{
   cSystem();

   double sPositionX;
   double sPositionY;
   double sMass;

   static std::uniform_real_distribution<double> unif;
   static std::default_random_engine re;
};

std::uniform_real_distribution<double> cSystem::unif(-100, 100);
std::default_random_engine cSystem::re;

//Constructor
cSystem::cSystem()
{
   /*Initialization of data members*/
   sMass=1.0014;
   sPositionX= unif(re);
   sPositionY= unif(re);
}

void getPositions(cSystem* systems)
{
   for (unsigned i = 0; i < 3; ++i )
   {
      std::cout << systems[i].sPositionX << " " << systems[i].sPositionY << std::endl;
   }
}

int main (void)
{
   cSystem systems[3];

   getPositions(systems);

   return 0;
}

See it working at https://ideone.com/bS8E4u .https://ideone.com/bS8E4u 上查看它的工作情况。

Update, in response to OP's comment.更新,以回应 OP 的评论。

You can initialize re as shown below to get different random numbers when the program is run again and again.可以如下图初始化re ,在程序反复运行时得到不同的随机数。

std::default_random_engine cSystem::re{std::random_device()()};

My problem is that I've created a constructor which gives every data member a random number我的问题是我创建了一个构造函数,它为每个数据成员提供一个随机数

  • You are not seeding the PRNG when you make it default constructed.当您将 PRNG 设为默认构造时,您不是在播种它。 It will start with its default state every time.每次都会以默认状态开始。
  • The PRNG is not supposed to be owned by any one class. PRNG 不应该由任何一个类拥有。 It's expensive to seed it, and it is supposed to be shared by all functions (per thread) that needs to generate random numbers - so separate it from any classes.播种它很昂贵,并且它应该由需要生成随机数的所有函数(每个线程)共享 - 因此将它与任何类分开。

I perfer to select a certain PRNG, but with the default, it could look like this:我更愿意选择某个 PRNG,但在默认情况下,它可能如下所示:

std::default_random_engine& prng() {
    // seed only one PRNG per thread that needs is:
    static thread_local std::default_random_engine gen(std::random_device{}());
    return gen;
}

In every distribution function (member function or otherwise) you use in your program you may now call prng() to get the generator, seeded once and not overseeded .在您在程序中使用的每个分布函数(成员函数或其他函数)中,您现在可以调用prng()来获取生成器,播种一次而不是overeded

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM