Is the Shuffling Algorithm in Javascript Unbiased?

I stumbled upon the algorithm below for shuffling an array in JavaScript. It seems to have a unique twist compared to the traditional Fisher–Yates shuffle method. This algorithm allows for a wider range of "swaps" as the for-loop counter increases, which is the opposite behavior of the classic Fisher-Yates approach. I'm intrigued by the validity of this algorithm. Could it possibly be a disguised version of Fisher-Yates? Is there any bias involved?

If someone could provide code to test the distribution of permutations generated by this algorithm, that would be greatly appreciated.

<script>
var shuffle = function (myArray) {
    var random = 0;
    var temp = 0;
    console.log(myArray);
    for (i = 1; i < myArray.length; i++) {
        random = Math.round(Math.random() * i);
        console.log(random + '\n');
        temp = myArray[i];
        myArray[i] = myArray[random];
        myArray[random] = temp;
        console.log(myArray);
    }
    return myArray;
}

var arr = [1, 2, 3, 4];

shuffle(arr);

</script>

Answer №1

Incorrect, the shuffle is not fair.

Math.random() * i generates a random floating point number between 0 and i, however using Math.round(Math.random() * i) does not result in an equal distribution of integers between 0 and i. For instance, when i is 2, values in the range [0, 0.5) round to 0, values in the range [0.5, 1.5) round to 1, and values in the range (1.5, 2) round to 2. This means that instead of selecting 0, 1, and 2 with the same frequency, 1 is selected 50% of the time, while 0 and 2 are each selected 25% of the time.

The correct approach would be to use

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

To validate this statistically: perform 10000 shuffles on the array [0, 1, 2] and observe the frequency at which 2 appears at the end of the array. Ideally, it should be approximately 3333 times, but due to the bias, it may likely be closer to 2500.

Despite this issue, the algorithm remains sound and could be likened to a reverse Fisher-Yates shuffle. It can be proven through induction, where the base case for n=1 is trivial and the induction step involves inserting the (n+1)'th item into a uniformly random index from 0 to n+1 in a permutation of n items.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide on transforming a CSS selector into XPath through JavaScript

Could someone help me find a similar function to Nokogiri::CSS.xpath_for()? I came across css2xpath, but the output from Nokogiri actually functions correctly, whereas the selector provided by css2xpath does not. The desired result would look something l ...

What steps can I take to ensure this conversion meets markup validation requirements?

I keep encountering a validation error that keeps coming up: $("#preview").html('<div align="center"><img src="/ajaximage/loader.gif" alt="Uploading...."/></div>'); The error message states: document type does not allow elemen ...

What are the steps to effectively implement the useEffect hook in React?

I'm facing an issue where I am trying to return a function that utilizes useEffect from a custom usehook, but I keep getting the error "useEffect is called in a function which is neither a react function component nor a custom hook." Here's what ...

Caution: The update depth has reached its maximum limit. Demonstrating the BubbleSort algorithm using React

Recently, I have been attempting to visualize bubble sort using React. Although the sorting and animation functionalities are working smoothly, once the sorting is completed, React starts throwing errors. https://i.sstatic.net/a8tPC.png In my efforts to ...

Filtering array objects based on elements in another array

I am trying to filter out elements from one array based on matching ids in another array. My first array looks like: const toFilter = [1,4,5] And the second array has a structure similar to this: const foo = [{id: 1, time:XXX}, {id:2, time:XXX}, {id: 3, t ...

Is Protractor compatible with Angular Material dialog popups?

Encountering an issue targeting elements in a popup dialog using Protractor. Once the popup dialog appears, the following error is displayed: Failed: unknown error: Element is not clickable at point (1204, 32). Other element would receive the click... ...

Can you please tell me the name of the ??= operator in Typescript?

The Lit Element repository contains a function called range that utilizes the ??= operator. This operator resembles the nullish coalescing operator but with an equal sign. Do you know what this specific operator is called? Below is the complete code snipp ...

Using JavaScript to manage form input values in React

I am currently coding a basic application using NextJS and bulma CSS. The snippet below shows the form I am working on: const MyPage = () =>{ const [firstName, setFirstName] = useState('') const [secondName, setSecondName] = useState('&ap ...

Checking if the input is valid before invoking a JavaScript/jQuery function

I am working on a wizard using TypeScript and ASP.NET which consists of several steps. Here is an example: Step 1: TextBox input <---Name TextBox input <--- Age Button onClick="nextStep()" When I click on the button, I want to validate my input u ...

Issue with Mongoose query for finding data in multiple columns

If a keyword matches in category.title, then it will provide a result; otherwise, it does not match with any other fields. Can someone point out what the issue might be here? I also attempted NewsModel.find().or(filters) without the $or key, but it still i ...

Opt for remove or hide in jQuery instead of resorting to split and join for better efficiency

My goal is to eliminate all occurrences of the £ symbol on a webpage (.aspx page). Currently, I am using the following jQuery code: $(':contains("£")').each(function(){ $(this).html($(this).html().split("£").join("")); }); Although the ...

Beware: Inaccessible code detected in Reactjs usage

Currently, I am working on a ReactJS project where I have integrated two components - PrescriptionIndex and PrescriptionNew. Let's start with the 'PrescriptionNew' component: import React, { Component } from 'react'; import Flo ...

A guide to adding a picture to AWS S3 with the help of GraphQL

When trying to upload a base64 string via GraphQL, I encountered an issue. It seems that if the string exceeds 50,000 characters, GraphQL fails to reach the resolve function without giving any error messages. However, when the string is less than 50,000 ...

Automating web pages with the power of Node.js

I have developed an API in PHP that accepts a 10-digit number as a variable and provides data in JSON format. For instance, the URL structure is like this: www.exampletest.com/index.php?number=8000000000. The succeeding variable will be the current number ...

The impact of array splicing on data manipulation

I have a $scope array variable that I'm using to generate tabs on the front end, but I'm struggling with implementing a remove tab function. The code for removing tabs is as follows: function removeTab(index) { $scope.tabs.splice(index, 1); ...

The mysterious case of Jquery's undefined appendage

I'm having trouble with appending a JSON file. It's displaying multiple undefined values and I can't figure out what's causing it. This is my code: $("button").click(function() { $.getJSON("https://api.myjson.com/bins/503aj", fu ...

Navigate to a dedicated product detail page within a React application from the main product listing page

I am facing an issue with my product page. When a user clicks on a specific product card, it should redirect them to a new page displaying only that product's details. However, even after redirecting, the entire product list is still shown on the deta ...

Why do my checkboxes refuse to respond separately?

I am currently experiencing an issue with the checkboxes in my JavaScript game. They do not respond to individual clicks as expected. Each time I log the output, I receive index 0 regardless of which box I click on. The checkboxes seem unresponsive but the ...

Reasons why Chrome may experience difficulties running jQuery

My browser of choice is Google Chrome, but I'm facing an issue with a script that runs perfectly on other browsers except for Chrome. Can anyone provide me with any suggestions on how to make it work on Chrome? <!DOCTYPE html PUBLIC "-//W3C//DTD X ...

Ways to eliminate flickering when dynamically updating iframe content

Currently, I am in the process of constructing an iframe slideshow that consists of 7 webpages named event1.html to event7.html. To implement the automatic changing of the iframe source every 1 second, I am utilizing setInterval. However, I am facing an is ...