fisher-yates
Example:
例:
Say the input array is
[1, 2 3, 4, 5 6, 7]
After reshuffling it can be anything like
[4, 3, 7, 2, 1, 5, 1]
Our goal is that the reshuffling should be as random as possible.
我们的目标是,改组应尽可能地随机。
There is a standard algorithm named Fisher-Yates algorithm which shuffles the array in linear times.
有一个名为Fisher-Yates算法的标准算法,可以在线性时间内对数组进行随机排序。
The idea is to start from an end
这个想法是从头开始
Say we are string from the right end and the array size is n
假设我们是从右端开始的字符串,数组大小为n
Now, pick the end element which will be the nth element, and pick up another element randomly from the range [0, n-1]. Then swap the elements and shrink the right end. Thus after this step, a[n-1](the rightmost element) is fixed. Continue the same until we reach the left end.
现在,选择将成为第n个元素的end元素,并从[0,n-1]范围内随机选择另一个元素。 然后交换元素并缩小右端。 因此,在此步骤之后, a [n-1] (最右边的元素)被固定。 继续同样操作,直到到达左端。
The detailed algorithm will be,
详细的算法将是
For i=n-1 to 1
Pick and element in the range [0,i-1] randomly
Swap the randomly picked element with a[i]
Decrement i
End for loop
Since, it's random we can't do dry run
因为这是随机的,所以我们不能空运行
But still to illustrate lets pick elements randomly as per thought
但仍需说明让我们根据想法随机选择元素
So initially,
Array is
[1, 2 3, 4, 5 6, 7]
So i=6
Say, we picked up 4th (0-indexed) element randomly (in the range [0-5])
Swap them
So array is now
[1, 2, 3, 4, 7, 6, 5]
So 5 is now fixed and is guaranteed to stay
there after the whole shuffling completes
On the next iteration
i will be 5 and we will continue similar way until I becomes 1
C++ implementation:
C ++实现:
#include <bits/stdc++.h>
using namespace std;
//reference to array is passed as we need
//to update the array within the function
void reshuffle(vector<int>& arr, int n)
{
srand(time(0));
for (int i = n - 1; i >= 1; i--) {
//j will be a random no with in range 0 to i-1
int j = rand() % i;
//swap ith index with jth
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int main()
{
cout << "input array size\n";
int n;
cin >> n;
cout << "Input array elements \n";
vector<int> arr(n);
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
reshuffle(arr, n);
cout << "After reshuffling, printing the array\n";
for (auto it : arr)
cout << it << " ";
cout << endl;
return 0;
}
Output:
输出:
input array size
6
Input array elements
12 34 32 56 48 11
After reshuffling, printing the array
56 48 12 11 32 34
Real-life applications:
实际应用:
Creating an application which will suggest movie/songs from a list randomly. But each time it would suggest a unique movie only.
创建一个可以从列表中随机建议电影/歌曲的应用程序。 但是每次都会只推荐一部独特的电影。
In this case, what we will do is we will show the ith indexed movie after each iteration. As the ith indexed one is never going to come again in the reshuffling as that's being fixed every time. That means we will recommend ith song/movie after the swap is done at each stage.
在这种情况下,我们要做的是在每次迭代后显示第i 个索引的电影。 由于第i 个被索引的索引永远不会在改组中再次出现,因为每次都固定。 这意味着在每个阶段完成交换后,我们将推荐第i首歌曲/电影。
Go through the below link to understand the detailed problem and solution.
浏览以下链接以了解详细的问题和解决方案。
fisher-yates