# Thread: How to generate random number without repetition?

1. ## How to generate random number without repetition?

Hello, everyone! i am trying to generate random numbers in 2d array as my code below, but i but I still have problems: At the output, i got the repetition of the index (i) .

Example:

arr[11][0] = 0.563585
arr[18][0] = 0.808741
arr[29][0] = 0.479873
arr[18][0] = 0.895962
arr[22][1] = 0.746605
arr[5][1] = 0.858943
arr[1][1] = 0.513535
arr[1][1] = 0.014985
.............................
.............................
arr[12][29] = 0.634724
arr[19][29] = 0.828791
arr[5][29] = 0.720908
arr[5][29] = 0.375134

Code:
```
#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

int main(void)

{

double arr[30][30];

int m[30];

int i,j;

i=0;

for(j=0; j<30; j++){

m[j]= 0;

while(m[j] <4){

i= (int) rand()%30;

arr[i][j]= (double) rand()/RAND_MAX;

if(arr[i][j] > 0){

m[j]++;

printf("arr[%d][%d] = %lf\t", i, j, arr[i][j]);

printf("\n");

}

}

}

getch();

}

```
Could anyone help me?

2. You're wasting 7200 bytes of local/stack memory. A 30x30 array of 8 byte types should be dynamically allocated or static.

If you want to successfully use rand(), you have to
Code:
`srand(time(NULL));`
first.

Get rid of conio.h and any of its associated functions, it's outdated.

3. Why are you using random numbers for your array index? Wouldn't it be better to assign a value to each element of your array?

Jim

4. Originally Posted by jimblumberg
Why are you using random numbers for your array index? Wouldn't it be better to assign a value to each element of your array?

Jim
Because i want to random with the fix m[j]=4. if i not do this mean m[j]= 30. Do you have any idea, what i should deal with this problem?

5. Originally Posted by memcpy
You're wasting 7200 bytes of local/stack memory. A 30x30 array of 8 byte types should be dynamically allocated or static.

If you want to successfully use rand(), you have to
Code:
`srand(time(NULL));`
first.

Get rid of conio.h and any of its associated functions, it's outdated.
I was put "srand(time(NULL));" but i stil get the same problem sir
How do i do? any advice?

"How to generate random number without repetition?"
I do not believe there is a way directly. What I would do is either:
1. fill the data structure with all possible values and then randomly shuffle the results (as in shuffling a deck of cards) or
2. throw away the duplicates and select again

Originally Posted by memcpy
You're wasting 7200 bytes of local/stack memory. A 30x30 array of 8 byte types should be dynamically allocated or static.
Or you could make the stack size larger, if necessary.

Originally Posted by Suntang
Code:
```...
int main(void)

{

double arr[30][30];

...
if(arr[i][j] > 0){

...
}```
You seem to be assuming that arr[30][30] is automatically initialized to value 0.0 for each element. This is not true for function or block scope variables that are not static. If you used either of memcpy's suggestions, the side effect is that they would be initialized. If I were doing this, I would reinitialize them all to 0.0 explicitly.

Originally Posted by Suntang
Code:
```...
int main(void)
{
...
int m[30];
int j;
...
for (j=0; j<30; j++) {
m[j]= 0;
while(m[j] <4){
...
if(arr[i][j] > 0){
m[j]++;
...
}
...
}
...
}
...
}```
What is the purpose of only doing the activity until there are four entries per sub-array? I do not have suggestions until we understand why you are doing this extra activity with m[].

You are using the magic number 30 in several places. I suspect they are all related, but I would know that for sure if they all had the same name. Since we are talking about C, consider giving 30 a name using a #define text substitution macro.

Give your variables longer more meaning full names. If you gave m[] a different name, I might not be asking the question above.

Consider adding comments that explain "why" you are doing some of what your are doing? Avoid comments that say "what" you are doing where the code already says the same thing.

7. What is the purpose of only doing the activity until there are four entries per sub-array? I do not have suggestions until we understand why you are doing this extra activity with m[].

You are using the magic number 30 in several places. I suspect they are all related, but I would know that for sure if they all had the same name. Since we are talking about C, consider giving 30 a name using a #define text substitution macro.

Give your variables longer more meaning full names. If you gave m[] a different name, I might not be asking the question above.

Consider adding comments that explain "why" you are doing some of what your are doing? Avoid comments that say "what" you are doing where the code already says the same thing.[/QUOTE]

Humm!! i main idea that i do this because i want to generate random number in evaluation systems, suppose: I have a reviewer r(i) has evaluated an object o(j), which is weighted with the assigned evaluation score arr(i,j) between 0 and 1. The number of reviewers and objects are 30 each. and i want to generate ramdon number with the fix number of reviewers per object at n=4. I mean each object should have evaluated only 4 reviewers.

Can you give me an advince? what is the best way i should deal with this?

8. I am going to assume that you are now explicitly initializing review[MAX_REVIEWERS][MAX_OBJECTS] (formerly known as arr[30][30]) to 0.0. [Use names for these things appropriate to your language and the common language of those who will be maintaining the code.]

