How can I set range to the random library - c++

I really don't like the rand() function.I wanted to use the library but I don't really know how to set up a range for example from 1 to 3. I want to "random" these numbers(1,2,3) and not huge numbers like 243245.This code is how you can use the random library and print random numbers
#include <iostream>
#include <string>
#include <random>
using namespace std;
int main()
{
minstd_rand simple_rand;
simple_rand.seed(NULL);
for (int ii = 0; ii < 10; ++ii)
{
std::cout << simple_rand() << '\n';
}
}

Use std::uniform_int_distribution:
#include <ctime>
#include <iostream>
#include <random>
int main()
{
std::mt19937 rng(std::time(0)); // `std::minstd_rand` would also work.
std::uniform_int_distribution d(1,3);
for (int i = 0; i < 10; i++)
{
std::cout << d(rng) << '\n';
}
}

#include <iostream>
#include <random>
int main()
{
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> dis(1, 3);
for (int n=0; n<10; ++n)
//Use dis to transform the random unsigned int generated by gen into an int in [1, 6]
std::cout << dis(gen) << ' ';
std::cout << '\n';
}
Thanks to #holyBlackCat Credit to: cppreference.com

Related

srand() is not working when used with non-constant parameter

I've got a problem with srand(). It only works when I use a number as a parameter, for example srand(1234), but when I try to use it with 'n' or with time (as below), then randint() keeps returning the same value.
#include <iostream>
#include <experimental/random>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
srand(time(nullptr));
for (int i = 0; i < 4; ++i) {
int random = experimental::randint(0, 9);
cout << random;
}
}
Thanks for your time.
The C function srand is meant to be used in combination with the C function rand. These are separate functions from those in C++'s std::experimental header. The randint function from the latter is meant to be used with the reseed function from the same header:
#include <experimental/random>
#include <iostream>
int main() {
std::experimental::reseed();
for (int i = 4; i--; ) {
int random = std::experimental::randint(0, 9);
std::cout << random << '\n';
}
}
However, there is no need to use experimental features here. Since C++11, there is std::uniform_int_distribution:
#include <iostream>
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> distrib(0, 9); // Default type is 'int'
for (int i = 4; i--; ) {
int random = distrib(gen);
std::cout << random << '\n';
}
}
This method is more flexible than the one from the C standard library and should, generally, be preferred in C++.

Random number generator producing identical results

I am having trouble using the random header to create a simple random number generator.
#include <iostream>
#include <random>
using namespace std;
int main()
{
random_device rd; //seed generator
mt19937_64 generator{rd()}; //generator initialized with seed from rd
uniform_int_distribution<> dist{1, 6};
for(int i = 0; i < 15; i++)
{
int random = dist(generator);
cout << random << endl;
}
}
This code produces identical results every time I run the program. What am I doing wrong? Also is there a way to modify this code such that it will generate a floating point number between 0 and 1? I don't think the uniform_int_distribution will let me and I can't figure out which distribution to use.
EDIT: Posted a possible solution to my problem below
Here is what I came up with eventually:
#include <iostream>
#include <ctime>
#include <random>
using namespace std;
int main()
{
srand(time(0));
default_random_engine rd(rand());
mt19937_64 generator{rd()}; //generator initialized with seed from rd
uniform_real_distribution<double> dist{0,1};
for(int i = 0; i < 15; i++)
{
double random = dist(generator);
cout << fixed << random << endl;
}
}
It turns out that you actually CAN combine srand(time(0)) with an engine from the random header file, and their powers combined seem to produce random-feeling numbers better than I have managed with either alone. Please feel free to point out any problems with this arrangement.

Random number generator generating the same number even after seeding

Here's my code:
#include <iostream>
#include <string>
#include <random>
#include <ctime>
using namespace std;
int RandomIntGen(int lowerLimit, int upperLimit);
int main()
{
for (int i = 0; i < 10; i++) {
cout << "I am rolling a " << RandomIntGen(1, 6) << endl;
}
system("PAUSE");
}
// A random integer generator that takes in a upper and lower integer limit and returns a random integer
int RandomIntGen(int lowerLimit, int upperLimit) {
default_random_engine randomGenerator(time(0)); //seeding with time
uniform_int_distribution<int> randomInteger(lowerLimit, upperLimit);
return randomInteger(randomGenerator);
}
Don't know why it's generating the same value even with seeding. How do I fix this?
Moved "default_random_engine randomGenerator(time(0));" to global space to make sure it is seeded only once.
#include <iostream>
#include <string>
#include <random>
#include <ctime>
using namespace std;
//Random Generator with Seed
default_random_engine randomGenerator(time(0));
// Function Declarations
int RandomIntGen(int lowerLimit, int upperLimit);
int main()
{
for (int i = 0; i < 10; i++) {
cout << "I am rolling a " << RandomIntGen(1, 6) << endl;
}
system("PAUSE");
}
// A random integer generator that takes in a upper and lower integer limit and returns a random integer
int RandomIntGen(int lowerLimit, int upperLimit) {
uniform_int_distribution<int> randomInteger(lowerLimit, upperLimit);
return randomInteger(randomGenerator);
}

