考虑需要一个n大小的矢量,其中每个元素都定义在[-1,1]之间。元素a [i]是由-1 + 2 * rand()生成的浮点数。我需要一种优雅的方法来确保数组元素的总和等于零。
我发现了两种可能的解决方案:
第一个是这个matlab函数https://www.mathworks.com/matlabcentral/fileexchange/9700-random-vectors-with-fixed-sum。它在R中也有一个实现,但是在C上实现它的工作量很大,因为此函数用于2d数组。
此线程在此处提供第二个:Generate random values with fixed sum in C++。本质上,这个想法是生成具有正态分布的n个数字,然后用我的总和将它们归一化。 (我已经使用python波纹管实现了它),向量总计为1.0。它适用于除零以外的每个总和值。
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 ++来做到这一点?如果您知道已经实现的功能,那就太好了。谢谢。
我想出了解决您问题的方法。这不是完美的,因为其randomness受范围要求的限制。
策略是:
执行此操作直到第(n-1)个元素。必须直接将最后一个元素分配为符号已更改的总和。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
float float_rand( float min, float max )
{
float scale = rand() / (float) RAND_MAX; /* [0, 1.0] */
return min + scale * ( max - min ); /* [min, max] */
}
void main( int argc, char *argv[] )
{
if( argc == 2 )
{
int i, n = atoi ( argv[1] );
float *outArr = malloc( n * sizeof( float ) );
float sum = 0;
printf( "Input value: %d\n\n", n );
/* Initialize seed */
srand ( time( NULL ) );
for( i=0; i<n-1; i++ )
{
/* Limit random generation range in order to make sure the next sum is *
* not outside (-1,1) range. */
float min = (sum<0? -1-sum : -1);
float max = (sum>0? 1-sum : 1);
outArr[i] = float_rand( min, max );
sum += outArr[i];
}
/* Set last array element */
outArr[n-1] = -sum;
/* Print results */
sum=0;
for( i=0; i<n; i++ )
{
sum += outArr[i];
printf( " outArr[%d]=%f \t(sum=%f)\n", i, outArr[i], sum );
}
free( outArr );
}
else
{
printf( "Only a parameter allowed (integer N)\n" );
}
}
我尝试过,并且在n = 1时也可以使用。如果n = 0,则应在我的示例中添加健全性检查。
一些输出示例:
N = 1:
Input value: 1
outArr[0]=-0.000000 (sum=-0.000000)
N = 4
Input value: 4
outArr[0]=-0.804071 (sum=-0.804071)
outArr[1]=0.810685 (sum=0.006614)
outArr[2]=-0.353444 (sum=-0.346830)
outArr[3]=0.346830 (sum=0.000000)
N = 8:
Input value: 8
outArr[0]=-0.791314 (sum=-0.791314)
outArr[1]=0.800182 (sum=0.008867)
outArr[2]=-0.571293 (sum=-0.562426)
outArr[3]=0.293300 (sum=-0.269126)
outArr[4]=-0.082886 (sum=-0.352012)
outArr[5]=0.818639 (sum=0.466628)
outArr[6]=-0.301473 (sum=0.165155)
outArr[7]=-0.165155 (sum=0.000000)