I am a beginner in C++ and I am trying to explore C++11 features. Here I am trying to get familiar with the new randomness generating engines.
I summarized the following code from a tutorial on this subject and I noticed two things:
1- The uniform_real_distribution doe not include the max value.
2- The commented line produce an error although it seems to work fine on the tutorial.
#include <iostream>
#include <random>
#include <chrono>
#include <string>
using namespace std;
int main(){
unsigned seed = 201;
//seed = chrono::steady_clock()::now().time_since_epoch().count();
default_random_engine e(seed);
uniform_real_distribution<double> u(0,9);
vector<double> v(10);
int num;
for(int i = 0; i < 400; ++i){
num = u(e);
++v[num];
}
for (int i = 0; i < 10; ++i)
cout << i << ": " << string(v[i],'*') << "\n";
}
I tried to find the reasons of these two things with no luck.
So, my questions:
1- How to include the max value?
2- Why I am getting the error when uncomment the chrono line ?
cannot convert 'std::chrono::_V2::steady_clock' to 'unsigned int' in initialization
Note: I am using MinGW64 g++ with c++14.
As already said by Chris Drew, you can use nextafter as the second parameter of uniform_real_distribution.
Note that you first instantiate a new object chrono::steady_clock (with chrono::steady_clock() ) and then try to call the static member now() from this object.
As now() is a static member function of chrono::steady_clock, you can (and should) directly call chrono::steady_clock::now().
Final code:
#include <iostream>
#include <random>
#include <chrono>
#include <string>
using namespace std;
int main(){
unsigned seed = 201;
seed = chrono::steady_clock::now().time_since_epoch().count();
default_random_engine e(seed);
uniform_real_distribution<double> u(0,std::nextafter(9, std::numeric_limits<double>::max()));
vector<double> v(10);
int num;
for(int i = 0; i < 400; ++i){
num = u(e);
++v[num];
}
for (int i = 0; i < 10; ++i)
cout << i << ": " << string(v[i],'*') << "\n";
}
Related
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++.
Trying to create a random number generator using Arrays, but the " a[i] = rand();" portion of my code creates an error of the type "Identifier i is Undefined". Can anyone find where I am going wrong here? Thanks
#include <iostream>
#include <string>
#include <array>
using namespace std;
int main()
{
int a[10] = {};
for (int i = 0; i < size(a); i++); {
a[i] = rand();
}
for (int i = 0; i < size(a); i++) {
cout << "The random number is: " << a[i] << endl;
}
}
$ clang++-7 -pthread -std=c++17 -o main main.cpp
main.cpp:15:11: error: use of undeclared identifier 'i'
a[i] = rand();
^
main.cpp:13:38: warning: for loop has empty body
[-Wempty-body]
for (int i = 0; i < size(a); i++); {
^
main.cpp:13:38: note: put the semicolon on a separate line
to silence this warning
1 warning and 1 error generated.
compiler exit status 1
clang helpfully notes that you have an unexpected semicolon after your for loop.
The error in your code was a stray semicolon. Try learning debuggers like gdb, will help for such problems. rand() function uses a seed, srand() is used to change/set the seed.
#include <iostream>
#include <string>
#include <array>
#include <ctime>. // Added for random seed generation
using namespace std;
int main()
{
int a[10] = {};
srand(time(0)); /* Added this to ensure seed of rand() is always different otherwise you might have ended up with same random numbers on different runs */
for (int i = 0; i < size(a); i++) { /*Issue was here, you had stray semicolon */
a[i] = rand();
}
for (int i = 0; i < size(a); i++) {
cout << "The random number is: " << a[i] << endl;
}
}
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
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.
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...