# Generate random arrays?

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on

Hi,  I have a matrix that is 100x100x100, and wish to generate a list of
1000 randomly chosen non-repeating x,y,z coordinates within the space.

I can generate a list of non-repeating single digits using rand(), but
Im not sure how to take it to the next level...

Thanks,
B

## Re: Generate random arrays?

> Hi,  I have a matrix that is 100x100x100, and wish to generate a list
> of
>   1000 randomly chosen non-repeating x,y,z coordinates within the
>   space.
>
> I can generate a list of non-repeating single digits using rand(), but
> Im not sure how to take it to the next level...

I am not exactly sure what you mean by 'non-repeating'. Now, the best
way to get help here is to first make an attempt, then ask specific

Here is some code (untested) that may or may not do what you want.

#! /usr/bin/perl

use strict;
use warnings;

my @points;

gen_coord(\@points) for (1 .. 3);

use Data::Dumper;
print Dumper \@points;

sub gen_coord {
my \$points = shift;
my %args = (
num => 100,
min => 0,
max => 100,
@_,
);

for my \$i (0 .. \$args - 1) {
push @{ \${ @ }[\$i] },
\$args + rand(\$args-\$args + 1);
}
}
__END__

--
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:

## Re: Generate random arrays?

A. Sinan Unur wrote:

> I am not exactly sure what you mean by 'non-repeating'. Now, the best
> way to get help here is to first make an attempt, then ask specific

Just that there should be no duplicate coordinates generated... and to
retroactivly correct my post, here was the first attempt, extracted and
modified from a web site:

use strict;
use warnings;

my @shuffle = &getCoords;
sub getCoords {
my @nums = (1..100);
my %random = ();
my \$num = 0;
until (\$num == 1000) {
my \$i = int(\$nums[rand(@nums)]);
\$random=1;
\$num = keys %random;
}
return(keys %random);
}

Thanks for the help,
B

## Re: Generate random arrays?

> A. Sinan Unur wrote:
>
> > I am not exactly sure what you mean by 'non-repeating'. Now, the best
> > way to get help here is to first make an attempt, then ask specific
> > questions. Please do read the posting guidelines for this group.
>
> Just that there should be no duplicate coordinates generated... and to
> retroactivly correct my post, here was the first attempt, extracted and
> modified from a web site:
>
> use strict;
> use warnings;
>
> my @shuffle = &getCoords;

Don't call subs with & for no good reason.

> sub getCoords {
>     my @nums = (1..100);

this variable serves no good purpose.  Only it's size is used in a
meaningful way, so just use that size directly (or a scalar holding the
size).

>     my %random = ();
>     my \$num = 0;

This variable serves no good purpose. It only stores the size of the hash,
which is easy enough to just use directly.  (Of course, if you need a
multi level hash for the "real" solution, then \$num may come in handy yet.)

>     until (\$num == 1000) {
until (1000 == keys %random) {

>        my \$i = int(\$nums[rand(@nums)]);
my \$i = int(rand 100)+1;

>        \$random=1;
I'd prefer to set it to () rather than 1, but no big deal.

>        \$num = keys %random;
no longer necessary.

>     }
>     return(keys %random);
> }

Ok, so now that you showed it to us, why doesn't it do what you want
it to do?  Is it because you want it be nonrepeating among
all three dimensions simultaneously, but possible to repeat within any
single dimenstion considered alone?  If that is the case, I'd just change
the one line to:

my \$i=join"\t",int(rand 100)+1,int(rand 100)+1,int(rand 100)+1;

And then use map and split to munge the keys into the desired format at
the end:

return map [split /\t/], keys %random;

You could use multi-level hash instead, but I wouldn't bother in this
case.

Xho

--
Usenet Newsgroup Service                        \$9.95/Month 30GB

## Re: Generate random arrays?

BCC wrote:
>
> sub getCoords {
>    my @nums = (1..100);
>    my %random = ();
>    my \$num = 0;
>    until (\$num == 1000) {
>       my \$i = int(\$nums[rand(@nums)]);
>       \$random=1;
>       \$num = keys %random;
>    }
>    return(keys %random);
> }

This should loop forever.  Your range for i is 0 to 99, but your loop
exit condition is to stop when you have 1000 different integers in that
range.  It won't happen.

Also, the concept of "random" and "non-repeating" is contradictory.

--
Just because I've written it doesn't mean that
either you or I have to believe it.

## Re: Generate random arrays?

> Hi,  I have a matrix that is 100x100x100, and wish to generate a list of
>   1000 randomly chosen non-repeating x,y,z coordinates within the space.
>
> I can generate a list of non-repeating single digits using rand(), but
> Im not sure how to take it to the next level...
>

Try this:

use strict;

# Usage generatate_non_repeating_coordinates (Dimensions, size, number of
coordinates, offset of axis (0 if left out));

my \$list=generatate_non_repeating_coordinates(3,100,1000,1);
# or maybe:
my \$list=generatate_non_repeating_coordinates(3,100,1000);

for (0..\$#) {
print "@\n";
}

sub generatate_non_repeating_coordinates {
my (\$dim,\$size,\$number)=@_;
die "Not enough space!" if (\$size**\$dim<\$number);
my \$offset=\$_[3] or 0;
my @points;
my %tmp;
while (\$number) {
my \$p=[map {\$offset+int rand \$size} (1..\$dim)];
unless (\$tmp"}++) {
\$number--;
push @points,\$p;
}
}
return \@points;
}

/jN