random function in C++

Is there a function that generates k random numbers within a specified range.
For example I want 5 random numbers between 0 to 100, with or without replacement.
You could use std::generate_n with either rand() or a generator from the new C++11 random number generators.
There is the Boost library, which you can use to generate random numbers, for example.
The following code generates 5 random numbers from [0, 100] with replacement:
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
const int numWantedNumbers = 5;
int main()
{
boost::random::mt19937 generator;
boost::random::uniform_int_distribution<> distribution(0, 100);
std::vector<int> result;
for (int i = 0; i < numWantedNumbers; ++i)
result.push_back(distribution(generator));
}
If you want to generate the numbers without replacement, simply check if they are
still available:
#include <algorithm>
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
const int numWantedNumbers = 5;
int main()
{
boost::random::mt19937 generator;
boost::random::uniform_int_distribution<> distribution(0, 100);
std::vector<int> result;
while (result.size() < numWantedNumbers)
{
int number = distribution(generator);
if (std::find(result.begin(), result.end(), number) == result.end())
result.push_back(number);
}
}
Note: The rejection sampling in the example without replacement has the obvious drawback that longer vectors are quite difficult to create. Just try to draw 99 out
of 100 numbers, to see what I mean (or even better draw 9999 out of 10000). If this
is a problem, I would suggest to create a random permutation of all possible numbers
and then cut the vector at the requested size:
#include <algorithm>
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
const int numWantedNumbers = 5;
int main()
{
boost::random::mt19937 generator;
boost::random::uniform_int_distribution<> distribution(0, 100);
// Generate a vector with all possible numbers and shuffle it.
std::vector<int> result;
for (int i = 0; i <= 100; ++i)
result.push_back(i);
for (int i = 0; i <= 100; ++i)
{
int x = distribution(generator);
std::swap(result[i], result[x]);
}
// Truncate to the requested size.
result.resize(numWantedNumbers);
}
Edit based on suggestion by juanchopanza:
In C++11 manner, the last variant would look like this
#include <algorithm>
#include <random>
#include <vector>
const int numWantedNumbers = 5;
int main()
{
std::random_device device;
std::mt19937 generator(device());
std::uniform_int_distribution<> distribution(0, 100);
// Generate a vector with all possible numbers and shuffle it.
std::vector<int> result;
for (int i = 0; i <= 100; ++i)
result.push_back(i);
std::random_shuffle(result.begin(), result.end());
// Truncate to the requested size.
result.resize(numWantedNumbers);
}
g++-4.6 compiles it happily, if you add the -std=c++0x switch.
Edit: Make use of std::random_shuffle() (tanks to James Kanze).
Yes there is a rand() function in C++ which can be used including cstdlib header file in your program.
You can implement your program using the following code.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
int max {100};
int min {0};
int number;
int count = 5; //assuming that only 10 numbers we need to print
srand(time(0));
for(int i=1;i<=count;i++)
{
number = rand() % (max - min +1) + min;``
cout<<number<<endl;
}
}

Getting integer random values instead of real values using boost::random library

I am trying to get real random values using boost::random libraries. This is my code:
#include <iostream>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/mersenne_twister.hpp>
boost::random::mt19937 eng = boost::random::mt19937();
boost::random::uniform_real_distribution<double> urd =
boost::random::uniform_real_distribution<double>(0,20);
for (int i = 0; i <= 100; i++)
std::cout << urd(eng) << std::endl;
But I get integer numbers between 0 and 20.
How can I do?
I also tried another engine:
#include <iostream>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/lagged_fibonacci.hpp>
boost::random::lagged_fibonacci607 eng = boost::random::lagged_fibonacci607();
boost::random::uniform_real_distribution<double> urd =
boost::random::uniform_real_distribution<double>(0,20);
for (int i = 0; i <= 100; i++)
std::cout << urd(eng) << std::endl;
But nothing... (always integer values)
How about setting the precision before you output? std::cout.precision(15);?
Or use:
std::cout.precision(std::numeric_limits<double>::digits10);
Example
#include <iostream>
#include <limits>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/mersenne_twister.hpp>
int main()
{
boost::random::mt19937 eng = boost::random::mt19937();
boost::random::uniform_real_distribution<double> urd =
boost::random::uniform_real_distribution<double>(0,20);
std::cout.precision(std::numeric_limits<double>::digits10);
for (int i = 0; i <= 100; i++)
{
std::cout << urd(eng) << std::endl;
}
}
The default precision for std::cout is set at 6, so it should work without setting this, but...