By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,693 Members | 1,972 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,693 IT Pros & Developers. It's quick & easy.

Randomizing specific range

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

Expand|Select|Wrap|Line Numbers
  1. use strict;
  2.  
  3. my @id;
  4. my $idx1;
  5. my $idx2;
  6. my $idx3;
  7. my $idx4;
  8.  
  9.  @id = (4..28); 
  10.    print ("ID range is @id \n");
  11.  
  12.    $idx1 = int(rand @id ); 
  13.    print ("idx1 random is $idx1 \n");
  14.    $idx2 = int(rand @id); 
  15.    print ("idx2 random is $idx2 \n");
  16.    $idx3 = int(rand @id); 
  17.    print ("idx3 random is $idx3 \n");
  18.    $idx4 = int(rand @id); 
  19.    print ("idx4 random is $idx4 \n");
Expand|Select|Wrap|Line Numbers
  1. Output:
  2.   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 
  3. idx1 random is 10 
  4. idx2 random is 2 
  5. idx3 random is 14 
  6. 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
Nov 13 '08 #1
Share this Question
Share on Google+
13 Replies


KevinADC
Expert 2.5K+
P: 4,059
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:

Expand|Select|Wrap|Line Numbers
  1.  @id = (4..28); 
  2.    print ("ID range is @id \n");
  3.  
  4.    $idx1 = int($id[rand @id] ); 
  5.    print ("idx1 random is $idx1 \n");
  6.    $idx2 = int($id[rand @id]); 
  7.    print ("idx2 random is $idx2 \n");
  8.    $idx3 = int($id[rand @id]); 
  9.    print ("idx3 random is $idx3 \n");
  10.    $idx4 = int($id[rand @id]); 
  11.    print ("idx4 random is $idx4 \n");
  12.  
Edit:

it should really be written like this:

Expand|Select|Wrap|Line Numbers
  1. $idx1 = $id[int rand @id];
although using 'int' isn't really necessary
Nov 13 '08 #2

eWish
Expert 100+
P: 971
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.

Expand|Select|Wrap|Line Numbers
  1. for (1..100) {
  2.     print 4 + int rand( 28-4+1 ), "\n";
  3. }
--Kevin
Nov 13 '08 #3

P: 19
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
Nov 13 '08 #4

nithinpes
Expert 100+
P: 410
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!
Nov 13 '08 #5

nithinpes
Expert 100+
P: 410
However, I will consider a different range(4..108). If you want to generate 100 unique random numbers in this range, use:
Expand|Select|Wrap|Line Numbers
  1. my %unique;
  2. for (1..100) { 
  3.     my $rand =4 + int rand( 108-4+1 ); 
  4.     redo if(exists $unique{$rand});
  5.     print "$rand\t";
  6.     $unique{$rand}++;
  7.  
Nov 13 '08 #6

P: 19
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);

Expand|Select|Wrap|Line Numbers
  1. use strict                    
  2. my @id ;
  3. my $idx1;
  4. my $idx2;
  5. my $idx3;
  6. my $idx4;
  7. my $idx5;
  8. my $idx6;
  9. my $idx7;
  10. my $idx8;
  11. my $idx9;
  12. my $idx10;
  13.  
  14.  @id = (4..30);
  15.   $idx1 = $id(int rand @id);
  16.   $idx2 = $id(int rand @id);
  17.   $idx3 = $id(int rand @id);
  18.   $idx4 = $id(int rand @id);
  19.   $idx5 = $id(int rand @id);
  20.   $idx6 = $id(int rand @id);
  21.   $idx7 = $id(int rand @id);
  22.   $idx8 = $id(int rand @id);
  23.   $idx9 = $id(int rand @id);
  24.   $idx10 = $id(int rand @id);
  25.   print("IDX values are  $dx1,$idx2,$idx3,$idx4,$idx5,$idx6,$idx7,$idx8,$idx9,$idx10");
  26.  
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
Nov 13 '08 #7

nithinpes
Expert 100+
P: 410
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,$idx3,$idx4,$idx5,$idx6,$idx7,$idx8,$id x9,$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.
Nov 13 '08 #8

P: 19
Can u please be clear, i tried alot for that but it's not coming.
Nov 13 '08 #9

nithinpes
Expert 100+
P: 410
Can u please be clear, i tried alot for that but it's not coming.
Expand|Select|Wrap|Line Numbers
  1. my %unique;
  2. for (1..10) { 
  3.    my $rand =4 + int rand( 30-4+1 ); 
  4.     redo if(exists $unique{$rand});
  5.     push @rand,$rand;
  6.     $unique{$rand}++;
  7. print "IDX values are:\n" ;
  8. $,="\t";
  9. print @rand;
  10.  
Also, the code you tried will not result in anything. Concentrate on Kevin's code.
Expand|Select|Wrap|Line Numbers
  1. $idx1 = $id(int rand @id);  # should be $idx1 = int($id[rand @id] );
  2. ## OR $idx2 = $id[int rand @id];
  3.  
Nov 13 '08 #10

P: 19
Thank you very much for helping me.
Nov 13 '08 #11

Ganon11
Expert 2.5K+
P: 3,652
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:

Expand|Select|Wrap|Line Numbers
  1. use strict;
  2. use warnings;
  3. use List::Util qw/shuffle/;
  4.  
  5. my @nums = (1..50);
  6. my $i = 1; # for printing nicely...
  7. while (@nums) {
  8.    @nums = shuffle(@nums);
  9.    my $num = shift @nums;
  10.    print "$num ";
  11.    print "\n" if ($i % 10 == 0); # for printing nicely...
  12.    $i++; # for printing nicely...
  13. }
Nov 13 '08 #12

KevinADC
Expert 2.5K+
P: 4,059
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,$idx3,$idx4,$idx5,$idx6,$idx7,$idx8,$id x9,$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.
Nov 13 '08 #13

P: 19
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
Nov 14 '08 #14

Post your reply

Sign in to post your reply or Sign up for a free account.