如何生成总计为0.0的n大小的随机浮点数组? [英] How to generate a n-sized random float array that sums up to 0.0?

查看:70
本文介绍了如何生成总计为0.0的n大小的随机浮点数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑我需要一个n大小的向量,其中每个元素都定义在[-1,1]之间.元素a [i]是由-1 + 2 * rand()生成的浮点数.我需要一种优雅的方法来确保数组元素的总和等于零.

Consider that I need a n-sized vector where each element is defined between [-1,1]. The element a[i] is a float generated by -1 + 2*rand(). I need a elegant way to ensure that the sum of the elements of my array is equal to zero.

我找到了两种可能的解决方案:

I've found two possible solutions:

第一个是这个matlab函数 https://www.mathworks.com/matlabcentral/fileexchange/9700-random-vectors-with-fixed-sum .它在R中也有一个实现,但是在C上实现它的工作量很大,因为该函数用于2d数组.

The first one is this matlab function https://www.mathworks.com/matlabcentral/fileexchange/9700-random-vectors-with-fixed-sum. It has also a implementation in R, however it is too much work to implement it on C, since this function is used for a 2d array.

此线程在此处提供第二个:在C ++中生成具有固定总和的随机值.本质上,想法是生成具有正态分布的n个数字,然后用我的总和将它们归一化.(我已经使用python波纹管实现了它),向量总计为1.0.它适用于除零以外的每个总和值.

The second one is provided in this thread here: Generate random values with fixed sum in C++. Essentially, the idea is to generate n numbers with a normal distribution then normalize them to with my sum. (I have implemented it using python bellow) for a vector with sum up to 1.0. It works for every sum value except for zero.

import random as rd

mySum = 1;
randomVector = []
randomSum = 0

for i in range(7):
    randomNumber = -1 + 2*rd.random()
    randomVector.append(randomNumber)
    randomSum  += randomNumber

coef = mySum/randomSum
myNewList = [j * coef for j in randomVector]
newsum = sum(myNewList)

那么,有没有办法使用C或C ++做到这一点?如果您知道已经实现的功能,那就太好了.谢谢.

So, is there a way to do that using C or C++? If you know a already implemented function it would be awesome. Thanks.

推荐答案

再次感谢您的帮助.

因此,基于 Cryostasys 的想法,我开发了以下C代码来解决我的问题:

So, based on the idea of Cryostasys I developed the following C code to solve my problem:

#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
#include <math.h>

int main()
{
    int arraySize = 10; //input value 
    double createdArray[arraySize]; //output value

    double randomPositiveVector[arraySize];
    double randomNegativeVector[arraySize];
    double positiveSum = 0.;
    double negativeSum = 0.;

    srand(time(NULL)); //seed for random generation

    for(int i = 0; i < arraySize; ++i)
    {
        double randomNumber = -1.+2.*rand()/((double) RAND_MAX); //random in [-1.0,1.0]
        printf("%f\n",randomNumber);
        if(randomNumber >=0)
        {
            randomPositiveVector[i] = randomNumber;
            positiveSum += randomNumber;
        }
        else
        {
            randomNegativeVector[i] = randomNumber;
            negativeSum += randomNumber;
        }
    }
    if(positiveSum == 0. || negativeSum == 0.) printf("ERROR\n");

    double positiveCoefficient =  1.0/positiveSum;
    double negativeCoefficient = -1.0/negativeSum;
    for(int i = 0; i < arraySize; ++i)
    {
        randomPositiveVector[i] = positiveCoefficient * randomPositiveVector[i];
        randomNegativeVector[i] = negativeCoefficient * randomNegativeVector[i];
        if(fabs(randomPositiveVector[i]) > 1e-6) //near to zero 
        {
            createdArray[i] = randomPositiveVector[i];
        }
        else
        {
            createdArray[i] = randomNegativeVector[i];
        }
    }

    for(int i = 0; i < arraySize; ++i)
    {
        printf("createdArray[%d] = %9f\n",i,createdArray[i]);

    }

    return(0);
}

请注意,如问题注释中所述,所生成的值的随机度减小了.同样,随机分布的类型由您用来生成上述randomNumber的函数确定.在这种情况下,我使用了 stdlib.h 中的 rand(),它是基于给函数提供种子的,它会生成一个伪随机数.您也可以使用其他选项,例如,来自 stdlib.h drand48().

Please note that the randomness of the values generated is decreased, as mentioned in the comments of the question. Also, the kind of random distribution is determined by the function that you use to generate the randomNumber above. In this case, I've used rand() from stdlib.h which is based on giving a seed to the function and it is going to generate a pseudo-random number. You could use a different option, for instance, drand48() from stdlib.h as well.

尽管如此,要求至少产生一个正值和一个负值才能使此代码工作.在代码中添加了一个验证步骤,如果达到此条件,则应再次运行代码或执行某些操作.

Nevertheless, it is required that at least one positive and one negative value is generated in order to this code work. One verification step was added to the code, and if it reaches this condition one should run again the code or do something about.

输出示例(arraySize = 10):

Output example (arraySize = 10):

createdArray[0] = -0.013824
createdArray[1] =  0.359639
createdArray[2] = -0.005851
createdArray[3] =  0.126829
createdArray[4] = -0.334745
createdArray[5] = -0.473096
createdArray[6] = -0.172484
createdArray[7] =  0.249523
createdArray[8] =  0.262370
createdArray[9] =  0.001640

这篇关于如何生成总计为0.0的n大小的随机浮点数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