JavaScript random shuffle algorithm for in-depth analysis of _javascript skills

Source: Internet
Author: User
Tags random shuffle shuffle

Shuffle algorithm is our common random problem, in playing games, random sorting often encounter. It can be abstracted like this: get an array of random sequences of all the natural numbers within a m.

In Baidu search "Shuffle Algorithm", the first result is "Baidu Library-Shuffle algorithm", swept the contents of the inside, a lot of content is easy to mislead others astray, including the end of the list to replace the array, but also a limited optimization (linked list also introduced the loss of reading efficiency).

The first method in this article can be simply described as: randomly draw a card, put it in another group, draw again, draw the empty card and repeat.
"Smoke the empty card is repeated pumping" This will lead to a more and more empty cards, obviously unreasonable.
Can optimize one step into: After the card is drawn away, the original card becomes less. (instead of leaving blank cards)
The code is as follows:

Copy Code code as follows:

function Shuffle_pick_1 (m)//shuffle//Draw card method
{
Generate M card
var arr = new Array (m);
for (var i=0; i<m; i++) {
Arr[i] = i;
}

Draw one card at a time and put it in another pile. Because it takes time to pull all the elements in the array and push them forward one after another.
var arr2 = new Array ();
for (var i=m; i>0; i--) {
var rnd = Math.floor (Math.random () *i);
Arr2.push (Arr[rnd]);
Arr.splice (rnd,1);
}
return arr2;
}

This is also obviously problematic, because if the array is very large, deleting an element in the middle can cause the queue to go forward one step at a time, which is a time-consuming action.
Think back to "why do we want to delete that element?" "The aim is to not produce empty cards.
In addition to removing that element, do we have any other way to remove the empty card?
----Yes, we put the last card that we haven't drawn in that position.
So, this idea we can optimize into this:

Copy Code code as follows:

function Shuffle_pick (m)//shuffle//Draw card optimization card
{
Generate M card
var arr = new Array (m);
for (var i=0; i<m; i++) {
Arr[i] = i;
}

Draw one card at a time and put it in another pile. Put the last card you haven't drawn on the empty seat.
var arr2 = new Array ();
for (var i=m; i>0;) {
var rnd = Math.floor (Math.random () *i);
Arr2.push (Arr[rnd]);
ARR[RND] = arr[--i];
}
return arr2;
}


In addition to drawing a card train of thought, we can also use the idea of exchanging cards.
"Baidu Library-Shuffle algorithm" refers to a new way of thinking: "Random exchange two locations, a total of exchange n times, n larger, the closer to random."
This is wrong, even if the n is very large (for example, 10 cards, 10 swaps), there is also a great possibility of "some cards do not change position."
Along this line of thought, do a little adjustment on it: the first I and any card to change seats, after a round can be changed.
The code is as follows:

Copy Code code as follows:

function Shuffle_swap (m)//Shuffle//Change the card method
{
Generate M card
var arr = new Array (m);
for (var i=0; i<m; i++) {
Arr[i] = i;
}

The first one and any card to change seats, after a round can be
for (var i=0; i<m; i++) {
var rnd = Math.floor (Math.random () * (i+1)),
temp = Arr[rnd];
ARR[RND] = Arr[i];
Arr[i]=temp;
}
return arr;
}

In addition to the idea of drawing cards and exchanging cards, we can also use the idea of inserting cards: There is a card, the second card has two positions can be randomly inserted (before the first card, or after), the third card has three positions can be randomly inserted (put in the back, or inserted in the first place, or inserted in the second position), and so on
The code is as follows:

Copy Code code as follows:

function shuffle_insert_1 (m)//Shuffle//card method
{
Each time one of the biggest cards is generated, it is inserted in front of a random card. Because you want to insert elements into an array, it's time consuming to squeeze all the elements back in one place.
var arr = [0];
for (var i=1; i<m; i++) {
Arr.splice (Math.floor (Math.random () * (i+1)), 0,i);
}
return arr;
}

