2
\$\begingroup\$

I'm doing some procgen stuff and I need a truncated gaussian distribution. Basically, I need a way to get the same thing as this:

import random
def truncated_gaussian(mean, deviation, min, max):
    while True:
        val = random.gauss(mean, deviation)
        if min < val < max: return val

except without so much wasted effort. It looks like this is a pretty complicated thing to do properly, but I don't need statistics-grade perfect randomness, just a video-game-grade approximation.

Anyone know a trick to make this work?

\$\endgroup\$
1
  • \$\begingroup\$ You might also be able to do this via inverse transform sampling, re-scaling the CDF to your desired range and clamping it before sampling the resulting function's inverse. I think you'd want to approximate it as a spline since it's not expressible in elementary functions... \$\endgroup\$
    – DMGregory
    Commented Sep 1, 2019 at 7:51

1 Answer 1

2
\$\begingroup\$

When all else fails, cheat. You could either generate 10,000 (or 1,000,000 or whatever) Gaussian randoms at startup, or put them in a resource and load them at start up, then generate one random offset into the list and start reading them as needed. Then it would be as fast as a look-up.

\$\endgroup\$
2
  • \$\begingroup\$ Oh, of course! And then if I run out it should work to just re-use the same values over and over again if there's enough of them. \$\endgroup\$
    – Schilcote
    Commented Sep 1, 2019 at 5:27
  • \$\begingroup\$ Yes, that's the idea. You can index into the array using a modulus operator. Like if it's called nextIndex you could grab the next random number by doing foo = randoms [ nextIndex ]; nextIndex = (nextIndex + 1) % kNumRandoms; \$\endgroup\$ Commented Sep 1, 2019 at 5:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .