I'm working on a game where a user is given a random reward with each reward's chance of being delivered weighted by a "share" system. To illustrate the issue, let's look at an example:
Let's say I was going to give a pure random reward, out of set: [A, B, C]. It would be as simple as getting a random index and returning whatever reward from the array.
In my use case, however, the reward set is weight with a "share" system. So we have a situation like below:
- A - Weight of 2.
- B - Weight of 3.
- C - Weight of 5.
So the set looks like something like this: [A, A, B, B, B, C, C, C, C, C].
Now, I could just build out that array and get a random result like that, but I'm concerned about performance implications. These rewards are stored in a database (using Django and PSQL as the backend if that factors in), and there may be upwards of 100 potential rewards, each with a weight of 1-100 (or more).
So I'm trying to figure out an efficient method to pull a random reward based on such weight.
As I'm writing this, one thing the comes to mind (but I'd like to hear other thoughts):
- After a reward set is updated, build out the array once, and then assign each reward a percentage chance. So calculate percentage once.
- In the above, we would end up with something like: [A: 0.2, B: 0.3, C: 0.5].
- Then we could get a random number between 0 and 1, and pull the reward that's the closest without going over? (so a random roll of 0.45 would get B since 0.3 is closest to 0.45 without being higher than 0.45).
- I'm struggling to think how one would write a performant query for this however. Maybe query all rewards with percentages below the roll (0.45 in example above) and return the one with the highest percent from those results.
I think I might have just answered my own question, but would appreciate a third-party perspective. Thanks all!