mercredi 6 janvier 2021

What explains the difference in distribution between these two snippets that choose items at random?

I just did a few tests to figure out some random item determination. Obviously, the first snippet here is the one to use if I ever needed a random item from the items array. But this question is not about that.

PickRandom.js

const items = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ]
    , occurrences = {};

for (let i = 0; i < 1000000; i++)
{
    const item = items[Math.floor(Math.random() * items.length)];
    if (!occurrences[item])
        occurrences[item] = 0;
    occurrences[item]++;
}

Running this resulted in an even distribution of occurrences between each element:

{
  '0': 48093,
  '1': 47603,
  '2': 47631,
  '3': 47793,
  '4': 47621,
  '5': 47562,
  '6': 47679,
  '7': 47495,
  '8': 47868,
  '9': 47485,
  '10': 47626,
  '11': 47472,
  '12': 47524,
  '13': 47809,
  '14': 47713,
  '15': 47519,
  '16': 47582,
  '17': 47065,
  '18': 47729,
  '19': 47595,
  '20': 47536
}

RandomLoop.js

const items = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ]
    , occurrences = {};

for (let i = 0; i < 1000000; i++)
{
    for (const item of items)
    {
        const chance = Math.random();
        if (chance < 1 / items.length)
        {
            if (!occurrences[item])
                occurrences[item] = 0;
            occurrences[item]++;
            break;
        }
    }
}

This snippet however didn't produce the same expected result, with a downward trend of occurrences per item:

{
  '0': 47534,
  '1': 45530,
  '2': 42870,
  '3': 40932,
  '4': 39057,
  '5': 37186,
  '6': 35665,
  '7': 33784,
  '8': 31959,
  '9': 30593,
  '10': 28999,
  '11': 27644,
  '12': 26679,
  '13': 25524,
  '14': 24204,
  '15': 22974,
  '16': 21677,
  '17': 20646,
  '18': 19833,
  '19': 19018,
  '20': 18329
}

Question

I'm wondering why this is happening. Is there something wrong with the latter snippet? Also, the number of occurrences for the latter test doesn't seem to add up to the number of iterations I specified (1,000,000).




Aucun commentaire:

Enregistrer un commentaire