0

我有一个元素数组。每个元素都有一个附加的概率值。可以说我有一系列苹果,红色,黄色,绿色,蓝色等,就像这样。

- (Apple *)pickRandomApple
{
    Apple *red = [Apple redApple];
    Apple *green = [Apple greenApple];
    Apple *yellow = [Apple yellowApple];
    Apple *blue = [Apple blueApple];

    red.probability = 0.23f;
    green.probability = 0.85f;
    yellow.probability = 0.1f;
    blue.probability = 0.5f;
    NSArray *array = @[red,green,blue,yellow];

    return array[arc4random()%array.count];
}

我想根据概率属性选择一个随机苹果。我怎样才能做到这一点?

谢谢!

4

3 回答 3

1

一种可能的解决方案是将项目(概率*精度)时间添加到数组中并在其上使用随机数。

否则,您可以总结您的概率并定义区域

double max = (red.probability + green.probability + yellow.probability 
+ blue.probability) * 100.f;

int random = arc4random()%(int)max;

if(random < red.probability * 100)
    return red;
else if(random < (red.probability + blue.probability) * 100)
    return blue:
...

等等。

也可以为此创建一个for循环:)

更新

double max = (red.probability + green.probability + yellow.probability 
+ blue.probability) * 100.f;
// max = (0.23 + 0.85 + 0.1 + 0.5) * 100; // = 1.68 * 100 = 168 

int random = arc4random()%(int)max;

if(random < red.probability * 100) // area 0 - 23
    return red;
else if(random < (red.probability + blue.probability) * 100) // area 24 - 108
    return blue:
...

在循环中你可以保存一个 currentValue 变量

double max = (red.probability + green.probability + yellow.probability 
+ blue.probability) * 100.f;
// max = (0.23 + 0.85 + 0.1 + 0.5) * 100; // = 1.68 * 100 = 168 

int random = arc4random()%(int)max;
int currentValue = 0;

for(Apple *apple in array)
{
    currentValue += (int)(apple.probability * 100.f);
    if(random <= currentValue)
        return apple;
}

用测试值试试这个,如果它没有按你的意愿工作,告诉我你错过了什么:)

于 2013-07-04T10:44:07.833 回答
0

我从你的问题中了解到,你想用强度来产生概率,比如绿色比红色更可能发生等等......这个问题与 iOS 或 iPhone 开发无关,它是纯粹的编程问题,我没有不要认为只有一种解决方案。这是我的解决方案,我通常想使用简单的解决方案。

在发布代码之前,我想解释一下我的想法。这道题和我们高中时学过的概率题类似,所以我就用同样的方法来解答。我也会使用你的号码。因此,假设您有一个包含 23 个红球、85 个绿球、10 个黄球和 50 个蓝球的盒子。所有这些球都在一个盒子里,你必须从盒子里随机选择一个球,因此红色的概率是 0.23,绿色的概率是 0.85...

这是我的彩球盒:

char apples[] = {'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'b', 'b', 'b', 'b', 'b', 'r', 'r', 'y', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'b', 'b', 'b', 'b', 'b', 'r', 'r', 'y', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'b', 'b', 'b', 'b', 'b', 'r', 'r', 'y', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'b', 'b', 'b', 'b', 'b', 'r', 'r', 'y', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'b', 'b', 'b', 'b', 'b', 'r', 'r', 'y', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'b', 'b', 'b', 'b', 'b', 'r', 'r', 'y', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'b', 'b', 'b', 'b', 'b', 'r', 'r', 'y', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'b', 'b', 'b', 'b', 'b', 'r', 'r', 'y', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'b', 'b', 'b', 'b', 'b', 'r', 'r', 'y', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'b', 'b', 'b', 'b', 'b', 'r', 'r', 'y', 'r', 'g', 'g', 'r', 'g', 'g', 'r', 'g'};

您注意到我使用特殊分布将球分布在阵列中。好吧,想象一下使用您的数字的盒子示例。你有 10 个黄球和 85 个绿球,这意味着我希望在每 1 个黄球旁边的框中看到 8 个绿球,同样我希望看到 5 个蓝球和 2 个红球。而且由于绿色是最有可能的,我希望首先看到它。因此,您可以看到我的数组具有以下模式:

'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'b', 'b', 'b', 'b', 'b', 'r', 'r', 'y',

每1个黄色,8个绿色,5个蓝色,2个红色。由于还有一些红色和绿色,我将它们添加到数组的末尾。

现在这个过程非常简单,因为这个集合包含 168 个球,所以我做了一个循环,运行 168 次,每次它生成一个从 0 到 167 的数字。我使用这个数字是数组的索引,apples我看看我得到了哪个球.

int counters[4] = {0, 0, 0, 0};
int x;
for(int i=0; i<168; i++)
{
    x = arc4random()%168;
    if(apples[x] == 'r') counters[0]++;
    else if(apples[x] == 'g') counters[1]++;
    else if(apples[x] == 'y') counters[2]++;
    else if(apples[x] == 'b') counters[3]++;
}

NSLog(@"Red:    %i%%", counters[0]);
NSLog(@"Green:  %i%%", counters[1]);
NSLog(@"Yellow: %i%%", counters[2]);
NSLog(@"Blue:   %i%%", counters[3]);

以下是程序在不同执行时的示例输出:

2013-07-04 19:48:54.557 DOS[798:707] Red:    24%
2013-07-04 19:48:54.560 DOS[798:707] Green:  78%
2013-07-04 19:48:54.562 DOS[798:707] Yellow: 11%
2013-07-04 19:48:54.563 DOS[798:707] Blue:   55%

2013-07-04 19:49:04.899 DOS[811:707] Red:    21%
2013-07-04 19:49:04.901 DOS[811:707] Green:  81%
2013-07-04 19:49:04.905 DOS[811:707] Yellow: 9%
2013-07-04 19:49:04.906 DOS[811:707] Blue:   57%

2013-07-04 19:49:15.243 DOS[824:707] Red:    20%
2013-07-04 19:49:15.246 DOS[824:707] Green:  89%
2013-07-04 19:49:15.246 DOS[824:707] Yellow: 8%
2013-07-04 19:49:15.247 DOS[824:707] Blue:   51%

您可以随心所欲地使用阵列来增强结果。

于 2013-07-04T16:50:31.523 回答
0

这是我的方法,它更通用一些。随时提问/编辑

/**
 @param probabilitiesArray - array of integers who represent probabilities.
 If the first var in the array is 20 and the rest of the array's variables 
 sum up to 100 - there are 20% probability for first var to be chosen.
 */
-(int) randomNumberWithProbabilities:(NSArray *) probabilitiesArray
{
    //Sum up all the variables in the array
    int arraySum = 0;
    for(int i = 0;i < probabilitiesArray.count;i++)
    {
        arraySum += [probabilitiesArray[i] intValue];
    }

    //Random a number from 0 to the sum of the array variables
    int randomNumber = arc4random_uniform(arraySum);

    //Iterating through the array variable and detect the right slot for the random number
    int tempSum = 0;
    for(int i = 0;i < probabilitiesArray.count;i++)
    {
        tempSum += [probabilitiesArray[i] intValue];
        if(randomNumber < tempSum)
        {
            return i;
        }
    }
    return 0;
}
于 2015-08-12T16:15:07.653 回答