How to generate a bounded, random value where the inputs are the "mean" and the "amount of randomness"?

87 Views Asked by At

While creative coding I often find myself wanting to generate a random value for certain parameters in my artworks based on a specific value within the parameter's bounds.

If the parameter's minimum value is 0.0 and its maximum value is 1.0, I want to be able to generate a random value within this range by specifying two inputs: a and r where a is the mean value (the value most likely to be selected) and r is the "amount of randomness" (where 0.0 is "no randomness" and 1.0 is "full randomness") to be applied to the sampling process.

Here are some examples of the behaviour I'd like:

  • if a is 0.3 and r is 0.0 (no "randomness"), the function should always return 0.3.
  • if a is 0.3 and r is 1.0 (100% "randomness"), the function will sample from a uniform distribution between 0.0 and 1.0.
  • if a is 0.3 and r is 0.5 (50% "randomness"), the function will:
    • most likely return 0.3
    • least likely return 1.0 (as it is the furthest "distance" away from a)
    • have the same likelihood of returning 0.0 and 0.6 (as they are equal "distance" away from a)

Currently I'm doing an embarassing job of this with a function that uses an offset, truncated, heavily tweaked and massaged gaussian distribution. It is very inefficient and quite inconsistent, so I thought it was about time I reached out to the experts to see if there is a more suitable solution.

Any assistance or guidance would be greatly appreciated!

1

There are 1 best solutions below

0
On

A simple way to do what I think you're trying to do is the following. If $r=0$ then you just return $a$; if $r=1$ then you just return a U(0,1). Technically these could be done using the framework I'm about to describe but it sounds inefficient and error-prone to do it that way.

In the interesting intermediate case, you first generate a Bernoulli random variable with success probability $a$. If you got a success, then you return an independent U(0,a) variable. If you got a failure, then you return an independent U(a,1) variable.

This last case can be done something like this (in Pythonish syntax):

u1=rand()
u2=rand()
if u1<a:
  return a*u2
else:
  return a+(1-a)*u2