We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
about random() (Read 1845 times)
about random()
Nov 6th, 2009, 7:07am
 
hi,

is there a way to generate random numbers which doesn't repeat?
It seems that normal random() generates random numbers within range but I believe that somehow it generates already generated number.

I'd like to generate random numbers within lo,hi range but I want to avoid to generate the same numbers during the single process.

thank you.
Re: about random()
Reply #1 - Nov 6th, 2009, 7:46am
 
milc wrote on Nov 6th, 2009, 7:07am:
is there a way to generate random numbers which doesn't repeat

No. That's also part of the randomness... Smiley
You can use a huge interval, the probability of repeating is lowered.
You can also store all previous results, and if new one is in this set, just ignore it and draw another number (if any is still available!).
You can use some alternative RND implementations, like Mersenne Twister or other cryptographic RNG.
If your goal is to generate semi-random numbers covering a whole interval without overlay, look at my last answer in this thread: Processing 1.0 - save/output large image with transparency (might be Euler's algorithm although I am not sure).
Re: about random()
Reply #2 - Nov 6th, 2009, 9:42am
 
The basic way I devised is to put all the possible numbers into an array. Use random(array.length) to select an index for selecting one of those possible numbers. Keep track of the index, and move the last element in the array into that indexed spot. Repeat the process but reducing the array.length by one, until you've drawn all possible numbers.
Re: about random()
Reply #3 - Nov 7th, 2009, 2:53am
 
thanks for the replies,
it seems that using array is the proper solution for my purpose.
however, I never coded using array, so it's not easy to get the concept.
I can understand the part random(array.length). In my case, I put the whole pixels of screen so it'd be a huge array contains millions of numbers.
But then, the part 'keep track of the index' and 'move the last element in the array into that indexed spot'...honestly I don't really get the idea of what it can possibly mean. Is it possible to get some code examples of this concept? It'll be hugely helpful for me.

thank you very much.
Re: about random()
Reply #4 - Nov 7th, 2009, 7:20am
 
Perhaps you could explain what you are trying to do (or need to do), so we can give more targeted advices.
Re: about random()
Reply #5 - Nov 7th, 2009, 7:48am
 
what I'm trying to do is actually quite simple. (at least it sounds simple..)

I just want to fill up a screen, let's say 640*480 resolution, with one-colored pixels. Pixel by pixel, until the whole screen filled with the color.
The problem is, as random() generates already generated numbers (coordination of pixels), the process is too slow. And the worst is that, at the end when there's not so many 'holes' to fill, it seems that it'll never end up filling the whole screen. It will take long long time to get the right numbers, let's say 48, 17204, 370, 9720, from the number range of 0 to 307200! So, that's the problem need to be solved.
this is the code I use for now:

void draw(){
int x = int(random(0, width));
int y = int(random(0, height));
set(x, y, #000000);
}

Thanks
Re: about random()
Reply #6 - Nov 7th, 2009, 8:26am
 
So, look again at my answer, the last part...
Re: about random()
Reply #7 - Nov 8th, 2009, 2:33am
 
ok, I had a closer look at the answer. But it's hard to understand the code, because there's a lot of things going on. I can't even run the code. it gives a nullPointException error. I guess that 'no overlap method' has something to do for my purpose but it's hard to break down the code and get the thing for me. am I too lazy? can someone please tell me then, what part of p5 to study so that I can find the solution myself? should I study array?
thanks.
Re: about random()
Reply #8 - Nov 8th, 2009, 4:27am
 
i have a totally different approach to this. but it works...
what i do is  to fill an array with allt he pixels available.
So array[i]=i;
now i shuffle the array and still got all the coordinates stored but in different order. now i can simply count up i and draw the whole array till the end.

in my example. when the full screen is filled, i set the counter back to 0 choose a different filling color and start again..

i would say the array and shuffle solution is really useful if you want some random numbers picked without repeating.


Code:
Integer[] pixelArray;
void setup(){
 size(100,100);
 pixelArray = new Integer[width*height];
 for(int i = 0; i<width*height;i++){
   pixelArray[i] = i;
frameRate(1000);
 }
 Collections.shuffle(Arrays.asList(pixelArray));
 background(0);
}
int i;
color cc = color(random(255),random(255),random(255));

void draw(){
 loadPixels();

 pixels[pixelArray[i]] = cc;
 i++;
 updatePixels();

 if(i==width*height){
   i=0;
   cc = color(random(255),random(255),random(255));
 }
}
Re: about random()
Reply #9 - Nov 8th, 2009, 5:44am
 
thanks!!!

it works perfectly!
I need to understand the code and twist a bit, but since I have the result, it's just matter of time.

thank you very much and next time I'll come up with better skills to avoid someone write me a code like this...
Re: about random()
Reply #10 - Nov 8th, 2009, 5:57am
 
Mmm, right, that example had some fluff, I had a simpler example (using the same algorithm) but I don't recall if I shown it in the forum.
Here it is:
Code:
static final int LARGE_PRIME = 444443;
int[] pixels;
int iterator, position;

void setup()
{
size(1000, 10);
pixels = new int[width];
}

void draw()
{
iterator++;
if (iterator > width + 10) // Deliberately go slightly over to verify my check routine...
{
noLoop();
for (int i = 0; i < width; i++) if (pixels[i] != 1) println("[" + i + "]=" + pixels[i]);
println("END");
}
position = (position + LARGE_PRIME) % width;
switch (pixels[position])
{
case 0: stroke(#00FFFF); break;
case 1: stroke(#00FF00); break;
case 2: stroke(#FFFF00); break;
default: stroke(#FF0000); break;
}
point(position, height / 2);
pixels[position]++;
}

It can be adapted to your request:
Code:
static final int LARGE_PRIME = 5554993;
int pixelNb;
int iterator, position;

void setup()
{
size(600, 400);
pixelNb = height * width;
loadPixels();
background(0);
frameRate(999);
}

void draw()
{
iterator++;
if (iterator > pixelNb)
{
noLoop();
println("END");
}
position = (position + LARGE_PRIME) % pixelNb;
pixels[position] = #8080FF;
updatePixels();
}

Well, it is still slow (that's a lot of pixels to paint! and the updatePixels() doesn't help) and it looks a bit too much regular...
Cedric's approach is fine too, just a bit memory hungry, but we have plenty of it  anyway, no?
Re: about random()
Reply #11 - Nov 8th, 2009, 7:48am
 
Here's the code I have for the method I described - it's based on the metaphor of having x number of balls in an urn:

int choice = 0;
int index = 0;
int num = <array size>;
int [] order = new int[num];

void urn() {
 int [] balls = new  int[num]; // initialize the array

 for (int i = 0; i < num; i++)
 {
   balls[i] = i; // fill the array with a sequence of integers starting with 0
 }
 for (int j = num-1; j > -1; j--) {
   index = int(random(0, j)); // choose a # between 0 and num
   choice = (balls[index]); //use it as an index to choose a value from the array
   order[j] = choice; // put the choice into the ordered array
   balls[index] = balls[j]; // move the last element in the urn
   // to the place where the choice came from
 }

}
Page Index Toggle Pages: 1