CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Randomly execute functions ?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

Randomly execute functions ?
PostPosted: Tue Feb 12, 2008 9:10 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Feb 12, 2008 10:24 pm     Reply with quote

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 Smile !

Sincerely yours,
Laurent
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Feb 12, 2008 10:28 pm     Reply with quote

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







PostPosted: Tue Feb 12, 2008 10:33 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Feb 13, 2008 8:48 am     Reply with 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.
_________________
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

View user's profile Send private message

PostPosted: Wed Feb 13, 2008 9:02 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Feb 13, 2008 9:55 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Feb 13, 2008 10:14 am     Reply with quote

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 Smile

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

View user's profile Send private message

PostPosted: Wed Feb 13, 2008 11:50 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Feb 13, 2008 12:56 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Feb 13, 2008 3:09 pm     Reply with quote

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

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Feb 14, 2008 9:48 am     Reply with 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.

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

View user's profile Send private message

PostPosted: Thu Feb 14, 2008 10:58 am     Reply with quote

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 Smile , 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

View user's profile Send private message

PostPosted: Fri Feb 15, 2008 6:04 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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