Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Newcomers DBPro Corner / Coin tossing bug

Author
Message
Geoff
16
Years of Service
User Offline
Joined: 10th Jul 2007
Location: Sheffield (U.K.)
Posted: 18th Dec 2013 17:57
I have just completed a program that simulates tossing a coin until eventually, a run of 10 heads occurs.
It seems to work just fine, BUT if I run the program several times in succession, it frequently repeats numbers more often than could be due to chance.

Any ideas, please?
Regards, Geoff.
LBFN
17
Years of Service
User Offline
Joined: 7th Apr 2007
Location: USA
Posted: 19th Dec 2013 01:50 Edited at: 22nd Dec 2013 09:35
Man, that is weird. It seems to like lowest/highest of 23/8185 a lot, and they follow one another.

I also tried printing out the value of timer() (when using it to seed the random generator) and the values did change, but the results did not. I also tried eliminating the randomize timer() command completely (you don't really need that in DBP anymore) and the results were the same. I also looked on the board for reporting bugs, but didn't see anything that was similar to this.

At this point, it seems like a bug in DBP, but perhaps someone else has run across this before and knows of a solution.

So many games to code.....so little time.
The Tall Man
10
Years of Service
User Offline
Joined: 16th Nov 2013
Location: Earth
Posted: 19th Dec 2013 04:53
You're using pseudo-random numbers, seeded by the value you get from Timer(). It could be you're getting the same seed value there most times you run. If that happens, then all the pseudo-random numbers will be identical with each successive run - that's the nature of pseudo-randomness.

To find this out, initialize a variable with the Timer(), and use that variable to Randomize. Then print that variable to see what it was.

Make sure that Timer is taking its reading from the system clock, rather than how long your program's been running.

Also, keep in mind that random numbers do produce non-random patters, called distributions.

You don't have to add 1 to the RND output, you can just check if the result is 0 or 1, rather than 1 or 2.

Q: ...you mean computer imagery was still based on the paradigm that the world was flat? Even into the 21st century??? Talk about doing something the hard way!

A: Yep! Back then people would render simple shapes with complex meshes of thousands of flat little triangles. Next to the bottleneck processors they used, it's the main reason why their computers were so slow. In the last days of the religious atmosphere of centralization and trade, corporate dogmas had people believing that flat was faster.
Geoff
16
Years of Service
User Offline
Joined: 10th Jul 2007
Location: Sheffield (U.K.)
Posted: 20th Dec 2013 12:42
Thankyou LBFN and Tall Man for your observations and suggestions.
I have experimented with using the system clock time as a seed number. But the old favourite repeating pairs continued to appear.
I am reasonably confident that my code is sound; I have tried it in Liberty Basic and Visual Basic 6 (boo!) and they both work without any weird repetitions.

I am now going to amuse myself by using an Array to observe if any repeaters are the predominant favourites.

Thanks again, Geoff.
Rudolpho
18
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 20th Dec 2013 17:08


That's the implementation of the rnd function in DBP.
I'm not sure why the multiplications are done as they are (maybe a single call to rand() was taken to return 0..(2^16 / 2)).
Still so, it most likely shouldn't produce repeating numbers as far as I can tell.


"Why do programmers get Halloween and Christmas mixed up?"
Geoff
16
Years of Service
User Offline
Joined: 10th Jul 2007
Location: Sheffield (U.K.)
Posted: 20th Dec 2013 18:18
Sorry, Rudolpho, my quaint old version 1.055 of DarkBasic Pro does not recognize your code.
I have tried several times to upgrade my DBpro , but I always get into a mess with the procedure involved, and am relieved when I recover my old friendly 1.055.
Thank you for your trouble.
Regards, Geoff.
Rudolpho
18
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 20th Dec 2013 21:03
Oh, no, that's the (C++) code used by DBP internally when you call the rnd built-in function.

All I meant is that it looks appropriate; you can assume that the C rand()-function isn't biased.

Quote: "my quaint old version 1.055 of DarkBasic Pro"

That may be your problem; that is a really old version (I think it's the one I have on my CD copy even!) - things may have been broken in older versions and fixed in later ones. Although I doubt the rng would have been broken just on accident.

Well, actually tyhat isn't your problem since I still get the same distributions with version 1.077.
I also checked to make sure timer returned the system time rather than the processing time of the application and indeed it did.

Since you're just looking for extremes, it *might* be that you call the function enough times that it goes through the entire pseudo-random number list and just about wraps around. In that case the extremes should be the same most of the times.


"Why do programmers get Halloween and Christmas mixed up?"
The Tall Man
10
Years of Service
User Offline
Joined: 16th Nov 2013
Location: Earth
Posted: 21st Dec 2013 04:07 Edited at: 21st Dec 2013 04:29
Rudolpho, have you looked at the code for the Randomize command? It could be the seed value isn't getting through??

Not that this matters here, but that RND function will function up to 36.4 million though, not just 22 million.

Found this interesting video trashing rand(). I've used it lots (although never heavily relied on t), everyone's saying how bad it is... Maybe I'll switch to something else now...
http://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

Sounds like the mersenne_twister class is a lot faster than rand(). That's great, because I've found rand() to be pretty slow.

Edit:
Of course you can always just use true random numbers:
http://randomnumber.org/links.htm#DownloadableRandomNumbers

Q: ...you mean computer imagery was still based on the paradigm that the world was flat? Even into the 21st century??? Talk about doing something the hard way!

A: Yep! Back then people would render simple shapes with complex meshes of thousands of flat little triangles. Next to the bottleneck processors they used, it's the main reason why their computers were so slow. In the last days of the religious atmosphere of centralization and trade, corporate dogmas had people believing that flat was faster.
Rudolpho
18
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 21st Dec 2013 18:30
Randomize just wraps srand.

Of course it doesn't create true random numbers, but in most causes that's not necessary either. You'd think it would be common knowledge more than a video trashing (which there probably exists for just about anything ) if the standard library rng for C was broken. It also would most likely have been fixed, was that the case.


"Why do programmers get Halloween and Christmas mixed up?"
The Tall Man
10
Years of Service
User Offline
Joined: 16th Nov 2013
Location: Earth
Posted: 22nd Dec 2013 02:17 Edited at: 22nd Dec 2013 02:19
Yeah I figured that The idea is - is the unique seed value getting into the srand().?

It's not just some random trash-talk; I wouldn't have bothered with that. The video is by a Microsoft guy - Did you notice the link was to their site? ...trashing their own library! And it's not that rand() is broken, it isn't. It's just not well implemented. But I don't think that the above code would suffer, I don't think rand() shouldn't be repeating ~that~ often.

Q: ...you mean computer imagery was still based on the paradigm that the world was flat? Even into the 21st century??? Talk about doing something the hard way!

A: Yep! Back then people would render simple shapes with complex meshes of thousands of flat little triangles. Next to the bottleneck processors they used, it's the main reason why their computers were so slow. In the last days of the religious atmosphere of centralization and trade, corporate dogmas had people believing that flat was faster.
Phaelax
DBPro Master
21
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 22nd Dec 2013 08:12
Quote: "can produce 0, 1 or 2"

How do you figure result = Rnd(1)+1 can ever produce 0?


Curious, but what are the most common set of numbers you guys are seeing be produced?

low - high
23 - 8185
46 - 15281


Just to note, if you move the randomize call to within the FOR loop, you'll use a different seed for each trial. And in doing so, I haven't seen any repeated outcomes yet.

LBFN
17
Years of Service
User Offline
Joined: 7th Apr 2007
Location: USA
Posted: 22nd Dec 2013 09:35
Quote: "Quote: "can produce 0, 1 or 2"
How do you figure result = Rnd(1)+1 can ever produce 0?"


It doesn't. Mistake on my part.

So many games to code.....so little time.
Geoff
16
Years of Service
User Offline
Joined: 10th Jul 2007
Location: Sheffield (U.K.)
Posted: 22nd Dec 2013 11:00
I'm Geoff (the originater of this query)
It is pleasing that my query has generated some interest from coders who are obviously way beyond my level.

Phaelax, I'm still not sure how to seed Randomize, could you please post a message containing my code as amended by yourself.
Thanks in anticipation, Geoff.
luskos
16
Years of Service
User Offline
Joined: 28th Jun 2007
Location:
Posted: 22nd Dec 2013 11:40
Just move Randomize Timer() within the For Next loop.Like this:


Most common numbers that i get are: 23 - 8185, 46 - 15281
Make few experiments.I get often same numbers only while using Repeat Until condition.

Coding is My Kung Fu!
And My Kung Fu is better than Yours!
Phaelax
DBPro Master
21
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 24th Dec 2013 04:15
I had a theory based on if other people had the same numbers coming up as me, but now I forget what that theory was.

Rudolpho
18
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 25th Dec 2013 11:55 Edited at: 25th Dec 2013 11:57
Quote: "Just move Randomize Timer() within the For Next loop"

That isn't very smart at all; if the loop runs fast enough that will definitively repeat most if not all of the pseudo-random series over and over on account of the seed value being the same / just progressing by one every now and then

@Phaelax: Yes, I do get 23 and 8185 very commonly (> 50% of the time).
46 and 15281 also occurs, but not as often as 56 and 8597.


You can try this to get a different random distribution; it doesn't seem to yield the same numbers repeatedly. It is quite a bit slower however (it can be speed up greatly by pre-allocating the 16 bytes rather than doing it and freeing them for every call):



"Why do programmers get Halloween and Christmas mixed up?"
Geoff
16
Years of Service
User Offline
Joined: 10th Jul 2007
Location: Sheffield (U.K.)
Posted: 25th Dec 2013 13:03
Sorry,Rudolpho,my quaint old version 1.055 of DarkBasic Pro does not recognize your code.

Thank you for your trouble.
Regards, Geoff.
The Tall Man
10
Years of Service
User Offline
Joined: 16th Nov 2013
Location: Earth
Posted: 25th Dec 2013 16:07
I think the RND will be far more reliable than looking into memory like that. And since you free it before you look at it, you may get some run-time exceptions.

Q: ...you mean computer imagery was still based on the paradigm that the world was flat? Even into the 21st century??? Talk about doing something the hard way!

A: Yep! Back then people would render simple shapes with complex meshes of thousands of flat little triangles. Next to the bottleneck processors they used, it's the main reason why their computers were so slow. In the last days of the religious atmosphere of centralization and trade, corporate dogmas had people believing that flat was faster.
Rudolpho
18
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 25th Dec 2013 16:23
@Geoff: Try this then, I can't say for sure, but might work with that version:


Quote: "I think the RND will be far more reliable than looking into memory like that."

Since CoCreateGuid "guarantees" to generate a unique id for each call, it should do very well for producing random numbers (since that is most likely what it is based on to begin with).

Quote: "And since you free it before you look at it, you may get some run-time exceptions."

Where exactly did I do that?


"Why do programmers get Halloween and Christmas mixed up?"
The Tall Man
10
Years of Service
User Offline
Joined: 16th Nov 2013
Location: Earth
Posted: 25th Dec 2013 16:54
My mistake about the exception. You freed it only if the DLL fails, and then exit in that case. I didn't realize about the specific DLL, so never mind what I said then! Still... how do you know what algorithm it uses. Just because it's unique from one call to the next during run-time, doesn't mean it'll not output the same numbers the next run-time. Anyway - worth an experiment at least!

If there is uniqueness from run-time to run-time, it could be combined with the RND to be sure the randomness is more unique. XOR makes a great way to combine them. In C, the XOR operator is ^

And keep in mind there's only 1 bit needed for the random output.

Q: ...you mean computer imagery was still based on the paradigm that the world was flat? Even into the 21st century??? Talk about doing something the hard way!

A: Yep! Back then people would render simple shapes with complex meshes of thousands of flat little triangles. Next to the bottleneck processors they used, it's the main reason why their computers were so slow. In the last days of the religious atmosphere of centralization and trade, corporate dogmas had people believing that flat was faster.
Rudolpho
18
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 25th Dec 2013 17:23
Yes, my selection of bytes from the guid structure is completely arbitrary and could probably be done better (for instance parts of all 16 bytes could be included).

Quote: "Still... how do you know what algorithm it uses. Just because it's unique from one call to the next during run-time, doesn't mean it'll not output the same numbers the next run-time."

GUID stands for globally unique identifier; its purpose is to be unique enough to be used for online verifications, meaning countless runs on countless different machines are unlikely to produce the same identifier. This description hints that it selects bytes randomly, otherwise it would have to consult some database to request a free id, which it evidently does not.


"Why do programmers get Halloween and Christmas mixed up?"
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 1st Jan 2014 14:18 Edited at: 1st Jan 2014 14:21


Awesome, video embedding works!
You will need to be on the beta forum to see it. (Just add "beta" to the front of any forum url.)
Check out the forum updates thread.


Formerly OBese87.

Login to post a reply

Server time is: 2024-04-19 23:43:18
Your offset time is: 2024-04-19 23:43:18