3

我无法保持随机生成的值,这些值通常分布在 0 和 1 之间(包括 0,不包括 1)。我相信算法基本上是正确的,我只是被难住了。任何见解都会很棒。

这些是所需的包含文件:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

正态分布随机数生成器函数:

float rand_normal(float mean, float stddev) 
{
    static float n2 = 0.0;
    float x, y, r;
    static int n2_cached = 0;
    if (!n2_cached) 
    {
        do
        {
            x = 2.0*rand()/RAND_MAX - 1;
            y = 2.0*rand()/RAND_MAX - 1;
            r = x*x + y*y;
        } while (r==0.0 || r>1.0);
        float d = sqrt(-2.0*log(r)/r);
        float n1 = x*d;
        float result = n1*stddev + mean;
        n2 = y*d;
        n2_cached = 1;
        return result;
    }
    else
    {
        n2_cached = 0;
        return n2*stddev + mean;
    }
}

main 函数仅用于测试目的。

int main()
{
    srand(time(NULL));
    int i;
    float min = 0.5, max = 0.5, r, avg = 0;
    float x, w;
    int n = 10000000;
    for (i=0; i<n; i++)
    {
        r = rand_normal(0.5, 0.09);
        if (r < min)
            min = r;
        else if ( r>max)
            max = r;
        avg += r;
    }
    avg /= (float)n;
    printf("min = %f\nmax = %f\navg = %f\n", min, max, avg);
    return 0;
}    

如果有人想知道,“植物中的遗传遗传”模拟需要此功能。

4

2 回答 2

3

为什么您希望结果保持在 0 和 1 之间?高斯分布具有完全支持,因此无论您正在查看的区间以及您选择的均值和方差如何,总会有(可能性非常小)非零概率落在该区间之外。如果出于某种原因您真的想将自己限制在 [0,1] 范围内,那么您可以简单地调用 rand_normal 直到您进入该区间。

另请注意,虽然 Box-Müller(您正在使用的算法)很容易实现,但这是生成高斯随机变量的最糟糕和最昂贵的方法之一。我所知道的最好和最快的算法是“Ziggurat”方法,它的实现可以在

http://www.seehuhn.de/pages/ziggurat

于 2012-06-27T13:45:19.323 回答
0

我肯定会创建一个函数来将“rand()”转换为规范化的浮点值。例如:

double
nrand ()
{
  return rand()/(RAND_MAX - 1);
}

此外,这里有一些链接可能会有所帮助:

于 2012-01-19T18:19:29.307 回答