So change statements in the inner while loop. Get your random reviewer (formerly known as i) and see if that reviewer has already reviewed that object (formerly known as j). If they have, skip the rest of the inner loop. So the if statement is moved and goes from "if (arr[i][j] > 0.0) {" to "if review[reviewer][object] == 0.0) {". So now we know it has not been reviewed. You may want to use a do while loop to make sure that rand() does not return a 0 in the 1/RAND_MAX time that that will happen.

By the way, you may want to make the value 0.0 have the name NOT_REVIEWED and use that for initialization and this check.

9. Originally Posted by pheininger
I am going to assume that you are now explicitly initializing review[MAX_REVIEWERS][MAX_OBJECTS] (formerly known as arr[30][30]) to 0.0. [Use names for these things appropriate to your language and the common language of those who will be maintaining the code.]

So change statements in the inner while loop. Get your random reviewer (formerly known as i) and see if that reviewer has already reviewed that object (formerly known as j). If they have, skip the rest of the inner loop. So the if statement is moved and goes from "if (arr[i][j] > 0.0) {" to "if review[reviewer][object] == 0.0) {". So now we know it has not been reviewed. You may want to use a do while loop to make sure that rand() does not return a 0 in the 1/RAND_MAX time that that will happen.

By the way, you may want to make the value 0.0 have the name NOT_REVIEWED and use that for initialization and this check.
Could you show me the code sir? i don't understad. i'm a new learnner in c.

10. Here's one way, and you'll like it:

Make an integer array with the numbers that you want to randomly select from. Say I want random numbers 0-9, and each one never repeating.

Code:
`array[10]={1,2,3,4,5,6,7,8,9,10};`
now
//set srand() up before the loop

Use a for loop, from 1 to 7 (or so), get a random number in the range of 0 to 9
swap array[i] with array[random Number], in the usual way:
Code:
```temp = array[i];
array[i]=array[random number];
array[random number]= temp;```
and you're done.

You'll want to do at least 5 swaps, since you are moving two values, across an array of 10 values. To be more random, you may want to do 10 swaps, and do use a better random number design if you want REAL random performance. Generating truly good random numbers, is a lot more challenging than it looks. Thankfully, there are libraries that can help if that high a level of randomness, is needed. (doubtful, but just in case).

11. As I understand it, you want to generate 4 random numbers from 0 to 29 (inclusive) without repetition. One way is a shuffle. But since you only want 4 out of the 30 possible numbers, it's reasonably efficient to simply check against the numbers already generated with a function like this:
Code:
```// Fill a[] with n non-repeating random integers in [0,high).
void NonRepeatingRandom(int a[], int n, int high) {
int i, j, again;
for (i = 0; i < n; i++) {
do {
again = 0;
a[i] = rand() / (RAND_MAX / high + 1);
for (j = i - 1; j >= 0; j--) {
if (a[j] == a[i]) {
again = 1;
break;
}
}
} while (again);
}
}

// Call it like this:
int rndReviewers[4];
// . . .
NonRepeatingRandom(rndReviewers, 4, 30);```

12. Originally Posted by Suntang
Could you show me the code sir?
Originally Posted by pheininger
I am going to assume that you are now explicitly initializing review[MAX_REVIEWERS][MAX_OBJECTS] (formerly known as arr[30][30]) to 0.0. (Use names for these things appropriate to your language and the common language of those who will be maintaining the code.)
Old:
Code:
`   double arr[30][30];`
New:
Code:
`   double arr[30][30]={0.0};`
Originally Posted by pheininger
So change statements in the inner while loop. Get your random reviewer (formerly known as i) and see if that reviewer has already reviewed that object (formerly known as j). If they have, skip the rest of the inner loop. So the if statement is moved and goes from "if (arr[i][j] > 0.0) ..." to "if review[reviewer][object] == 0.0) ...". So now we know it has not been reviewed. You may want to use a do while loop to make sure that rand() does not return a 0 in the 1/RAND_MAX time that that will happen.
Old:
Code:
```          i= (int) rand()%30;
arr[i][j]= (double) rand()/RAND_MAX;
if (arr[i][j] > 0){
m[j]++;
}```
New:
Code:
```          i= (int) rand()%30;
if (arr[i][j] == 0.0) {
arr[i][j]= (double) rand()/RAND_MAX;
if (arr[i][j] > 0.0) {
m[j]++;```

13. > Or you could make the stack size larger, if necessary.

What do you think is easier:
• Using malloc() and writing code that follows convention.

Or:
• Finding a way to change the stack size,
• that may not work on older computers with less memory,
• that definitely doesn't work universally across systems,
• that's a quick "hack" that might or might not work,
• that slows down your code by forcing the system to do a lot more work than necessary

14. Making the stack larger isn't hard, it's just wrong because large chunks of data is not what the stack is for.
However FYI, 7.2K is not that large. Windows apps have a typical stack size of 1MB, and a minimum of 7.2K. Even with that you'd be more than fine.

15. Drat, I meant to say a minimum of 64K