Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Random but most likely 1 float

Tags:

java

random

math

I want to randomize a float that so that

  • There is 95% chance to be about 1
  • There is 0.01% chance to be < 0.1 or > 1.9
  • It never becomes 0 or 2

Is this possible by using Random.nextFloat() several times for example?

A visual illustration of the probability:

A visual illustration of the probability

like image 915
Solver42 Avatar asked Feb 06 '16 05:02

Solver42


2 Answers

You need to find a function f such that:

  1. f is continuous and increasing on [0, 1]

  2. f(0) > 0 and f(1) < 2

  3. f(0.01) >= 0.1 and f(0.99) <= 1.9

  4. f(x) is "about 1" for 0.025 <= x <= 0.975

And then just take f(Random.nextDouble())

For example, Math.tan(3*(x-0.5))/14.11 fits this, so for your expression I'd use:

Math.tan(3*(Random.nextDouble()-0.5))/14.11

The probability is distributed as:

Wolfram cloud session

like image 136
Daniel Martin Avatar answered Oct 19 '22 10:10

Daniel Martin


I do not code in JAVA but anyway, if I would want to use the internal pseudo-random generator (I usually use different approaches for this) I would do it like this:

  1. Definitions

    Let's say we have pseudo-random generator Random.nextFloat() returning values in range <0,1> with uniform distribution.

  2. Create mapping from uniform <0,1> to yours (0,2)

    It would be something like:

    mapping

    THE 0.001 SHOULD BE 0.0001 !!! I taught it was 0.1% instead 0.01% while drawing ...

    Let's call it f(x). It can be a table (piecewise interpolation), or construct some polynomial that will match the properties you need (BEZIER,Interpolation polynomials,...)

    As you can see the x axis is the probability and the y axis is the pseudo-random value (in your range). As built-in pseudo-random generators are uniform, they will generate uniformly distributed numbers between <0,1> which can be directly used as x.

    To avoid the 0.0 and 2.0 either throw them away or use interval <0.0+ulp,2.0-ulp> where ulp is unit in last place

    The graph is drawn in Paint and consists of 2x cubic BEZIER (4 control points per cubic) and a single Line.

  3. Now just convert the ranges

    So your pseudo-random value will be:

    value=f(Random.nextFloat());
    

[Notes]

This would be better with fixed point format numbers otherwise you need to make the curvatures insanely high order to make any effect or use very huge amount of data to match desired probability output.

like image 2
Spektre Avatar answered Oct 19 '22 10:10

Spektre