简体   繁体   English

C++ Header 文件不创建随机数

[英]C++ Header file not creating random number

My first attempt at creating a header file.我第一次尝试创建 header 文件。 The solution is nonsense and nothing more than practice.解决方案是废话,无非是实践。 It receives two numbers from the main file and is supposed to return a random entry from the vector.它从主文件接收两个数字,并应该从向量返回一个随机条目。 When I call it from a loop in the main file, it increments by 3 instead of randomly.当我从主文件的循环中调用它时,它会增加 3 而不是随机增加。 (Diagnosed by returning the value of getEntry.) The Randomizer code works correctly if I pull it out of the header file and run it directly as a program. (通过返回 getEntry 的值进行诊断。)如果我从 header 文件中将其拉出并作为程序直接运行,则 Randomizer 代码可以正常工作。

int RandomNumber::Randomizer(int a, int b){
    std::vector < int > vecArray{};
    int range = (b - a) + 1;

    time_t nTime;
    srand((unsigned)time(&nTime));

    for (int i = a-1; i < b+1; i++) {
        vecArray.push_back(i);
    }

    int getEntry = rand() % range + 1;

    int returnValue = vecArray[getEntry];
    vecArray.clear();

    return returnValue;
}

From what I read, header files should generally not contain function and variable definitions.根据我的阅读,header 文件通常不应包含 function 和变量定义。 I suspect Rand, being a function, is the source of the problem.我怀疑作为 function 的兰德是问题的根源。

How, if possible, can I get my header file to create random numbers?如果可能的话,我怎样才能让我的 header 文件创建随机数?

void random(){
    double rangeMin = 1;
    double rangeMax = 10;
    size_t numSamples = 10;

    thread_local std::mt19937 mt(std::random_device{}());
    std::uniform_real_distribution<double> dist(rangeMin, rangeMax);

    for (size_t i = 1; i <= numSamples; ++i) {
        std::cout << dist(mt) << std::endl;
    }
}

This method will give you the opportunity to generate random numbers, between two numbers this method you have to include random此方法将使您有机会生成随机数,在两个数字之间,此方法您必须包含random

There are many cases where you will optate to engender a desultory number.在很多情况下,您会选择生成一个断断续续的号码。 There are genuinely two functions you will require to ken about arbitrary number generation.您确实需要两个函数来了解任意数字的生成。 The first is rand(), this function will only return a pseudo desultory number.第一个是rand(),这个function只会返回一个伪断断续续的数字。 The way to fine-tune this is to first call the srand() function.对此进行微调的方法是首先调用 srand() function。

Here is an example:这是一个例子:

#include <iostream>
#include <ctime>
#include <cstdlib>

using namespace std;
 
int main () {
   int i,j;
 
   
   srand( (unsigned)time( NULL ) );

   for( i = 0; i < 10; i++ ) {
      
      j = rand();
      cout <<" Random Number : " << j << endl;
   }

   return 0;
}

Using srand( (unsigned)time( NULL ) );使用srand( (unsigned)time( NULL ) ); Instead of using your own value use NULL for the default setting.不要使用您自己的值,而是使用NULL作为默认设置。 You can also go here for more info.您也可以在这里go 了解更多信息。

I hope I answered your question!我希望我回答了你的问题! Have a nice day!祝你今天过得愉快!

Ted Lyngmo gave me the idea that fixed the problem. Ted Lyngmo 给了我解决问题的想法。 Using random appears to work correctly in a header file.在 header 文件中使用随机似乎可以正常工作。

I removed/changed the following:我删除/更改了以下内容:

time_t nTime;
srand((unsigned)time(&nTime));
int getEntry = rand() % range + 1;

and replaced them with:并将它们替换为:

std::random_device rd;
std::mt19937 gen(rd());
int getEntry = gen() % range + 1;

Issue resolved.问题解决了。 Thank you everybody for your suggestions and comments!谢谢大家的建议和意见!

