Timeline for Random number in a range, biased toward the low end of the range
Current License: CC BY-SA 4.0
20 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| Oct 3, 2024 at 2:40 | history | edited | DMGregory♦ | CC BY-SA 4.0 | Adding simpler version |
| Jun 17, 2022 at 13:30 | comment | added | Chris Pfohl | Anyone popping in here in ruby-land needing a functional implementation of this as a method: def random_weighted_low(range) (((rand() - rand()).abs * (1 + range.max - range.min)) + range.min).floor end | |
| Nov 10, 2016 at 18:05 | history | edited | DMGregory♦ | CC BY-SA 3.0 | Taking a correction from the comments and making it more prominent in the answer |
| Oct 5, 2016 at 0:41 | comment | added | Logan Pickup | @DMGregory I agree, the inverse transform sampling method doesn't have this problem | |
| Oct 4, 2016 at 1:45 | comment | added | DMGregory♦ | @LoganPickup I think you're right. The Inverse Transform Sampling version should avoid this artifact. I think there should be a way to correct the two-roll version too - I'll update the answer if I think of such a method. | |
| Oct 4, 2016 at 0:56 | comment | added | Logan Pickup | I know this is about real numbers, but if using integers then abs(random(0, n) - random(0, n)) peaks not at 0, but at 1. Does this mean that if a range [0,1) is generated by random() as being [0, n) / n (which is how random number generators I am aware of work), this formula will have an unexpected dip at 0? | |
| Feb 21, 2016 at 15:49 | history | edited | DMGregory♦ | CC BY-SA 3.0 | Explaining why last edit was rolled back. |
| Feb 21, 2016 at 15:47 | history | rollback | DMGregory♦ | Rollback to Revision 4 | |
| S Feb 20, 2016 at 16:34 | history | suggested | user70223 | CC BY-SA 3.0 | fixed bracket |
| Feb 20, 2016 at 15:57 | review | Suggested edits | |||
| S Feb 20, 2016 at 16:34 | |||||
| Feb 20, 2016 at 13:59 | history | edited | DMGregory♦ | CC BY-SA 3.0 | adding inverse approach |
| Feb 19, 2016 at 15:51 | comment | added | DMGregory♦ | Not that I'm complaining about the upvotes, but don't forget to spread the love a bit. ;) This was just a quick off-the-cuff answer - the power-based approaches in some of the other answers offer more flexibility in the falloff of the probability distribution, with similar simplicity. | |
| Feb 19, 2016 at 7:05 | vote | accept | Standard | ||
| Feb 18, 2016 at 19:38 | comment | added | DMGregory♦ | @DietrichEpp I've updated the rounding function to floor, which should keep the distribution linear, including for the min & max buckets. | |
| Feb 18, 2016 at 19:36 | history | edited | DMGregory♦ | CC BY-SA 3.0 | Changing rounding function to better handle the extreme cases |
| Feb 18, 2016 at 19:10 | comment | added | Dietrich Epp | To expand on this answer: this trick works with random() returning float/double but it doesn't work if you use random integers, because the probability of returning min will be about half of what it should be. For continuous or high-resolution outputs, the probability of returning min is approximately 0 anyway so it doesn't matter. | |
| Feb 18, 2016 at 15:47 | comment | added | DMGregory♦ | @user1306322 because random() is uniformly distributed on [0, 1), so random() * 2 - 1 is uniformly distributed on [-1, 1) - it doesn't have the non-uniformity OP has asked for. By taking two independent random rolls a and b, we introduce some non-uniformity: there are more ways to get 0 (all cases a == b) than there are to get 1 (only a == 1, b == 0 fits the bill - this is a simplification since 1 is actually outside the range of this function, but the extreme is easier to talk about) | |
| Feb 18, 2016 at 13:47 | history | edited | DMGregory♦ | CC BY-SA 3.0 | Adding related link, clarifying assumption |
| Feb 18, 2016 at 13:45 | comment | added | Vaillancourt♦ | Ooh! That's clever! | |
| Feb 18, 2016 at 13:42 | history | answered | DMGregory♦ | CC BY-SA 3.0 |