I want to make a function that generates numbers but doesn't repeat it self. If every number is generated the array can be emptied and it can start over again.
This is the code I made but it doesn't work.
The comments in the code explains the code a little.
The largest number that is allowed is "howManyWords".
This is used to display words which are stored in an array
I want to use it like this: array\[random()\]
#include <stdio.h>
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
//public scope
int howManyWords; // how many words you have enter
int random(){
int random;
int numbers[howManyWords];
srand(time(0)); //changing the algorithm
random = rand() % howManyWords;
numbers[random] = random; // store the digit in the position in the array equal to the digit that is generated
for(int i=0; i<howManyWords; i++){ // going through every element in the array
if(numbers[i] == random){ // if the number is already generated, generate a different number
random = rand() % howManyWords;
}
}
return random;
}
Rather than your function, which discards the state of which numbers it has returned each time it is called, you should use a function object.
struct random_t {
random_t(int max) : values(max), current(max) {
std::iota(values.begin(), values.end(), 0);
}
template<typename URBG = std::random_device &>
int operator()(URBG&& urbg = default_random) {
if (current == values.size()) {
shuffle(std::forward<URBG>(urbg));
}
return values[current++];
}
private:
template<typename URBG>
void shuffle(URBG&& urbg) {
std::shuffle(values.begin(), values.end(), std::forward<URBG>(urbg));
current = 0;
}
std::vector<int> values;
std::vector<int>::size_type current;
static thread_local std::random_device default_random;
};
See it live
I am trying to make a mini lottery simulator. I want to generate 8 random numbers with a minimum of 1 and a maximum of 20. And i store these generated numbers in a Lottery object. I have a LotteryManager class, where i can decide how many times do i want to generate these lotteries. But i always get the same random numbers. I seeded the generator so I dont understand whats the problem with it. Any help is appreciated!
This is my lottery class:
class Lottery
{
private:
vector<int> lotteryA;
int lotteryB;
public:
Lottery();
vector<int> getLotteryA() const;
int getLotteryB() const;
void generateLotteryA();
void generateLotteryB();
void printLottery() const;
};
And this is the class that manages it:
class LotteryManager
{
private:
unsigned int quanity = 0;
map<unsigned int, Lottery> lotteries;
public:
LotteryManager();
LotteryManager(unsigned int q);
unsigned int getQuanity() const;
void setQuanity(unsigned int value);
void generateLotteries();
void printLotteries() const;
};
And this is my main code:
LotteryManager* lm = new LotteryManager(100);
lm->generateLotteries();
lm->printLotteries();
The generate and print functions in the LotteryManager class:
void LotteryManager::generateLotteries()
{
for(unsigned int i = 0; i < getQuanity(); ++i)
{
Lottery l;
l.generateLotteryA();
l.generateLotteryB();
lotteries.insert(make_pair(i, l));
l.printLottery();
}
}
void LotteryManager::printLotteries() const
{
cout << "Lotteries:" << endl;
for(auto current : lotteries)
{
cout << current.first << ".: ";
current.second.printLottery();
}
}
And the generate functions in the Lottery class:
(The generate A and B are just the different fields, because the game aims to imitate the game named Putto, where you need to guess 8 numbers from 20 in the field A and 1 from 4 in the field B)
void Lottery::generateLotteryA()
{
random_device rn_d;
mt19937 rng(rn_d());
uniform_int_distribution<int> dist(1, 20);
for(unsigned int i = 0; i < 8; ++i)
{
lotteryA.push_back(dist(rng));
}
}
void Lottery::generateLotteryB()
{
srand(time(0));
lotteryB = (rand() % 20) + 1;
}
Thanks in advance!
In Lottery::generateLotteryA you are declaring a random engine, and random device. Every time you call this function, the engine is seeded with the same random device, and so you could get the same results.
It might seem reasonable that invoking rn_d() each time with different random_devices will generate a different value. However, this is not required, and as mentioned in the reference:
... each std::random_device object may generate the same number sequence.
In practice, most implementations will generate different values, and so this is not really a problem. You could even consider it a defect in the standard library for not making this guarantee. However, as currently specified, you could see the same values being produced.
The simplest fix would be to make the engine static, so it only gets seeded the first time the function is called:
void Lottery::generateLotteryA()
{
// ...
static mt19937 rng(rn_d());
// ...
}
I am to draw 3 balls from an urn of 24 and add up the total discount the balls represent. I am not allowed to replace the balls after drawing, so there can be no duplicate balls drawn. The discounts are 1, 2, 3, 4, 5, 6, 7, 8, and there are 3 of each.
My solution to this problem was to create multiple while loops that roll out of 24 and re-roll until no duplicates are drawn. I have done a loop like this in the past that would loop random numbers until a non-duplicate was chosen and it worked fine, so I set this program up the same way.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int draw(int urn[], int draws[]);
int main()
{
int discountSum,discount;
int urn[24]={1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8};
int draws[1000]={0};
draw(urn,draws);
cin >> discount;
int averageDiscount=discount/1000;
return 0;
}
int draw(int urn[], int draws[])
{
static int discountSum=0;
int i; //simulations counter
int ball1, ball2, ball3;
int score1, score2, score3;
int totalDiscount;
srand(time(0));
for(i=0;i<1000;i++)
{
ball1=rand()%24;
while (ball2==ball1)
{
ball2=rand()%24;
}
while ((ball3==ball2)||(ball3==ball1))
{
ball3=rand()%24;
}
score1=urn[ball1];
score2=urn[ball2];
score3=urn[ball3];
totalDiscount=score1+score2+score3;
draws[i]=totalDiscount;
cout << "1) " << draws[i] << " percent discount.\n";
discountSum+=totalDiscount;
}
return discountSum;
}
When I run this code, instead of receiving an error, the program runs with no output, and a return of a negative garbage value instead of 0. I would like to see the output from each discount up to the 1000th loop.
It looks as if the bug is that ball2 and ball3 are compared before they're ever set to anything. They're never even initialized, which is the likely cause of your "garbage value." It'll probably work if you "draw" each ball before comparing it, as:
ball1=rand()%24;
ball2=rand()%24;
while (ball2==ball1)
{
ball2=rand()%24;
}
ball3=rand()%24;
while ((ball3==ball2)||(ball3==ball1))
{
ball3=rand()%24;
}
An even better way would be to use do...while loops instead, which always run once, as:
ball1=rand()%24;
do
{
ball2=rand()%24;
} while (ball2==ball1);
do
{
ball3=rand()%24;
} while ((ball3==ball2)||(ball3==ball1));
A much simpler way to do this is to use the facilities build into the C++ standard library:
#include <iostream>
#include <algorithm>
#include <random>
std::mt19937 gen(std::random_device{}()); // initialize random number generator
/*
* or
std::mt19937 gen(std::time(NULL));
* if std::random_device is not well-implemented
*/
int draw()
{
static int urn[24]={1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8};
std::shuffle(std::begin(urn), std::end(urn), gen); // shuffle array
return urn [0] + urn[1] + urn[2]; // pick first three balls from array
}
int main()
{
int discount = draw();
// Use discount. For example,
std::cout << discount;
return 0;
}
Documentation:
std::mt19937
std::random_device
std::shuffle
I need to make a simulator for a college homework. In this simulator there are 3 computers, 2 of which send messages to computer 1 which then decides to either send the message or reject it. The rejection is random chance with 20% of rejection on computer 2 and 50% on computer 3. I use the rand()%100+1 function with the srand(time(NULL)) seed. It makes a random number however I need to run this multiple times and every time the same random number is used. For example if I run the simulation 12 times and the number generated is 45, 45 is used 12 times. I've both placed the random number generator inside the code and made a function outside.
How can you make a random number generator that generates a random number every time?
#include <iostream>
#include <new>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;
int randomgen()
{
int rndnum=0;
srand (time(NULL));
rndnum=rand()%100+1;
cout<< rndnum<<endl;
return rndnum;
}
struct comp1
{
int rejected=0;
int received=0;
int sent=0;
int onhold=0;
bool comp2reception()
{
received++;
bool result=false;
int rndnum=0;
srand (time(NULL));
rndnum=rand()%100+1;
if(rndnum<=20)
{
rejected++;
result=false;
}
if(rndnum>=21)
{
onhold++;
result=true;
}
return result;
}
bool comp3reception()
{
received++;
bool result=false;
int rndnum=randomgen;
if(rndnum<=50)
{
rejected++;
result=false;
}
if(rndnum>=51)
{
onhold++;
result=true;
}
return result;
}
};
Use the C++11 header <random>.
#include <random>
static std::random_device rd;
static std::mt19937 gen(rd());
int randomgen()
{
std::uniform_int_distribution<> dis(0,100);
int rndnum = dis(gen);
std::cout << rndnum << std::endl;
return rndnum;
}
Call srand(time(NULL)) just once at the beginning of the program.
Since time() return number of seconds from 1970 and you program probably takes less than that to finish, you esentially reset the generator with same value before each call. Which of course returns same (first) value each call.
I want to create a class that will return a random number whenever I call it. But when I put it into a loop it returns the same random number each time. I am seeding it once but it still returns the same one over and over again. Its only when I close out of the program and open it again itll be different. Any help would be much appreciated.
**EDIT
When I cant see how I am calling it every time.
RadomGenerator rg = new...
for(int i =0; i<10; i++){
rg.createRandomNumber(1,5);}
Is this not instansiating the seed only once then calling the method createRandomNumber several times?
RandomGenerator::RandomGenerator()
{
seed = time(0);
}
int RandomGenerator::createRandomNumber(int start, int end)
{
std::function<int()> randomNumber = std::bind(std::uniform_int_distribution<int>(start,end),
mt19937(seed));
qDebug()<< "result" << randomNumber() ;
return randomNumber();
}
You're seeding it every single time.
#include <random>
struct RandomGenerator {
std::mt19937 _engine;
std::uniform_int_distribution<int> _dist;
RandomGenerator(int start, int end)
: _engine { std::random_device{} () },
_dist(start, end)
{
}
int createRandomNumber()
{
return _dist(_engine);
}
};
Note that it's actually not useful to create an instance of uniform_*_distribution for a single call either.
Let alone, wrapping that in a function<>.
You can usually use a
auto mygen = bind(, );
Instead of that whole class, and use it:
int this_is_random = mygen();
In C++14:
auto mygen = [ _engine = mt19937{ random_device{}() }, _dist = uniform_int_distribution<>(12, 42) ]() mutable {
return _dist(_engine);
};
See it Live On Coliru
Is this not instansiating the seed only once then calling the method createRandomNumber several times?
No. In this line you instantiate a mt19937 each time with the same seed:
std::function<int()> randomNumber = std::bind(std::uniform_int_distribution<int>(start,end),
mt19937(seed));