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

考えられる解決策の 1 つは、アイテム(確率 * 精度)の回数を配列に追加し、random を使用することです。

それ以外の場合は、確率を合計して領域を定義できます

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の開発とは関係ありません。純粋なプログラミングの質問であり、私は知りませんそれに対する解決策は 1 つだと思います。これが私の解決策であり、通常は単純な解決策を使用したいと思います。

コードを投稿する前に、私の考えを説明したいと思います。この問題は、私たちが高校で習った確率の問題と似ているので、同じように解きます。番号も使用させていただきます。赤のボールが 23 個、緑のボールが 85 個、黄のボールが 10 個、青のボールが 50 個入っている箱があるとします。これらのボールはすべて 1 つのボックスに入っているため、ボックスからランダムに 1 つのボールを選択する必要があるため、赤の確率は 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 個の隣のボックスに表示されることを意味します。そして、緑が最も可能性が高いので、私はそれを最初に目にすることを期待しています. したがって、私の配列には次のパターンがあることがわかります。

'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 に答える