Thread: How to generate random number without repetition?

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    9

    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?
    Thanks in advance!!!
    Last edited by Suntang; 03-17-2012 at 09:56 AM.

  2. #2
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    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. #3
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    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. #4
    Registered User
    Join Date
    Mar 2012
    Posts
    9
    Quote Originally Posted by jimblumberg View Post
    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. #5
    Registered User
    Join Date
    Mar 2012
    Posts
    9
    Quote Originally Posted by memcpy View Post
    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?

  6. #6
    Registered User
    Join Date
    Jun 2010
    Location
    Michigan, USA
    Posts
    143
    Quoting the thread title:
    "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


    Quote Originally Posted by memcpy View Post
    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.

    Quote Originally Posted by Suntang View Post
    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.

    Quote Originally Posted by Suntang View Post
    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[].

    General comments:
    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.
    Last edited by pheininger; 03-17-2012 at 10:45 AM. Reason: General clean up. Misspelling from through->throw.

  7. #7
    Registered User
    Join Date
    Mar 2012
    Posts
    9
    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[].

    General comments:
    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. #8
    Registered User
    Join Date
    Jun 2010
    Location
    Michigan, USA
    Posts
    143
    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. #9
    Registered User
    Join Date
    Mar 2012
    Posts
    9
    Quote Originally Posted by pheininger View Post
    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. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    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. #11
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    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);
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  12. #12
    Registered User
    Join Date
    Jun 2010
    Location
    Michigan, USA
    Posts
    143
    Quote Originally Posted by Suntang View Post
    Could you show me the code sir?
    Quote Originally Posted by pheininger View Post
    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};
    Quote Originally Posted by pheininger View Post
    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. #13
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    > 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. #14
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    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.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  15. #15
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Drat, I meant to say a minimum of 64K
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 9
    Last Post: 11-02-2011, 09:53 AM
  2. how to generate a random number in c?
    By blogchama in forum C Programming
    Replies: 2
    Last Post: 01-20-2011, 10:39 AM
  3. Generate Random Number
    By peacealida in forum C++ Programming
    Replies: 10
    Last Post: 04-06-2008, 08:57 AM
  4. Replies: 11
    Last Post: 07-16-2002, 11:39 AM
  5. Ask about generate Random number
    By ooosawaddee3 in forum C Programming
    Replies: 2
    Last Post: 07-01-2002, 04:30 AM

Tags for this Thread