想了一天,郁闷呀!
其实也就是在MIn 和MAX 之间选N个数 平均值是AVER
那么可转换为在0~(MAX-MIN) 之间选N个平均值是AVER-MIN=iAver
我们先选N个数 和是Sum 但是要求和是iAve这样平均值才能保证。那么就缩放
现有数值iAver*Count/Sum倍保证整数就加上0.5.这时在求和Sum1,Sum1就接近或等于iAver*Count这时在数据上在修正Sum1与iAver*Count之间的差距每个数据上修正一个单位并保证每个数据的范围在0~(MAX-Min)之间。函数如下:
bool CAverageDlg::RandAver(UINT Count ,int Max,int Min,int Aver,int *Data)
{
if(Aver>=Max)
return FALSE;
if(Aver<=Min)
return FALSE;
if(Max==Min)
return FALSE;
if(Count==0)
return FALSE;
int iMax=Max-Min;
int iData[256]={0};
int iAver=Aver-Min;
long lSum=0;
srand((unsigned) time(NULL));
for(int i=0;i<Count;i++)
{
iData[i]=rand()%iMax;
lSum+= iData[i];
}
long lSum1=0;
for(int i=0;i<Count;i++)
{
iData[i]=iData[i]*iAver*Count*1.0/lSum+0.5;
if(iData[i]>iMax)
iData[i]=iMax;
lSum1+=iData[i];
}
int iTmp=(lSum1-iAver*Count);
if(iTmp!=0)
{
for(int i=0,j=0;i<abs(iTmp);)
{
if(iData[j]+(lSum1-iAver*Count)/abs(iTmp)<0)
{
j++;
}
else
if(iData[j]+(lSum1-iAver*Count)/abs(iTmp)>iMax)
{
j++;
}
else
{
iData[j]-=(lSum1-iAver*Count)/abs(iTmp);
j++;
i++;
}
}
}
for(int i =0;i<Count;i++)
Data[i]=iData[i]+Min;
//delete iData;
return TRUE;
}