1

I somehow need to find a solution to the problem, though, can't know exactly what and how this can be achieved.

Let's imagine I have some properties

prop1 - 7%

prop2 -3%

prop4 - 35%

and so on. those values above (7,3,35) are percentage changes of being picked.

Now, I have a random number between 0 and 1.

Can I somehow use the above information and pick the property depending on that random number and the percentages ?

how can it be possible ? sorry for my out-of-this-world question.

Nika Kurashvili
  • 6,006
  • 8
  • 57
  • 123

1 Answers1

2

You can use a random number to pick an option in a weighted list of options, whether the sum of all weightings adds to 100 or not, using this algorithm:

  1. Create a random number between 0 and 1
  2. Multiple that random number by the sum of your weightings
  3. Iterate through your options, keeping a running total of the weightings of all options considered so far. Once your running total is above the number you calculated, you have found your picked item

Some example code:

const options = [
    {
        id: 1, weight: 0.5
    },
    {
        id: 2, weight: 2
    },
    {
        id: 3, weight: 1
    },
];

const pick = function (options) {
    const weightTotal = options.reduce((sum, option) => sum + option.weight, 0);

    const seed = Math.random();
    const weightedSeed = seed * weightTotal;

    let runningTotal = 0;
    for (let option of options) {
        runningTotal += option.weight;

        if (runningTotal > weightedSeed) {
            return option;
        }
    }
};

console.log(pick(options).id);

This method requires you to have your available options be iterable, but their order doesn't matter since you're using a random seed anyway.

Mark Hanna
  • 3,206
  • 1
  • 17
  • 25
  • 1
    Thanks a lot Mark. This is what I needed. Though, I might ask: I somehow need to have my own seed to have reproducible randomness. In this case, does it matter to have options list with weights in the particular sequence ? – Nika Kurashvili Nov 07 '21 at 22:52
  • 1
    So I will have something like this `seed(100); var num = Random() * 100;` `num` will be my random now – Nika Kurashvili Nov 07 '21 at 22:55
  • @NikaKurashvili if you need to be able to get consistent results with the same seed then yes, you will need to make sure your options appear in a consistent order when you're iterating through them like that. Though usually I wouldn't expect that to be a problem - typically you'd need to do additional work to make the ordering inconsistent. – Mark Hanna Nov 07 '21 at 22:58
  • what does consistend order mean here ? like in weights ascending order ? – Nika Kurashvili Nov 07 '21 at 23:05
  • 1
    Just that each time you iterate through your options, they'll be in the same order. It doesn't matter what particular order they are in, only that it's the same each time. – Mark Hanna Nov 07 '21 at 23:07