Reputation: 101
I'm trying to produce do some processing on a random permutation of the alphabet, however each permutation produces the same result despite using srand(myseed)
I have included the <algorithm>
header.
string create_permutation(unsigned seed)
{
srand(seed);
string permutation = ALPHABET;
random_shuffle(permutation.begin(), permutation.end());
return permutation;
}
cout << create_permutation(2) << endl; // or 3, 4, 5 etc
// continuously returns 'XQACKHSLOJ,TRBZNGV.W FIUEYDMP
Any help would be greatly appreciated.
EDIT: Minimal, Complete, and Verifiable example
EDIT 2: adjustment to mcve
#include <iostream>
#include <algorithm>
using namespace std;
const string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,' ";
string create_permutation(unsigned seed)
{
srand(seed);
string permutation = ALPHABET;
random_shuffle(permutation.begin(), permutation.end());
return permutation;
}
int main(){
cout << create_permutation(2) << endl; // or 3, 4, 5 etc
// continuously returns 'XQACKHSLOJ,TRBZNGV.W FIUEYDMP
return 0;
}
Upvotes: 1
Views: 4000
Reputation: 33932
srand
, you reset the seed and reset the starting point for the algorithm.
srand
. Unless you have a very good reason not to (and if you do, you probably shouldn't use rand
and srand at all. Look to the <random>
library) you should call srand
once at the beginning of the program to seed the generator once and ever after use that seed. srand
is also quite expensive. From a performance standpoint, you don't want to call it often. So: since every call to create_permutation
calls srand
with the seed
parameter and create_permutation
is always called with the same seed value, for a given implementation of the random number generator, create_permutation
will always use the same random number sequence and thus generate the same permutation.
A quick example that will generate different permutations, so long as the program is not run more often than once per second is
#include <iostream>
#include <string>
#include <algorithm>
#include <ctime>
const std::string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,' ";
std::string create_permutation()
{
std::string permutation = ALPHABET;
std::random_shuffle(permutation.begin(), permutation.end());
return permutation;
}
int main(){
srand(time(NULL)); // caveat: time's minimum resolution is 1 second.
// multiple executions of this program within 1
// second will get the same time and use the same seed.
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
return 0;
}
A more modern approach:
#include <random>
#include <algorithm>
#include <iostream>
#include<string>
const std::string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,' ";
std::random_device rd; // Warning: implementation of this is allowed to be stupid and
// return the same value every time. Does not work in mingw 4.8
// Can't speak for 4.9 or greater
std::mt19937 randomizer(rd());
std::string create_permutation()
{
std::string permutation = ALPHABET;
std::shuffle(permutation.begin(), permutation.end(), randomizer);
return permutation;
}
int main()
{
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
std::cout << create_permutation() << std::endl;
}
Upvotes: 0
Reputation: 4555
shuffle_random
is using the same seed for the random number generator each time it is called.srand
does not seed the random_shuffle
function, it seeds rand
and random_shuffle
usually calls rand
, but does not have to.
random_shuffle
has two forms:
One that takes 2 arguments (begin/end iterators)
One that takes 3 (begin/end iterator and a random generator).
You have demonstrated that you know how to use the first form, but the problem with the first form is that it is implemented differently on different platforms and with different compilers. It may not use rand()
at all, which is the function that srand
seeds.
You should use the 3 argument form and provide the random number generator as a parameter to the function.
You can follow this detailed answer to learn how to make your own random number generator, or you can provide rand()
to the random_shuffle
function as the random number generator.
Upvotes: 7