How to generate random integers 0 to 0x7FFFFFFF? - c++

This doesn't work:
for (int p = 0; p < 10; p++) {
random_device rd;
mt19937 gen(rd);
uniform_real_distribution<int> dis(0, INT_MAX);
printf("%i\n", dis(gen));
}
Any advice would be appreciated.

You have few mistakes in your code.
You should move creation of random_device and seeding mt19937 outside the for loop. I'll also suggest the same for uniform_real_distribution<int>
mt19937 takes in the constructor value of seed not random_device so you have to call it to get seed(rd())
You should use uniform_int_distribution<int> if you are generating integers
If your intention is to generate number to 0x7FFFFFFF you should put this number explicitly but if you want to get numbers to max int value i'll suggest using more C++ style std::numeric_limits<int>::max()
Here is working example:
#include <cstdio>
#include <random>
#include <limits>
using namespace std;
int main(){
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<int> dis(0, std::numeric_limits<int>::max());
for (int p = 0; p < 10; p++) {
printf("%i\n", dis(gen));
}
return 0;
}

Related

How to generate 4 different random numbers in C++

I am making Bulls and Cows assignment from Bjarne Stroustrup's "Programming Principles and Practice Using C++" book (p. 130, exercise 13) and I want program to generate four different integers in the range 0 to 9 (e.g., 1234 but not 1122)
I made a vector to store numbers and a function which generates 4 numbers and adds them to vector, but numbers might be the same and I can't return numbers to main function
#include "../..//..//std_lib_facilities.h"
vector<int> gen4Nums(vector<int> secNum)
{
random_device rd; // obtain a random number from hardware
mt19937 eng(rd()); // seed the generator
uniform_int_distribution<> distr(0, 9); // define the range
secNum.clear();
for (int i = 0; i < 4; i++)
{
secNum.push_back(distr(eng));
cout << secNum[i];
}
return secNum;
}
int main()
{
vector<int> secNum;
gen4Nums(secNum);
}
I expect to return 4 different random numbers to the main function
You can ensure to get different random numbers in the result if you change your code like this:
#include <vector>
#include <random>
#include <algorithm>
using namespace std;
vector<int> gen4Nums()
{
vector<int> result;
random_device rd; // obtain a random number from hardware
mt19937 eng(rd()); // seed the generator
uniform_int_distribution<> distr(0, 9); // define the range
int i = 0;
while(i < 4) { // loop until you have collected the sufficient number of results
int randVal = distr(eng);
if(std::find(std::begin(result),std::end(result),randVal) == std::end(result)) {
// ^^^^^^^^^^^^ The above part is essential, only add random numbers to the result
// which aren't yet contained.
result.push_back(randVal);
cout << result[i];
++i;
}
}
return result;
}
int main() {
vector<int> secNum = gen4Nums();
}
Seems like you're trying to generate 4 unique random integers in the range 0...9.
You can do this by generating a vector of integers containing the values 0...9. Then shuffle the vector, as you want it to be a random selection of the integers. Lastly trimming the vector to the desired size, as you only want 4 unique random integers:
#include <vector>
#include <random>
#include <algorithm>
#include <numeric>
void gen4Nums(std::vector<int>& v) {
//Generate initial vector with values 0...9:
v.resize(10, 0);
std::iota(v.begin(), v.end(), 0);
//Shuffle the vector:
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(v.begin(), v.end(), g);
//Trim the vector to contain only 4 integers:
v.resize(4);
}

Generate random number in range without repetition

I am using C++ to generate n uniform numbers in a given range without repeatition. I want to save it in array(not vector). I found a code but it does not allow to generate number without repetition.
std::random_device rd; // only used once to initialise (seed) engine
std::mt19937 rng(rd()); // random-number engine used (Mersenne-Twister in this case)
std::uniform_int_distribution<int> uni(0,10-1); // guaranteed unbiased
auto random_integer = uni(rng);
For example, I will generate 5 random numbers in range 0-9 such as
1 0 3 8 6
This is my code
typedef unsigned int U32, *PU32;
U32 total_num = 5;
U32 *rndArray = new U32[total_num];
for (U32 i = 0; i < total_num; i++)
{
std::random_device rd // only used once to initialise (seed) engine
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(0,10-1);
auto random_integer = uni(rng);
rndArray[i] = random_integer ;
}
Second way, I used the code bellow which allows without repetition. But it is not support in g++ (I am using g++ in ubuntu)
#include <random>
#include <algorithm>
#include <iterator>
#include <iostream>
typedef unsigned int U32;
int main()
{
U32 total_num = 5;
U32 *rndArray = new U32[total_num];
std::random_device rd;
std::mt19937 g(rd());
std::vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::shuffle(v.begin(), v.end(), g);
for (int i=0;i<5;i++)
{
rndArray[i]=v[i];
std::cout<< rndArray[i] << " ";
}
std::cout << "\n";
}
There's a couple ways you can do this.
If the random number is already in the array, then generate another one until you find a number that has not been seen before. This is quick to implement but has the disadvantage of very high running time theoretically.
Create the entire range to begin with in an array and then scramble it. To get k numbers, obtain the first k elements of the scrambled array.
Use the Fisher-Yates shuffle algorithm to shuffle a vector/array filled with all the numbers in the desired range: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
The easiest way to achieve what you want is to do what user Untitled123 suggested (see below). To compile: g++ -std=c++11 file.cpp
#include <vector>
#include <algorithm>
using namespace std;
int randomize(const int &i) return rand() % i;
int main() {
srand(unsigned(time(0)));
int n = 10;
vector<int> sample(n);
// generate numbers 0 .. n-1
iota(sample.begin(), sample.end(), 0);
// shuffle elements
random_shuffle(sample.begin(), sample.end(), randomize);
// grab the first five elements after shuffling
vector<int> chosen(sample.begin(), sample.begin() + 5);
// do stuff
return 0;
}

generating random numbers in c++

I need to generate a random number between 1 and n where n is unsigned int.
If n were int I would simply write 1 + rand()% n. But unfortunately n is unsigned int. What do you suggest?
rand() should be avoided whenever possible*.
Use http://en.cppreference.com/w/cpp/numeric/random
#include <random>
#include <iostream>
int main()
{
std::random_device rd;
std::mt19937 engine(rd());
std::uniform_int_distribution<unsigned> dist(1, 77);
for (int i = 0; i != 5; ++i)
std::cout << dist(engine) << '\n';
}
* Because it shares a global state, gets often implemented as a linear congruential engine which has a few drawbacks and it's range is often only 0-2^16. Also, % n where n is not an exact multiple of the range does not produce an uniform distribution.
Edit: This might seem like overkill, but technically one would want something like this, since mt19937 needs a bit of "warm up":
std::mt19937 create_seeded_rng()
{
std::random_device rd;
std::array<std::mt19937::result_type, std::mt19937::state_size> seed_data;
std::generate(seed_data.begin(), seed_data.end(), std::ref(rd));
std::seed_seq seq(seed_data.begin(), seed_data.end());
return std::mt19937(seq);
}
int main()
{
std::mt19937 rng = create_seeded_rng();
std::uniform_int_distribution<int> dist(0, 100);
for (unsigned i = 0; i != 100; ++i)
std::cout << dist(rng) << '\n';
}

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;
}
}

Progressively slow down loop?

I've been trying to figure out a way that I can cpp progressively slow down loop for a dice program I want to write. Getting a random number and displaying/comparing it is not difficult. My issue is trying to figure out how I could display random numbers as if the dice was rolling where it progressively gets slower and slower until I want to display the rand number that was generated.
I've thought about doing a for-loop inside another for-loop and using the first loops number to subtract from the second. I don't know if there is a better way or not. All seraching comes up with seraches on how a program is going slower because they weren't allocating memory.
for (int i = 5; i > 0; i--)
{
for (int j = 1000; j > 0; j -= i)
{
cout << randNumGen();
}
}
#include <thread>
#include <chrono>
:::
for (int i = 5; i > 0; i--)
{
for (int j = 1000; j > 0; j -= i)
{
cout << randNumGen();
std::this_thread::sleep_for(
std::chrono::milliseconds(j));
}
}
http://en.cppreference.com/w/cpp/thread/sleep_for
http://en.cppreference.com/w/cpp/chrono
it is probably also worth your while look at C++11 random it is more C++ way of generating random number in a cross platform way.
std::uniform_int_distribution<int> distribution(1, 6); //dice values
std::mt19937 engine; // Mersenne twister MT19937
int random = distribution(engine);
http://en.cppreference.com/w/cpp/numeric/random
#include <thread>
#include <chrono>
#include <random>
#include <iostream>
:::
std::random_device rd;
std::uniform_int_distribution<int> dist(1, 6); //dice values
std::mt19937 mt(rd()); // Mersenne twister MT19937
for (int i = 5; i > 0; i--) //i don't really get what your loops mean
{
for (int j = 1000; j > 0; j -= i)
{
cout << dist(mt);
std::this_thread::sleep_for(
std::chrono::milliseconds(j));
}
}
You will need to compile with c++11 support for gcc and clang this is -std=c++0x