0

Traditionally if I wish to choose a case occurred 25%, I use "arc4random()%" function by integer to trigger the case of 1/4 chance. Now I have 4 cases with float rate. Let's say,

A 0.3055

B 0.391

C 0.165

D 0.1485

A+B+C+D=1

How can I develop a random selector to trigger a case of 4 by properly selecting? Of course, case B gets the most chance to be selected.

Many thanks

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Graphite
  • 346
  • 3
  • 11
  • I posted a solution to a similar question here, http://stackoverflow.com/questions/13635448/generate-random-numbers-within-a-range-with-different-probabilities/13637027#13637027. – user515430 May 01 '14 at 13:10

3 Answers3

2

I don't think this is perfect, but it'll get you close

    int probability = arc4random_uniform(10000);
    NSLog(@"Probability: %i", probability);

    if (probability < 3055) {
        // A
    }
    else if (probability <= (3055 + 3910)) {
        // B
    }
    else if (probability <= (3055 + 3910 + 1650)) {
        // C
    }
    else {
        // D
    }
Logan
  • 52,262
  • 20
  • 99
  • 128
  • The `391` should be `3910` and `165` should be `1650`. – rmaddy May 01 '14 at 05:33
  • +1. Just a bit of explanation: chances of `probability` in the code above will fall within a given range (e.g. `probability < 3055`, `probability <= 3055 +3910` etc) are proportional to the length of that range relative to total length (which is 10000). And the relative length of each range is given by its probability times 10000 (e.g. 3055 = 0.3055 * 10000). – bytefire May 01 '14 at 07:06
  • Thanks. Appreciate your help. – Graphite May 03 '14 at 05:35
1

By selecting with the appropriate probability from a uniform distribution.

int myOwnFunkyDistribution(void)
{
    uint32_t A = 0.3055 * UINT32_MAX;
    uint32_t B = A + 0.3910 * UINT32_MAX;
    uint32_t C = B + 0.1650 * UINT32_MAX;

    uint32_t r = arc4random();

    if (r < A)
        return 0;

    if (r < B)
        return 1;

    if (r < C)
        return 2;

    return 3;
}

With more cases, this is definitely to be refactored using an array and a for loop.

0

You want to do a multinomial sample. You could do this in iOS with GSL or other C- or C++-based statistics libraries.

Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345