|
|
View previous topic :: View next topic |
Author |
Message |
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
Randomly execute functions ? |
Posted: Tue Feb 12, 2008 9:10 pm |
|
|
Dear CCS Members,
I have a question that is kinda weird: how to randomly execute a function ?
ex:
i have a set of 6 functions
bob0();
bob1();
bob2();
bob3();
bob4();
bob5();
how to run them in a random manner ?
I don't need a pseudo random generator , only a simple random will suffice!
Any idea?
Thank you !
Best Regards,
Laurent |
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Tue Feb 12, 2008 10:24 pm |
|
|
Maybe this one will be more easier...
How to generate a random number but that will never be picked 2 times in a row?
if i use rand() with RAND_MAX 21 ,, many same numbers will be picked up ... i know it's the way random work but how to make it randomize ?
ex:
Correct order:
bob[0]
bob[1]
bob[2]
bob[3]
bob[4]
randomized order:
bob[2]
bob[4]
bob[3]
bob[0]
bob[1]
Have a nice day !
Sincerely yours,
Laurent |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 12, 2008 10:28 pm |
|
|
Add a test. Compare the current random number to the previous one.
If it's the same, then call the rand() function until you get a different one. |
|
|
Guest_7068 Guest
|
|
Posted: Tue Feb 12, 2008 10:33 pm |
|
|
There might be a few ways to do this:
You basically need a random number between 1 and 6 and then use this in a switch case statement and run one of your functions.
Method 1: Use some math function like rand, scale the value and you should be good to go.
Method 2: Use a random table in ROM. This table can be as long as you want depending on how much memory you have to spare.
Code: |
const random_table[50] = { 5,2,3,5,1,6,2,4,2, .....};
|
Once the table is in memory, you can have an simple index which increments since the table is already random. You could further randomize this by randomizing the index. |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Wed Feb 13, 2008 8:48 am |
|
|
If you pick a random number from 1 to 5 (not 0 to 5), add it to your last number, and mod() to get back into the range you will never get the same entry twice in a row. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Wed Feb 13, 2008 9:02 am |
|
|
Thanks for your replies,
Quote: | If you pick a random number from 1 to 5 (not 0 to 5), add it to your last number, and mod() to get back into the range you will never get the same entry twice in a row. |
Sorry for such stupid question, but what is mod ?
I've searched through the CCS help file, neither a C reference mention this !
Best Regards,
Laurent |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Wed Feb 13, 2008 9:55 am |
|
|
Sorry Mod() is from BASIC. In C the modulus operator is %, ie 36 % 25 returns 11. You can use it to "wrap" a counter so when it counts off the end of a range % will cause it to go back to the beginning.
Code: | int x(6); // array from 0 to 5
int count =0;
while (1){
y=x(count++); //This would eventually exceed 5
}
while (1){
y=x(count++ =% 6); //This wraps back to 0
}
|
(This code is off the top of my head and may be erroneous) _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Wed Feb 13, 2008 10:14 am |
|
|
Thanks,
Quote: | while (1){
y=x(count++ =% 6); //This wraps back to 0
} |
I have some trouble to understand what your are saying.
If count = 6 or any higher numbers will wrap back to 0. But this doesn't limit random in any way to select the same numbers again ?? Random can still give 4 4 4 3 2 3 1 1 etc the only thing it protect is to exceed the range defined... but is this the job of RAND_MAX right ?
In C++ there's a function called random_shuffle which is built to do what i want to do with arrays!
Unfortunately it is not available to C.
EDIT: Quote: | If you pick a random number from 1 to 5 (not 0 to 5), add it to your last number, and mod() to get back into the range you will never get the same entry twice in a row. |
Apply what you've said previously to what you replied make more sense
Basically you mean:
Code: |
RAND_MAX 6
rand to give a number between 0 and 6
ex: 4 is selected
then apply:
rand % 4 //This wraps back to 0 if 4 is chosen in the next rand ????
|
When writting this edit i realized something... why not rand a number then store it,, then rand another number then compare it to the last number stored if it's the same rand another one until it is not the same ?
This is no true randomize but atleast they wont be selected twice in a row ? Or even better i could store them into an array and check if the number is already there ? no ?... what you think ?
Best Regards,
Laurent |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Wed Feb 13, 2008 11:50 am |
|
|
What I intended to suggest was:
1) Say your last random number was 3.
2) Pick a random number from 1 to 5, say 4.
3) Add the new 4 to the old 3 to get 7.
4) Apply the modulus operator to "wrap" 7 to become 1.
5) The new 1 is your next random number.
The new random number must be different from the old one because step 2 must return at least 1, and not more than 5.
Step 4 assures you get a valid output.
You can think of it as a random increment instead of a random number. The increment can be positive or negative (after wrapping), but never 0. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Wed Feb 13, 2008 12:56 pm |
|
|
Thank you SherpaDoug!
I'm considering to use your technique.
However while analyzing the rand function i ran into a another problem...
RAND_MAX is defined by the compiler and it works BUT what happen when i need to generate a number with a max of 150 in the next rand??
Rand_max cannot be altered in any way during the execution of the code since it's defined !
Anyone had success creating randoms numbers with different ranges ?
Best Regards,
Laurent |
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Wed Feb 13, 2008 3:09 pm |
|
|
I started to wrote a function which i can dynamically change the max range
Code: |
void randomize(int8 max){
seedeeprom = read_eeprom(0)+1; //read the eeprom seed and increment
write_eeprom(0,seedeeprom); // store it in case of a shutdown
seed = seedeeprom;
seed = seed * 1103515245 + 12345;
((seed >> 16) % max);
for(i=0;i<max+1;i++) rndarray[i]=0; //flush the array depending on the usage
//TODO: code to pick numbers
}
|
the only thing that i'm blocked is concerning about writing an efficient «l.o.t.t.e.r.y.» numbers generator.
I'm trying to figure , how to fill the array of MAX numbers in the l.o.t.t.e.r.y. style.
EDIT: on a computer you know it's easy ,, generate an number check if it exist into the array, if not add it if yes then generate another check if its not in the array etc etc.
Like i said this work #1 on a computer when you got plenty of processing power available... on the PIC it's another story!
Best Regards,
Laurent |
|
|
SET
Joined: 15 Nov 2005 Posts: 161 Location: Glasgow, UK
|
|
Posted: Thu Feb 14, 2008 9:48 am |
|
|
If you exclude the possibility of repeated numbers, then it's *not* random.. but of course any limit to the range reduces the 'randomness' somewhat.
Another approach is a hardware noise generator - a zener diode (AC) amplified will produce nice white noise, sample that with the ADC and you should get reasonable random numbers - this has the advantage over PRBS that you dont need a seed value. |
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Thu Feb 14, 2008 10:58 am |
|
|
Quote: | If you exclude the possibility of repeated numbers, then it's *not* random.. but of course any limit to the range reduces the 'randomness' somewhat |
I know , I've changed my mind while coding , i found that a «l.o.t.t.e.r.y.» generator would be much appropriated than a simple random... but still, it is random (draw me all numbers between ex: 0-21 in a random manner) except that the number output must be controlled.
Quote: | Another approach is a hardware noise generator - a zener diode (AC) amplified will produce nice white noise, sample that with the ADC and you should get reasonable random numbers - this has the advantage over PRBS that you dont need a seed value. |
I've noted that , this could be very usefull later on !
Thank you for your comment SET.
Best Regards,
Laurent |
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Fri Feb 15, 2008 6:04 pm |
|
|
Ok since I've tried many many things to randomize an array without any success :(...
I will start from something VERY simple and it still doesn't work...
I've created a «random» array
Here's the problem:
Code: |
const int16 led[]={pin_d0,pin_d1,pin_d2,pin_d3,pin_d4,pin_d5,pin_d6,pin_d7,
pin_b0,pin_b1,pin_b2,pin_b3,pin_b4,pin_b5,pin_b6,pin_b7,pin_a0,pin_a1,pin_a2,
pin_a3,pin_a4,pin_a5};
int8 rndtable[]={5,4,0,17,21,20,14,9,8,16,15,10,6,11,2,7,19,1,13,3,12,18};
void drawpiece2(void){
for(c=0;c<21;++c)
{
output_high(led[rndtable[i]]);
}
//clsfade();
}
|
Output_high(led[0]); will work but when i'm trying to load randomized numbers with this : output_high(led[rndtable[i]]); the pic hang.
EDIT: fixed>> i, should be c ... my bad
Anyway thanks for the support!
Best Regards,
Laurent |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|