“加权”随机数发生器

时间:2013-01-03 16:37:58

标签: objective-c ios

我目前正在使用以下代码从数组中获取随机元素。我将如何更改代码,以便返回一个按照我希望它出现的百分比加权的元素?例如,我希望索引0处的元素在27.4%的时间内上升,但索引7处的元素仅占5.9%的时间。

NSArray *quoteArray = @[    @"quote1",    @"quote2",    @"quote3",    @"quote4",    @"quote5",    @"quote6",    @"quote7",    @"quote8",    ];    

NSString *quoteString;

int r = arc4random() % [quoteArray count];
if(r<[rewardTypeArray count])
    quoteString = [quoteArray objectAtIndex:r];

3 个答案:

答案 0 :(得分:6)

我会使用一个float数组(包装成NSNumber)对象。

每个对象代表一个百分比。在这种情况下,您将拥有一个包含8个对象的数组:

  

对象1:@ 27.5;

     

...

     

对象7:@ 5.9。

然后你得到一个从1到100的随机数。如果你想要更高的精度,你也可以得到一个带小数部分的随机数,精度不影响效率,也不影响使用的内存。

然后,当您获得遍历所有数组的数字时,跟踪索引和您拥有的百分比。您使用浮点数来汇总所有已达到的百分比,并且仅当总百分比大于您拥有的百分比时才停止。

示例

NSArray* percentages= @[ @27.4 , ... , @5.9];
float randomNumber= arc4random_uniform(100) + (float)arc4random_uniform(101)/100;  
NSUInteger n=0;
float totalPercentage= 0.0;
for(NSUInteger i=0; i<percentages.count; i++)
{
    totalPercentage+= [ percentages[i] floatValue ];
    if( totalPercentage >= randomNumber)  // This case we don't care about
                                          // the comparison precision
    {
        break;
    }
    n++;
}
// Now n is index that you want

答案 1 :(得分:4)

最简单的方法是根据您希望百分比的细粒度生成随机数。要计算到十分之一的百分比,您可以生成0-1000之间,并且可以随机生成的值中的274将是第一个元素。 59个值对应于元素7.

例如:

0-273    = index 1 27.4%
274-301  = index 2 2.7%
302-503  = index 3 20.1%
504-550  = index 4 4.6%
551-700  = index 5 14.9%
701-941  = index 6 24%
942-1000 = index 7 5.9%

百分比没有正确加起来,所以我在某个地方做错了数学,但你明白了。

答案 2 :(得分:0)

您可以创建另一个带有计数器的数组,该数组将跟踪每个元素生成的次数。如果该计数器小于您的目标,则让该索引进入您的r,否则重新生成。