Large unique random number generator

Mar 7, 2016 at 2:58pm
Hi all, I want to generate any random integer from 1 million to 30 million, so here is the code I've written.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
int digit[7];
long int id=0;
int main()
{
    srand(time(NULL));
    for (int n=1; n<100000; n++)
    {
        digit[6]=rand()%29+1; //1,XXX,XXX to 30,XXX,XXX
        for (int i=5; i>=0; i--) {digit[i]=rand()%10+1;} //Other digits
        id=digit[6]*pow(10,6)+digit[5]*pow(10,5)+digit[4]*pow(10,4)+digit[3]*pow(10,3)+digit[2]*pow(10,2)+digit[1]*10+digit[0]; //Summation
        cout << id << "\n";
    }
    return 0;
}


It works seemingly good. However if I want all the numbers to be unique, do I have to store all results in a list (array), then check if any new integer generated is the same as any on the list, and discard it if it is? I need to generate a large quantity of numbers, say tens of thousands. Is there any better way?
Last edited on Mar 7, 2016 at 3:02pm
Mar 7, 2016 at 3:41pm
You create multiple numbers in ranges [1..30] and [1..10] in order to create one number in range [1'000'000..30'000'000].
(Except that you don't allow any 0 within the XXX'XXX. Furthermore, the first numbers could be 30 and 10, which makes 31 million and change.)

You could create the one number with a RNG single call. Preferably with <random> http://www.cplusplus.com/reference/random/uniform_int_distribution/

However, you do have an additional requirement: unique values.
Think of a new deck of cards. Every card is unique, but they are neatly ordered.
What do the dealers do first? They shuffle the deck.
The cards are still unique, but in random order.

The standard library has:
http://www.cplusplus.com/reference/vector/vector/
http://www.cplusplus.com/reference/numeric/iota/
http://www.cplusplus.com/reference/algorithm/shuffle/
Last edited on Mar 7, 2016 at 3:45pm
Mar 7, 2016 at 3:55pm
Hm. Not sure why you use arrays for the job :/ when a simple function and variables will do. I see you are using long type, and thats a good thing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <cstdlib>
#include <ctime>

using namespace std;

int main ()
{
srand (time (0));
//or you can use srand (time (NULL));

long int randNum , randMax , randMin;

randNum =
rand () % (randMax - randMin) + randMin;

return 0;
}


To generate random number between 30mil and 1mil, just initialize as follows:
1
2
3
long int randNum;
long int randMax = 30000000;
long int randMin = 1000000;

and then just do the other operation, initializing randNum as instructed.
Hope I helped!
Mar 7, 2016 at 4:00pm
To ensure uniqueness, put the numbers in a std::set. Then to generate a unique number, just loop until you get a number that isn't already in the set.
Mar 7, 2016 at 4:02pm
For unique numbers I would use a std::set. http://www.cplusplus.com/reference/set/set/
Mar 7, 2016 at 4:18pm
I'd just keep inserting to the set until the size() reached the required quantity.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <unordered_set>

using namespace std;

long generate1()
{
    static const int p6 = 1e6;
    static const int p5 = 1e5;
    static const int p4 = 1e4;
    static const int p3 = 1e3;
    static const int p2 = 1e2;
    static const int p1 = 1e1;
//  static const int p0 = 1e0;

    static int digit[7];
    
    digit[6] = rand() % 30 + 1;
        
    for (int i=5; i>=0; i--) 
        digit[i] = rand() % 10 + 1;
       
    return digit[6] * p6 
         + digit[5] * p5
         + digit[4] * p4 
         + digit[3] * p3 
         + digit[2] * p2 
         + digit[1] * p1 
         + digit[0];    
}

int main()
{    
    srand(time(NULL));
       
//    const int size = 100000;
    const int size = 10;

    std::unordered_set<long> randoms;    
    
    while (randoms.size() < size)
        randoms.insert(generate1());
     
    for (auto & num : randoms)
        cout << num << '\n';
}

Mar 7, 2016 at 4:29pm
I want to generate any random integer from 1 million to 30 million

Your algorithm can generate numbers in excess of 30 million. When adding, there can be a carry from the previous column.

In a quick test I got values up to 31,110,480.
Topic archived. No new replies allowed.