Randomizing specific range

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • raghavendrap
    New Member
    • Oct 2008
    • 19

    Randomizing specific range

    Hello Friends,
    I am doing randomization of intergers for specific range.The way i have done is mentioned below.

    Code:
    use strict;
    
    my @id;
    my $idx1;
    my $idx2;
    my $idx3;
    my $idx4;
    
     @id = (4..28); 
       print ("ID range is @id \n");
       
       $idx1 = int(rand @id ); 
       print ("idx1 random is $idx1 \n");
       $idx2 = int(rand @id); 
       print ("idx2 random is $idx2 \n");
       $idx3 = int(rand @id); 
       print ("idx3 random is $idx3 \n");
       $idx4 = int(rand @id); 
       print ("idx4 random is $idx4 \n");
    Code:
    [U]Output:[/U]
      ID range is 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 
    idx1 random is 10 
    idx2 random is 2 
    idx3 random is 14 
    dx4 random is 13
    Here my problem is i am not getting the random values with in the given range, see the code which i got output for the program, idx2 value is 2, but the range i have mentioned is 4..28.

    Please anyone let me know where i did wrong.

    Thanks
    Raghavendra
    Last edited by eWish; Nov 13 '08, 04:34 AM. Reason: Please use the code tags
  • KevinADC
    Recognized Expert Specialist
    • Jan 2007
    • 4092

    #2
    Its because you are using the array @id in scalar context which is the length of the array, not the elements in the array. The array is length 15 so the values returned by your code will be 0 thru 14. What you want to do is use the length of the array to generate a random number to use as an index number of the array which will return the corresponing values in the array. Easier explained with code than words:

    Code:
     @id = (4..28); 
       print ("ID range is @id \n");
     
       $idx1 = int($id[rand @id] ); 
       print ("idx1 random is $idx1 \n");
       $idx2 = int($id[rand @id]); 
       print ("idx2 random is $idx2 \n");
       $idx3 = int($id[rand @id]); 
       print ("idx3 random is $idx3 \n");
       $idx4 = int($id[rand @id]); 
       print ("idx4 random is $idx4 \n");
    Edit:

    it should really be written like this:

    Code:
    $idx1 = $id[int rand @id];
    although using 'int' isn't really necessary

    Comment

    • eWish
      Recognized Expert Contributor
      • Jul 2007
      • 973

      #3
      I like Kevin's code. However, this will produce a random number between 4 and 28. Just for an example I am printing it 100 times.

      Code:
      for (1..100) {
      	print 4 + int rand( 28-4+1 ), "\n";
      }
      --Kevin

      Comment

      • raghavendrap
        New Member
        • Oct 2008
        • 19

        #4
        Thank you kelvin,
        In that code, if i want to generate random values for idx1,idx2,idx3. ...so on..such that the random value generated by idx1 not equal to anyone of the indexes i.e unique and the random value generated by idx2 not equal to anyone of the indexes ..so on i.e
        the random values must be unique i.e idx1 != idx2 != idx3 ..so on.....
        if i run 100 or 1000 times.....the values must not be same for the range (4..30).


        Thanks
        Raghavendra

        Comment

        • nithinpes
          Recognized Expert Contributor
          • Dec 2007
          • 410

          #5
          Originally posted by raghavendrap
          Thank you kelvin,
          In that code, if i want to generate random values for idx1,idx2,idx3. ...so on..such that the random value generated by idx1 not equal to anyone of the indexes i.e unique and the random value generated by idx2 not equal to anyone of the indexes ..so on i.e
          the random values must be unique i.e idx1 != idx2 != idx3 ..so on.....
          if i run 100 or 1000 times.....the values must not be same for the range (4..30).


          Thanks
          Raghavendra
          That is an incorrect expectation, logically. You can't expect 100 random numbers generated in the range (4..30) to be unique as the range itself consists of only 26 numbers!

          Comment

          • nithinpes
            Recognized Expert Contributor
            • Dec 2007
            • 410

            #6
            However, I will consider a different range(4..108). If you want to generate 100 unique random numbers in this range, use:
            Code:
            my %unique;
            for (1..100) { 
                my $rand =4 + int rand( 108-4+1 ); 
                redo if(exists $unique{$rand});
                print "$rand\t";
                $unique{$rand}++;
            }

            Comment

            • raghavendrap
              New Member
              • Oct 2008
              • 19

              #7
              Hello nithinpes,
              Thank you very much,
              My actual scenario is, i have registers from "Ridxinitial... Ridxend"
              lets say idxinitial = , idxend =30 i.e i have registers from R4..R30.
              tat's y i have taken range (4..30)

              i.e @id = (4..30);

              Code:
              use strict                    
              my @id ;
              my $idx1;
              my $idx2;
              my $idx3;
              my $idx4;
              my $idx5;
              my $idx6;
              my $idx7;
              my $idx8;
              my $idx9;
              my $idx10;
              
               @id = (4..30);
                $idx1 = $id(int rand @id);
                $idx2 = $id(int rand @id);
                $idx3 = $id(int rand @id);
                $idx4 = $id(int rand @id);
                $idx5 = $id(int rand @id);
                $idx6 = $id(int rand @id);
                $idx7 = $id(int rand @id);
                $idx8 = $id(int rand @id);
                $idx9 = $id(int rand @id);
                $idx10 = $id(int rand @id);
                print("IDX values are  $dx1,$idx2,$idx3,$idx4,$idx5,$idx6,$idx7,$idx8,$idx9,$idx10");
              If i run the exact code once which i have mentioned above i am getting the output as anyone of the $id values are same,
              But what my requirement is if run the code once, the random values generated by & assigned to $idx much be unique.


              Thanks & Regards
              Raghavendra
              Last edited by eWish; Nov 14 '08, 12:22 AM. Reason: Please use the code tags

              Comment

              • nithinpes
                Recognized Expert Contributor
                • Dec 2007
                • 410

                #8
                Originally posted by raghavendrap
                Hello nithinpes,
                Thank you very much,
                My actual scenario is, i have registers from "Ridxinitial... Ridxend"
                lets say idxinitial = , idxend =30 i.e i have registers from R4..R30.
                tat's y i have taken range (4..30)

                i.e @id = (4..30);

                use strict
                my @id ;
                my $idx1;
                my $idx2;
                my $idx3;
                my $idx4;
                my $idx5;
                my $idx6;
                my $idx7;
                my $idx8;
                my $idx9;
                my $idx10;

                @id = (4..30);
                $idx1 = $id(int rand @id);
                $idx2 = $id(int rand @id);
                $idx3 = $id(int rand @id);
                $idx4 = $id(int rand @id);
                $idx5 = $id(int rand @id);
                $idx6 = $id(int rand @id);
                $idx7 = $id(int rand @id);
                $idx8 = $id(int rand @id);
                $idx9 = $id(int rand @id);
                $idx10 = $id(int rand @id);
                print("IDX values are $dx1,$idx2,$idx 3,$idx4,$idx5,$ idx6,$idx7,$idx 8,$idx9,$idx10" );

                If i run the exact code once which i have mentioned above i am getting the output as anyone of the $id values are same,
                But what my requirement is if run the code once, the random values generated by & assigned to $idx much be unique.


                Thanks & Regards
                Raghavendra
                Try the code that I mentioned in my previous post.

                Comment

                • raghavendrap
                  New Member
                  • Oct 2008
                  • 19

                  #9
                  Can u please be clear, i tried alot for that but it's not coming.

                  Comment

                  • nithinpes
                    Recognized Expert Contributor
                    • Dec 2007
                    • 410

                    #10
                    Originally posted by raghavendrap
                    Can u please be clear, i tried alot for that but it's not coming.
                    Code:
                    my %unique;
                    for (1..10) { 
                       my $rand =4 + int rand( 30-4+1 ); 
                        redo if(exists $unique{$rand});
                        push @rand,$rand;
                        $unique{$rand}++;
                    } 
                    print "IDX values are:\n" ;
                    $,="\t";
                    print @rand;
                    Also, the code you tried will not result in anything. Concentrate on Kevin's code.
                    Code:
                    $idx1 = $id(int rand @id);  # should be $idx1 = int($id[rand @id] );
                    ## OR $idx2 = $id[int rand @id];
                    Last edited by nithinpes; Nov 13 '08, 02:14 PM. Reason: edited code

                    Comment

                    • raghavendrap
                      New Member
                      • Oct 2008
                      • 19

                      #11
                      Thank you very much for helping me.

                      Comment

                      • Ganon11
                        Recognized Expert Specialist
                        • Oct 2006
                        • 3651

                        #12
                        Another very simple method of getting a unique number each time would be to use the List::Util subroutine shuffle(). Every time you need a random element in id, shuffle the array, then shift() the first element. The shuffle will randomize the array, and removing the element will make sure you never get a repeat. Here's a sample:

                        Code:
                        use strict;
                        use warnings;
                        use List::Util qw/shuffle/;
                        
                        my @nums = (1..50);
                        my $i = 1; # for printing nicely...
                        while (@nums) {
                           @nums = shuffle(@nums);
                           my $num = shift @nums;
                           print "$num ";
                           print "\n" if ($i % 10 == 0); # for printing nicely...
                           $i++; # for printing nicely...
                        }

                        Comment

                        • KevinADC
                          Recognized Expert Specialist
                          • Jan 2007
                          • 4092

                          #13
                          Originally posted by raghavendrap
                          Hello nithinpes,
                          Thank you very much,
                          My actual scenario is, i have registers from "Ridxinitial... Ridxend"
                          lets say idxinitial = , idxend =30 i.e i have registers from R4..R30.
                          tat's y i have taken range (4..30)

                          i.e @id = (4..30);

                          use strict
                          my @id ;
                          my $idx1;
                          my $idx2;
                          my $idx3;
                          my $idx4;
                          my $idx5;
                          my $idx6;
                          my $idx7;
                          my $idx8;
                          my $idx9;
                          my $idx10;

                          @id = (4..30);
                          $idx1 = $id(int rand @id);
                          $idx2 = $id(int rand @id);
                          $idx3 = $id(int rand @id);
                          $idx4 = $id(int rand @id);
                          $idx5 = $id(int rand @id);
                          $idx6 = $id(int rand @id);
                          $idx7 = $id(int rand @id);
                          $idx8 = $id(int rand @id);
                          $idx9 = $id(int rand @id);
                          $idx10 = $id(int rand @id);
                          print("IDX values are $dx1,$idx2,$idx 3,$idx4,$idx5,$ idx6,$idx7,$idx 8,$idx9,$idx10" );

                          If i run the exact code once which i have mentioned above i am getting the output as anyone of the $id values are same,
                          But what my requirement is if run the code once, the random values generated by & assigned to $idx much be unique.


                          Thanks & Regards
                          Raghavendra
                          Why bother to explain and post code examples if you are going to ignore them? You went right back to your incorrect code.

                          Comment

                          • raghavendrap
                            New Member
                            • Oct 2008
                            • 19

                            #14
                            Sorry kevin,
                            the method which you said is perfectly working for me,since i am in learning stage that's why i am looking for some more solutions inorder to know how the perl constructs are used in several ways.
                            Thanks alot to you & members for the quick response.

                            Regards
                            Raghavendra

                            Comment

                            Working...