我的程序应该生成固定最大值为9999的随机数。这些数字用于创建对象。现在问题是当使用时间作为种子时,如果我一个接一个地创建两个对象,则两个对象都将使用相同的数字创建(因为时间没有在过程中发生变化)。
如何更有效地完成这项工作,以便每次运行程序时都可以生成不同的随机数?
答案 0 :(得分:8)
关键是 - 只创建一个随机对象(或其状态),然后重复使用它以获取下一个值。这种方法通常用于其他语言,例如Java,C#,Python。
对于较旧的C风格示例,请参阅rand,这是您感兴趣的位
var ci = event.relatedTarget.getAttribute("c_index");
Meta.elements[ci] = {CurrParent: "workspace"};
与C++11相同的想法,例如uniform distribution
//initialize random seed ONCE
srand (time(NULL));
// call MANY TIMES for next value
rand();
rand();
rand();
答案 1 :(得分:1)
用于生成随机数的简单C ++类。头文件。
#include <stdio.h>
#include <tchar.h>
#include <random>
#include <iostream>
#include <algorithm>
#include <vector>
namespace Random
{
/// <summary>
/// Secure pseudo random number generator.
/// </summary>
class RandomGenerator
{
public:
/// <summary>
/// Random number generator.
/// </summary>
RandomGenerator();
/// <summary>
/// Random number generator destructor.
/// </summary>
~RandomGenerator();
/// <summary>
/// Get the randomly ordered numbers between the lower bound and upper bound inclusive. Each random value only occurs once.
/// </summary>
/// <param name="lowerBound">The smallest random value to generate.</param>
/// <param name="upperBound">The largest random value to generate.</param>
/// <returns>The list of randomly ordered values.</returns>
/// <exception cref="std::invalid_argument">Invalid parameters.</exception>
std::vector<int> GetRandomList(int lowerBound = 1, int upperBound = 52);
/// <summary>
/// Get the random number between the lower bound and upper bound inclusive.
/// </summary>
/// <param name="lowerBound">The smallest random value to generate.</param>
/// <param name="upperBound">The largest random value to generate.</param>
/// <returns>A random value.</returns>
/// <exception cref="std::invalid_argument">Invalid parameters.</exception>
int Generate(int lowerBound, int upperBound);
private:
bool _disposed;
};
}
代码文件。
#include "RandomGenerator.h"
using namespace Random;
/// <summary>
/// Random number generator.
/// </summary>
RandomGenerator::RandomGenerator() : _disposed(false)
{
}
/// <summary>
/// Random number generator destructor.
/// </summary>
RandomGenerator::~RandomGenerator()
{
// If not disposed.
if (!_disposed)
{
// Indicate that dispose has been called.
_disposed = true;
}
}
/// <summary>
/// Get the randomly ordered numbers between the lower bound and upper bound inclusive. Each random value only occurs once.
/// </summary>
/// <param name="lowerBound">The smallest random value to generate.</param>
/// <param name="upperBound">The largest random value to generate.</param>
/// <returns>The list of randomly ordered values.</returns>
/// <exception cref="std::invalid_argument">Invalid parameters.</exception>
std::vector<int> RandomGenerator::GetRandomList(int lowerBound, int upperBound)
{
// Validate input.
if (lowerBound > upperBound)
throw std::invalid_argument("The parameters are invalid, the lower bound can not be larger then the upper bound.");
std::vector<int> numbers;
int arraySize = upperBound - lowerBound + 1;
// Allocate the total number of values.
numbers.resize(arraySize);
// For each value in the bounds.
for (int i = lowerBound; i <= upperBound; i++)
{
// Assign the numbers.
numbers[i - lowerBound] = i;
}
// Non-deterministic generator
// to seed mersenne twister.
// Random values on each execution.
std::random_device rd;
std::mt19937 engine(rd());
// Shuffle the numbers between the lower and upper bounds.
std::shuffle(numbers.begin(), numbers.end(), engine);
// Return the randomly ordered numbers.
return numbers;
}
/// <summary>
/// Get the random number between the lower bound and upper bound inclusive.
/// </summary>
/// <param name="lowerBound">The smallest random value to generate.</param>
/// <param name="upperBound">The largest random value to generate.</param>
/// <returns>A random value.</returns>
/// <exception cref="std::invalid_argument">Invalid parameters.</exception>
int RandomGenerator::Generate(int lowerBound, int upperBound)
{
// Validate input.
if (lowerBound > upperBound)
throw std::invalid_argument("The parameters are invalid, the lower bound can not be larger then the upper bound.");
int randomValue;
// Non-deterministic generator
// to seed mersenne twister.
// Random values on each execution.
std::random_device rd;
std::mt19937 engine(rd());
// Use the uniform distribution to generate
// a value between lower and upper bound inclusive.
std::uniform_int_distribution<> dist(lowerBound, upperBound);
// Generate the random value.
randomValue = dist(engine);
// Return the random value.
return randomValue;
}
答案 2 :(得分:0)
为了更好地理解,我将向您展示线性同余生成器的工作原理。
对于这种类型的生成器,数学非常简单:
xi+1=(A*xi+B) mod N
其中A,B和N是常数。
代码可以是:
static unsigned int x; //the seed (time in your case)
unsigned int myRand(){
x=A*x+B; //We do not need modulo because it is implicit. For 32b integer the modulo will be 2^32.
return x;
}
因此,当您设置x =时间时,如果时间没有改变,您只需重置发生器。
所以问题的解决方案可能是:
#include <iostream>
#include <time.h>
#include <stdlib.h>
int main() {
srand(time(NULL));
for (unsigned int i=0; i<10;i++){
std::cout << random()%(9999+1)<<std::endl;
}
}
或尝试这种不同的方法:
#include <iostream>
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> distribution(0,9999);
for (unsigned int i=0; i<10;i++){
std::cout << distribution(gen)<<std::endl;
}
}
有关random_device的更多信息:http://www.cplusplus.com/reference/random/random_device/