Select Page

Weighted Random Numbers in Javascript

Posted on July 15, 2017
James Quick, Social Developer

One small problem I came across recently was how to generate a random set of numbers from a given range that each had weights.  I needed to find the simplest way to generate dummy data that looked relatively close to what “real” data would look like.

The Scenario

Let’s say for this example, you run a restaurant and want to create sample data set to represent the status of your tables. Each table can only be in one of three different states: occupied, empty but not yet cleaned, and ready for a customer. For simplicity let’s represent these states by a number: 1- occupied, 2 – empty but not yet cleaned, and 3 – ready for a customer. While mocking up this data for a Saturday night, you know the majority of the tables are typically in state 1 (occupied), let’s say ~80% of them. Then ~10% of tables are in state 2 and the last ~10% are in state 3. Let’s take a look at how to generate random data that adhere to this guideline.

The Solution

If I know I have many numbers I want, the simplest structure to represent the data is an array.  So, what we will is iterate through 20 times and push a new weighted random number to the array.  Generating the weighted random number is not incredibly complex but is a tad bit tricky.  Let’s start with creating a random number between 1 and 100.

We will use Math.random() which generates a decimal between 0 (inclusive) and 1 (exclusive).  Now, to get a number between 1 and 100, we take the result of Math.random, then multiply it by 100 and then add 1 (add 1 so that we go from 1-100 instead of 0-99).  Looks like this.

(Math.random()*10) + 1

The next step is to convert that result from a number with a decimal to an interger.  For that we can use Math.floor();

Math.floor((Math.random()*10) + 1)

Now, we should be getting an integer between 1 and 100, but you might be wondering how that helps us.  Well, notice that I broke down the weightedness (that may not be a word but who cares) of the table statuses to percentages.  Conveniently, the percentages (80 + 10 +10) sum up to 100.  So my thought is that for every random number we generate, if it’s between 1-80, it’s status 1, 81-90 is status 2, and 91-100 is status 3.  After doing this 20 times, we should get  a set of random data that maps closely to a typical Saturday night.  Here’s what it looks like.

var tableStatuses = [];

for ( var i = 0; i< 20; i++){
    var num = Math.floor((Math.random()*100) + 1);
    var status = 0;
    if(num <= 80){
        status = 1;
    }
    else if (num <=90) {
        status = 2;
    }
    else {
        status = 3;
    }
    tableStatuses.push(status);
}
console.log("Statuses", tableStatuses)


And here’s what the data looks like…

[“1”, “3”, “1”, “1”, “1”, “2”, “1”, “1”, “1”, “3”, “1”, “1”, “3”, “3”, “1”, “1”, “1”, “1”, “2”, “1”]

Looks pretty good.  Most of the tables are occupied as we would expect, and then a few that are empty and clean and a few that are empty but not clean.  Hope this helps you mock up some data in the future!

Subscribe

Subscribe

Javascript. Node. Angular. Bootstrap. Wordpress. You name it.  If you are a current or aspiring web developer looking to learn more, then subscribe!  I will share the latest news and tutorials as well as exclusive assets.

Thank you for subscribing!

Pin It on Pinterest

Share This

Share this post with your friends!