Hi
Would any one tell me how can I generate a random permutation of N numbers in c++?
Is there any algorithm in STL for this purpose?
Thanks in advance
Hi
Would any one tell me how can I generate a random permutation of N numbers in c++?
Is there any algorithm in STL for this purpose?
Thanks in advance
Short answer: don't enumerate all permutations. Produce each permutation uniformly at random (Fisher–Yates / std::shuffle) and, if you must avoid repeats, detect duplicates by storing a compact, unique representation (a Lehmer / factorial-number rank) rather than saving every permutation. That keeps memory small and avoids the M! explosion warned about; it also fixes the bias problems in ad-hoc approaches like “stop next_permutation at a random point” (which does not give uniform samples).
Here is a compact pattern you can apply immediately (assumes permutations of 1..n). It generates random permutations with std::shuffle, computes a unique 64-bit Lehmer rank for each sample, and keeps only distinct ones until you have N samples.
#include <algorithm>
#include <numeric>
#include <random>
#include <vector>
#include <unordered_set>
using u64 = unsigned long long;
// compute factorials up to n
std::vector<u64> facts(int n){
std::vector<u64> f(n+1,1);
for(int i=2;i<=n;i++) f[i]=f[i-1]*i;
return f;
}
// Lehmer rank (perm values are 1..n)
u64 lehmer_rank(const std::vector<int>& p, const std::vector<u64>& f){
int n = p.size();
std::vector<char> used(n+1,0);
u64 rank = 0;
for(int i=0;i<n;i++){
int smaller = 0;
for(int v=1; v<p[i]; ++v) if(!used[v]) ++smaller;
rank += (u64)smaller * f[n-1-i];
used[p[i]] = 1;
}
return rank;
}
// sample N distinct permutations
std::vector<std::vector<int>> sample_unique(int n, int N){
auto f = facts(n);
std::mt19937 rng(std::random_device{}());
std::unordered_set<u64> seen;
std::vector<std::vector<int>> out;
while((int)out.size() < N){
std::vector<int> p(n);
std::iota(p.begin(), p.end(), 1);
std::shuffle(p.begin(), p.end(), rng);
if(seen.insert(lehmer_rank(p,f)).second) out.push_back(std::move(p));
}
return out;
} Notes and cautions:
std::shuffle/std::mt19937 or std::uniform_int_distribution instead of rand()/% to avoid bias.Jump to Post— mrnutty 761What sort of premutation? On what set?
i found this: http://www.codeguru.com/cpp/cpp/algorithms/article.php/c5123/
That was a great help, but what I am looking for is to output N permutations out of total M permutations Randomly. (N < M)
What sort of premutation? On what set?
What sort of premutation? On what set?
int array[] ={1,2,3,4};
The output of next_permutation() on the above array result in
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
.....
.....
2 4 3 1
...
...
What I like to be output is permutation of those numbers, but in different orders each time the function is called.
E.X
2 4 3 1
1 4 3 2
2 1 3 4
1 2 4 3
3 4 2 1
4 2 1 3
...
...
1 2 3 4
You can store all permutations in 2D vector. Then You need to create another vector with M! elements (indexes). Random_shuffle vector with indexes and you have order in which You should read data from 2D vector (with all permutations).
But since (N < M) this algorithm is little overkill, because no matter how big N would be, you always have to generate all permutations.
I have reached to the following idea which works quite well for me. Although it won't generate all the permutations in the given range.
int array[] = {1,2,3,4,5};
srand (time(0));
do{
}while(next_permutation(array, array +(rand()%5)));
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.