Generate random arrays?

B

BCC

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
 
A

A. Sinan Unur

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
questions. Please do read the posting guidelines for this group.

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{num} - 1) {
push @{ ${ @{$points} }[$i] },
$args{min} + rand($args{max}-$args{min} + 1);
}
}
__END__
 
B

BCC

A. Sinan Unur said:
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;
sub getCoords {
my @nums = (1..100);
my %random = ();
my $num = 0;
until ($num == 1000) {
my $i = int($nums[rand(@nums)]);
$random{$i}=1;
$num = keys %random;
}
return(keys %random);
}

Thanks for the help,
B
 
X

xhoster

BCC said:
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{$i}=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
 
J

Jonas Nilsson

BCC said:
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..$#{$list}) {
print "@{$list->[$_]}\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{"@{$p}"}++) {
$number--;
push @points,$p;
}
}
return \@points;
}

/jN
 
B

Big and Blue

BCC said:
sub getCoords {
my @nums = (1..100);
my %random = ();
my $num = 0;
until ($num == 1000) {
my $i = int($nums[rand(@nums)]);
$random{$i}=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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top