Calling an object with a probability of n%
youngdave
Posts: 70
Dear All
I have a loop in Spin repeating infinitely, within which a number of objects are called, one of these needs to be called with a probability of 60%, another with a probability of 0.001%, … etc. Does anybody have any ideas on how to implement this?
TIA David Young
I have a loop in Spin repeating infinitely, within which a number of objects are called, one of these needs to be called with a probability of 60%, another with a probability of 0.001%, … etc. Does anybody have any ideas on how to implement this?
TIA David Young
Comments
- Set a threshold for each routine that is proportional to the % times it is to be called.
- If 0.001% is the smallest then use a random number generator to produce a number between 0 - 1,000,000.
- The thresholld for 0.001% would be 10, and 60% would be 600,000
- If the random number is less than the threshold call the routine.
Another option would be to use a counter with a noisy high frequency input clock instead of a random number generator.
I second what Kwin said. But here is a program that achieves it.
It uses the OBEX object called RealRandom.spin.....see the attached Zip file
it has all you need. The top level file is called RandomNumber_Demo.spin
it has commnets for you to see how things are done.
The RealRandom object uses jitter in the PLL system to create random
numbers -2147483648 to 2147483647
I use the Absolute (||) operator to keep it positive
I also use the modulus (//) operator to keep it from 0 to n-1
and as Kwin said if you use n of 1000_000 then 60% of the time
the number will be less than 600_000 and 0.001% of the time it
will be less than 10.
I hope this helps
Samuel
Post Edited (SamMishal) : 8/13/2009 4:04:22 AM GMT
http://www.rand.org/pubs/monograph_reports/MR1418/
Post Edited (Agent420) : 8/12/2009 5:29:25 PM GMT
The random number generator generates numbers from 0 to 9 but the range you are interested in is 0 - 5. If you now use modulus 6, the result will be 0 for 0 or 6 ... 1 for 1 or 7 ... 2 for 2 or 8 ... 3 for 3 or 9 ... 4 only for 4 and 5 only for 5. This means the propability for 0-3 is different than the propability for 4 and 5.
If the number generator has a range from 0 to 11 it would be ok to use modulus in this example.
So, if you need an accurate propability, you should simply regenerate a number in case a number of the upper range is generated.
MagIO2: You example is correct, but the random number generator returns values on the order of 2^31.
John Abshier
That's why I said ".. if you need accurate ...". The OP already mentions a propability of 0.001% and that's only an example. So, if the minimum possible propability is even lower, accuracy might be an issue.
if the number repeatedly comes out to be outside the range) is to do this
use the || to make it positive and then divide it by ($7FFFFFFF / n)
so change the line in the program
·· Return ||RR.Random // 1000000
to
·· Return ||RR.Random / ($7FFFFFFF / Limit)
Of course there is a little bit of accuracy loss due to Integer division. However it should be good enough
for what you are trying to do.
Samuel
·
Thanks so much for all the suggestions.
The PropStick USB I received a couple of weeks ago seems to have been a dud, so I've sent it back to Dave Andreaes for checking.
With everyone's assistance I've written the rough code, so I'm now treading water until I get the thing back.
Thanks David Young
I assume that the one object is called 60% means from a 100 loops within 60 loops the object should be called
averaged every 1,667 loops the object should be called REGULARLY ?
this could be realised with the bresenham-algorythm.
it was developed for drawing lines with any kind of angle on a screen at high speed
the algorytm does only addition and substraction if integers and because of this it is fast.
It is very useful for CNC-controls too if you want two axis move at the same time with different speeds
best regards
Stefan