The above code will also have some problems: that is, as the number of cards increases, the card becomes more and more difficult, because the card will cause a lot of cards behind the next step.
Of course, we can also optimize the appropriate: first n-1 card, the nth card at the end, and then with any card swap position.
The code is as follows:

Copy Code code as follows:

function Shuffle_insert (m)//shuffle//card optimization version, you can use mathematical induction to prove that the shuffle is uniform.
{
Make one of the biggest cards at a time and change seats with a random card
var arr = new Array (m);
Arr[0] = 0;
for (var i=1; i<m; i++) {
var rnd = Math.floor (Math.random () * (i+1));
Arr[i] = Arr[rnd];
ARR[RND] = i;
}
return arr;
}

OK, all the code is as follows, interested students can try on their own machine, see their respective implementation efficiency, and the final results are theoretical random.

Copy Code code as follows:

<meta http-equiv= "Content-type" content= "text/html; charset=gb2312 ">
<title>jk:javascript Shuffle Algorithm </title>

<body>
<script type= "Text/javascript" >

function Shuffle_pick_1 (m)//shuffle//Draw card method
{
Generate M card
var arr = new Array (m);
for (var i=0; i<m; i++) {
Arr[i] = i;
}

Draw one card at a time and put it in another pile. Because it takes time to pull all the elements in the array and push them forward one after another.
var arr2 = new Array ();
for (var i=m; i>0; i--) {
var rnd = Math.floor (Math.random () *i);
Arr2.push (Arr[rnd]);
Arr.splice (rnd,1);
}
return arr2;
}


function Shuffle_pick (m)//shuffle//Draw card optimization card
{
Generate M card
var arr = new Array (m);
for (var i=0; i<m; i++) {
Arr[i] = i;
}

Draw one card at a time and put it in another pile. Put the last card you haven't drawn on the empty seat.
var arr2 = new Array ();
for (var i=m; i>0;) {
var rnd = Math.floor (Math.random () *i);
Arr2.push (Arr[rnd]);
ARR[RND] = arr[--i];
}
return arr2;
}


function Shuffle_swap (m)//Shuffle//Change the card method
{
Generate M card
var arr = new Array (m);
for (var i=0; i<m; i++) {
Arr[i] = i;
}

The first one and any card to change seats, after a round can be
for (var i=0; i<m; i++) {
var rnd = Math.floor (Math.random () * (i+1)),
temp = Arr[rnd];
ARR[RND] = Arr[i];
Arr[i]=temp;
}
return arr;
}

function shuffle_insert_1 (m)//Shuffle//card method
{
Each time one of the biggest cards is generated, it is inserted in front of a random card. Because you want to insert elements into an array, it's time consuming to squeeze all the elements back in one place.
var arr = [0];
for (var i=1; i<m; i++) {
Arr.splice (Math.floor (Math.random () * (i+1)), 0,i);
}
return arr;
}

function Shuffle_insert (m)//shuffle//card optimization version, you can use mathematical induction to prove that the shuffle is uniform.
{
Make one of the biggest cards at a time and change seats with a random card
var arr = new Array (m);
Arr[0] = 0;
for (var i=1; i<m; i++) {
var rnd = Math.floor (Math.random () * (i+1));
Arr[i] = Arr[rnd];
ARR[RND] = i;
}
return arr;
}


Alert (Shuffle_pick (10))


var funcs = [Shuffle_pick_1, Shuffle_pick, Shuffle_swap, Shuffle_insert_1, Shuffle_insert],
Funcnames = ["Draw the card", "Draw the card optimization", "Change the card", "card", "card optimization"]
m = 10000,
Times=[];
for (var i = 0; i < funcs.length; i++) {
var d0= new Date ();
Funcs[i] (m);
Funcnames[i] = (new Date ()-d0) + ' \ t ' + funcnames[i];
}

Alert (funcnames.join (' \ n '));

</script>


</body>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.