As an experiment, I remove the vector and focus on the randomizer `srand(T)`, where `T` is the system time `volatile time_t T = time(NULL)`.作为一个实验,我删除了向量并专注于随机化器`srand(T)`,其中`T`是系统时间`volatile time_t T = time(NULL)`。 We then found that system is NOT changed during the program running (execution simply too fast).然后我们发现系统在程序运行期间没有改变(执行太快了)。

The function `rand()` generates a pesudo-random integer using confluent rnadom generator , basically multiply the seed by another larger unsigned integer and truncated to the finite bits of `seed`. function `rand()` 使用合流随机数生成器生成伪随机 integer ,基本上将种子乘以另一个更大的无符号 Z157DB7DF530023575515D366C9B6 的有限位。 The randomizer `srand(T)` is used to initialize the seed using system time, or any number `srand(12345);`.随机发生器 `srand(T)` 用于使用系统时间或任何数字 `srand(12345);` 来初始化种子。 A seed gives a fixed sequence of random number.种子给出一个固定的随机数序列。 Without calling `srand(T)`, the seed is determined by the system initial memory gabage.不调用 `srand(T)`,种子由系统初始 memory gabage 确定。 The seed is then changed in every generating `rand()`.然后在每次生成的 rand() 中更改种子。

In your code, you issue randomizer `srand(T)` reset the seed to the system time in every run.在您的代码中,您发出 randomizer `srand(T)` 在每次运行中将种子重置为系统时间。 But the system time didn't changed, Thus, you are reseting the `seed` to a same number.但是系统时间没有改变,因此,您将“种子”重置为相同的数字。

Run this test.运行此测试。

#include <cstdlib>
#include <iostream>
#include <ctime>
int Randomizer(int a, int b){
    volatile time_t T = time(NULL);
    std::cout << "time = " << T << std::endl;
    srand(T);
    std::cout << "rand() = " << rand() << std::endl;
    return rand();
}
int main()
{
   int n1 = 1, n2 = 8;
   for(int i=0; i<5; ++i)
   {
        std::cout << Randomizer(n1, n2) << std::endl;
   }
}

The seed is reset to the system time, which is not change during execution.种子被重置为系统时间,在执行过程中不会改变。 Thus It renders the same random number.因此它呈现相同的随机数。

$ ./a.exe
time = 1608049336
rand() = 9468
15874
time = 1608049336
rand() = 9468
15874
time = 1608049336
rand() = 9468
15874
time = 1608049336
rand() = 9468
15874
time = 1608049336
rand() = 9468
15874

In order to see the change of system time, we add a pause in the main():为了查看系统时间的变化,我们在main()中添加了一个暂停:

int main()
{
    int n1 = 1, n2 = 8;
    for(int i=0; i<5; ++i)
    {
        std::cout << Randomizer(n1, n2) << std::endl;
        system("pause");
    }
}

We can observe the system time moving on...我们可以观察到系统时间在移动......

$ ./a.exe
time = 1608050805
rand() = 14265
11107
Press any key to continue . . .

time = 1608050809
rand() = 14279
21332
Press any key to continue . . .

time = 1608050815
rand() = 14298
20287
Press any key to continue . . .

Because system time is not much different, the first generation of confluent sequence rand() is also rather closed, but the continue sequence of numbers will be "seemingly" random.因为系统时间相差不大,第一代合流序列 rand() 也相当封闭,但连续的数字序列将“看似”随机。 The principle for confluent random generator is that once after set the seed don't change it.融合随机发生器的原理是一旦设置种子就不要改变它。 Until you are working for another series of random set.直到您为另一系列随机集工作。 Therefore, put the srand(T) funtcion just once in the main() or somewhere that executed only once.因此,只需将 srand(T) 函数放在 main() 中或仅执行一次的地方。

int main()
{
    srand(time(NULL)); // >>>> just for this once  <<<< 
    int n1 = 1, n2 = 8;
    for(int i=0; i<5; ++i)
   {
        std::cout << Randomizer(n1, n2) << std::endl;
   }
}

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

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