我想使用GSL的统一随机数生成器。在他们的网站上,他们包含以下示例代码:
#include <stdio.h>
#include <gsl/gsl_rng.h>
int
main (void)
{
const gsl_rng_type * T;
gsl_rng * r;
int i, n = 10;
gsl_rng_env_setup();
T = gsl_rng_default;
r = gsl_rng_alloc (T);
for (i = 0; i < n; i++)
{
double u = gsl_rng_uniform (r);
printf ("%.5f\n", u);
}
gsl_rng_free (r);
return 0;
}
然而,这不依赖于任何种子,因此每次都会产生相同的随机数。
他们还指定了以下内容:
可以使用环境变量GSL_RNG_TYPE更改生成器本身。以下是使用种子值123和多递归生成器mrg
的程序输出$ GSL_RNG_SEED=123 GSL_RNG_TYPE=mrg ./a.out
但我不明白如何实现这一点。关于我可以对上面的代码进行哪些修改以包含种子的任何想法?
答案 0 :(得分:3)
阅读18.6 Random number environment variables,了解gsl_rng_env_setup()
功能正在做什么。它从环境变量中获取生成器类型和种子。
然后看18.3 Random number generator initialization - 如果您不想从环境变量中获取种子,可以使用gsl_rng_set()
来设置种子。
答案 1 :(得分:3)
问题是没有生成新的种子。如果你只想要一个返回一个随机数字的函数,而不关心它是如何生成的粘性细节,试试这个。假设您已安装GSL。
#include <iostream>
#include <gsl/gsl_math.h>
#include <gsl/gsl_rng.h>
#include <sys/time.h>
float keithRandom() {
// Random number function based on the GNU Scientific Library
// Returns a random float between 0 and 1, exclusive; e.g., (0,1)
const gsl_rng_type * T;
gsl_rng * r;
gsl_rng_env_setup();
struct timeval tv; // Seed generation based on time
gettimeofday(&tv,0);
unsigned long mySeed = tv.tv_sec + tv.tv_usec;
T = gsl_rng_default; // Generator setup
r = gsl_rng_alloc (T);
gsl_rng_set(r, mySeed);
double u = gsl_rng_uniform(r); // Generate it!
gsl_rng_free (r);
return (float)u;
}
答案 2 :(得分:0)
可以在in this link中看到带有示例代码的完整答案。
为了完整起见,我在这里放一个函数代码的副本来创建一个种子。它由Robert G. Brown撰写:http://www.phy.duke.edu/~rgb/。
#include <stdio.h>
#include <sys/time.h>
unsigned long int random_seed()
{
unsigned int seed;
struct timeval tv;
FILE *devrandom;
if ((devrandom = fopen("/dev/random","r")) == NULL) {
gettimeofday(&tv,0);
seed = tv.tv_sec + tv.tv_usec;
} else {
fread(&seed,sizeof(seed),1,devrandom);
fclose(devrandom);
}
return(seed);
}
但根据我自己使用此功能的经验,我会说dev/random
解决方案与gettimeofday()
相比非常耗时,您可以查看它。因此,如果gettimeofday()
解决方案的准确性水平足够,那么#include <stdio.h>
#include <sys/time.h>
unsigned long int random_seed()
{
struct timeval tv;
gettimeofday(&tv,0);
return (tv.tv_sec + tv.tv_usec);
}
解决方案可能会更好:
{{1}}