Need an altered RNG algorithm

I’m trying to write an algorithm where it will generate a random float between 0 and 1.

But I want to create a variable that alters the average number outputted by this algorithm

For example I want the most likely number to be 0.2. So the numbers outputed by this function are more likely to be around 0.1, 0.2, 0.3. and unlikely to be around 1, 0.9, 0.8.

I was also hoping I could have a min and max variable as well. I know I could just math.Clamp but I want the furthest number away from the desired number to almost never come up. Clamping would make the less likely number still come up a fair amount.

I know this would just be a single formula but I don’t know how complicated this will be. And I don’t know where to start. I’ve been looking into beta distributions but I cant find an Algorithm for this without there being a built in one.

Any help on this would be much appreciated.

thanks ~ Anon

This article, although for a different language, may help

You could also use my solution to this problem.

The main advantage of this is just how simply you can edit and visualize distribution.

1 Like

Very smart way of tackling this, Never would have thought of it!

1 Like

You can roll two or three dice to get a non-uniform distribution.
That is, (math.random() + math.random()) / 2 will give you a pyramidal distribution with values closer to 0.5 appearing a lot more often than near 1 or 0. If you average 3 dice instead, you get a bell curve.
However, the distribution is always symmetrical.

You can also square a random number 0-1 to get a lower random number.
math.random() ^ 2 will get you a distribution where 0-adjacent values are a lot more common than high values. The distribution should look like a straight line going down iirc.

After some tinkering, I combined the two. I’m not sure what the curve should look like, though.

((math.random() ^ 1.5) + (math.random() ^ 1.5)) / 2

Example with 10000 samples:

{ [0] = 26, 55, 74, 76, 78, 86, 78, 83, 98, 112, 115, 111, 91, 101, 118, 118, 
  122, 134, 137, 101, 129, 144, 144, 144, 172, 163, 136, 149, 157, 149, 174, 
  154, 160, 175, 163, 153, 185, 158, 152, 183, 179, 172, 188, 187, 191, 181, 
  170, 193, 171, 185, 170, 157, 145, 135, 147, 130, 121, 123, 98, 124, 110, 90, 
  97, 93, 89, 78, 83, 69, 58, 61, 66, 69, 63, 59, 48, 45, 50, 44, 46, 54, 42, 
  32, 35, 39, 31, 32, 28, 21, 24, 19, 23, 15, 18, 15, 8, 7, 6, 7, 1, 0 }

Definitely use @tlr22’s solution, it lets you design the probability curve.

edit: christ, it still has a peak at 0.5

===============
=======================
============================
===============================
==================================
=====================================
=======================================
========================================
===========================================
============================================
=============================================
===============================================
================================================
=================================================
===================================================
====================================================
=====================================================
======================================================
=======================================================
========================================================
=========================================================
==========================================================
===========================================================
============================================================
============================================================
=============================================================
==============================================================
===============================================================
=================================================================
=================================================================
==================================================================
===================================================================
==================================================================
===================================================================
====================================================================
=====================================================================
=====================================================================
======================================================================
=======================================================================
========================================================================
========================================================================
========================================================================
=========================================================================
==========================================================================
==========================================================================
===========================================================================
============================================================================
=============================================================================
============================================================================
==============================================================================
=========================================================================
====================================================================
================================================================
============================================================
=========================================================
=======================================================
===================================================
=================================================
===============================================
==============================================
============================================
=========================================
========================================
======================================
=====================================
===================================
==================================
================================
===============================
==============================
============================
===========================
=========================
========================
=======================
======================
=====================
====================
===================
==================
=================
===============
===============
==============
============
============
===========
==========
=========
========
=======
======
=====
=====
====
===
==
=
=

I see a few ways of doing this, the solutions above work.

If you just want a series of values that can be returned each with a different probability, there’s no need to do any real math. You could just create a table of values (e.g [0.1,0.1,0.1,0.2,0.2,0.2,0.2 … etc.]) each with a different number of repetitions and then call math.random from 1 to the length of the table itself. This would create a pseudo-random weighted system for picking values.

Alternatively, you could randomise each step of the process. You could first randomise whether or not the number returned is greater than the mean. Then increment into smaller, less likely batches of numbers. You could continue doing this, almost like a binary search tree until you have a range of values small enough (e.g 0.1 < x < 0.2). This does have the pretty major drawback that instead of it being a smooth distribution of probability, it would be more like certain ranges of numbers have that probability.

The best way would be some kind of distribution. The issue with this is that it really requires a lot of math. Gaussian distribution would be fairly easy, but realistically this problem would want something like Gamma distribution. The math for Gamma distributions and functions is available, programming it is possible, just fairly time consuming. Most languages have libraries for this kind of thing like numpy.random.gamma which would simplify the process massively. This video seems to describe a possible methodology fairly well:

I’ll definitely have a go at putting it into code myself at some point, maybe even make a module.