Recent

Author Topic: randomize  (Read 16890 times)

ezlage

  • Guest
randomize
« on: October 05, 2016, 01:41:15 am »
Friends,

In some way, at some time, somewhere, someone told me that I should not use the command "randomize" more than once in the program.

This information is true? How do I know if the command has already been executed in the application?

Sorry by my poor english.
Thank you.
« Last Edit: October 05, 2016, 03:00:13 am by ezlage »

Eugene Loza

  • Hero Member
  • *****
  • Posts: 729
    • My games in Pascal
Re: randomize
« Reply #1 on: October 05, 2016, 07:03:12 am »
someone told me that I should not use the command "randomize" more than once in the program
The manual says:
Quote
Randomize initializes the random number generator of Free Pascal, by giving a value to Randseed, calculated with the system clock.
More detailed analysis shows:
Code: Pascal  [Select][+][-]
  1.   procedure randomize;
  2.   begin
  3.     randseed:=GetTickCount;
  4.   end;
So, basically you can use "randomzie" as often as you like. However... do you really need to? Once is perfectly enough.

(UPD) Hovwever... Yes. If I understand correctly GetTickCount (quote) "provides number of milliseconds since Windows was started". So, you get only ~58 millions random sequences per day of a normal software user who turns off the computer at night :) Basically if you "measure" 1-second long random number sequences you might get a repeat in a year or two. And if you repeat the experiment in special conditions (e.g. right after turning on the computer) you have a ~0.01% chance to catch a repeating combination if startred manually and much higher probability if started in autorun. If you call randomize again somewhere in an non-trivial place you might mixh those random sequences, so, basically you get absolutely unrepeatable combinations of random numbers.
But that doesn't make any practical sense, right?

So IMHO: If you don't need multiple randomize - don't do them. It'll just mess up your code without any good sense. If you accidentally or unavoidably have more than one randomize - don't care.
« Last Edit: October 05, 2016, 07:14:35 am by Eugene Loza »
My FOSS games in FreePascal&CastleGameEngine: https://decoherence.itch.io/ (Sources: https://gitlab.com/EugeneLoza)

useroflazarus

  • New Member
  • *
  • Posts: 23
Re: randomize
« Reply #2 on: October 05, 2016, 07:53:10 am »
for random seed you can use the local variables:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormActivate(Sender: TObject);
  2. var rndDouble : double;
  3. begin
  4.   Edit1.Text:=floattoStr(rndDouble);
  5. end;
  6.  

Every time it generate random value, for example:
DEC                                                    HEX
5,88763352687033E-297             026ECDCFFFFFFFFD
5,50401551648458E-297             026CCBFFFFFFFFFB
1,21524922083397E-296             027FCA700000001A
....
after it you can interpretate HEX as integer or calculate crc32 or other... :)

Thaddy

  • Hero Member
  • *****
  • Posts: 19175
  • Glad to be alive.
Re: randomize
« Reply #3 on: October 05, 2016, 08:02:19 am »
@useroflazarus
You seem to take advantage of a dirty stack. That is wrong. The local stack is dirty, yes, and appears to give random values, but in fact it is often deterministic.
Therefor it is not suitable as a random seed.
Apart from gettickcount,some processors, like the one in the RaspberryPi, modern intels too, are able to generate a hwrnd value that can be used as random seed and have (close to) indeterministic values.

What is worse, that code relies on specific compiler settings. E.g. try to compile with -Ct and that code is not random.
« Last Edit: October 05, 2016, 08:51:55 am by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

RAW

  • Hero Member
  • *****
  • Posts: 871
Re: randomize
« Reply #4 on: October 05, 2016, 01:39:07 pm »
I found this in an old Delphi-Book...
Code: Pascal  [Select][+][-]
  1. Procedure MyRandomize;
  2.  Begin
  3.   Randomize;
  4.   RandSeed:= ((RandSeed Shl 8) Or GetCurrentProcessID) Xor GetTickCount;
  5.  End;    
  6.  

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12865
  • FPC developer.
Re: randomize
« Reply #5 on: October 05, 2016, 02:27:47 pm »
Repeated seeding of randomize (besides being useless) can cause non uniform distributions of random results.

RAW

  • Hero Member
  • *****
  • Posts: 871
Re: randomize
« Reply #6 on: October 05, 2016, 03:08:07 pm »
Thanks a lot...
I need RANDOMIZE in my next program, so I decided to check if this is working better than the "normal" one.
Now I don't use it  :)

The explanation in the book was: ..without RANDOMIZE RANDSEED starts at zero...
(very old Delphi-Book)

Thaddy

  • Hero Member
  • *****
  • Posts: 19175
  • Glad to be alive.
Re: randomize
« Reply #7 on: October 05, 2016, 04:13:34 pm »
That's because randomness in computing has to be able to reproduce itself for e.g. statistical reasons.
Clearly not something your math teacher payed any attention to, even worse if it was your programming teacher..
(Grumpy mode again) >:D

Random means a distribution close to equal chance, white noise if you want.
The seed determines where it starts.
If you do not use a random seed, the distribution is still equal, but it is repeatable.
You actually need that.... Guess why?
(Actually the Mersenne twister in FPC  and other algorithms all output the same results given the same seed)
« Last Edit: October 05, 2016, 04:55:49 pm by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

Eugene Loza

  • Hero Member
  • *****
  • Posts: 729
    • My games in Pascal
Re: randomize
« Reply #8 on: October 05, 2016, 08:36:11 pm »
Hmm... and I've just came up with a simlar question.
Can I get TWO random seeds simultaneously running flawlessly in FPC without making some "my own random generation procedure"?

In detail:
I'm generating a map for a computer game based on random.
If I give the random equal random seed it'll generate equal maps (that's what I want).
BUT, there are a few parallel processes running like "generating..." and a random image, which uses random and therefore disrupts the random sequence of the map generation process.
Can I separate "random for map generation which has to strictly reproduce the random numbers sequence" and "everything else I don't care about"?

Or should I just write my own random number generator? E.g. Xorshift algorithm? I might even gain some performance boost :)
My FOSS games in FreePascal&CastleGameEngine: https://decoherence.itch.io/ (Sources: https://gitlab.com/EugeneLoza)

useroflazarus

  • New Member
  • *
  • Posts: 23
Re: randomize
« Reply #9 on: October 05, 2016, 08:55:19 pm »

Or should I just write my own random number generator? E.g. Xorshift algorithm? I might even gain some performance boost :)

https://en.wikipedia.org/wiki/Mersenne_Twister который используется в Lazarus достаточно быстрый, можно его алгоритм и использовать :)

Eugene Loza

  • Hero Member
  • *****
  • Posts: 729
    • My games in Pascal
Re: randomize
« Reply #10 on: October 05, 2016, 09:33:24 pm »
https://en.wikipedia.org/wiki/Mersenne_Twister который используется в Lazarus достаточно быстрый, можно его алгоритм и использовать :)
Можно, но xorshift кажется проще :) и мне, вообще говоря, не нужен "идеальный" генератор случайных чисел - они должны быть просто последовательностью чисел для генерации карты для компьютерной игры...

Yes. It's possible, but Xorshift seems much simpler and I don't really need ideal random distribution, just a random for my map generator:
Code: Pascal  [Select][+][-]
  1. var x,y,z,w: Cardinal;
  2.  
  3. procedure Xorshift_randomize;
  4. begin
  5.  randomize;
  6.  x:=random(maxint);
  7.  y:=random(maxint);
  8.  z:=random(maxint);
  9.  w:=random(maxint);
  10. end;
  11.  
  12. function xorshift:single;
  13. var t: Cardinal;
  14. begin
  15.   t:=x;
  16.   t:=t xor (t shl 11);
  17.   t:=t xor (t shr 8);
  18.   x:=y;
  19.   y:=z;
  20.   z:=w;
  21.   w:=w xor (w shr 19);
  22.   w:=w xor t;
  23.   result:=w/maxint/2;
  24. end;
My FOSS games in FreePascal&CastleGameEngine: https://decoherence.itch.io/ (Sources: https://gitlab.com/EugeneLoza)

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: randomize
« Reply #11 on: October 05, 2016, 10:14:56 pm »
Hmm... and I've just came up with a simlar question.
Can I get TWO random seeds simultaneously running flawlessly in FPC without making some "my own random generation procedure"?
You can use the fpc's own random() for multiple sets, but it involves on you managing multiple sets of randseed.

Code: Pascal  [Select][+][-]
  1. var
  2.   seeds: array of cardinal; // Use same type as randseed
  3.   currSet: integer;
  4.  
  5. function RandomSet(setN: integer): single;
  6. begin
  7.   if setN <> currSet then begin
  8.     seeds[currSet]:=randseed;
  9.     randseed:=seeds[setN];
  10.     currSet:=setN;
  11.   end;
  12.   result:=random;
  13. end;

Eugene Loza

  • Hero Member
  • *****
  • Posts: 729
    • My games in Pascal
Re: randomize
« Reply #12 on: October 05, 2016, 10:23:51 pm »
You can use the fpc's own random() for multiple sets, but it involves on you managing multiple sets of randseed
Thanks a lot! This one looks really nice!
My FOSS games in FreePascal&CastleGameEngine: https://decoherence.itch.io/ (Sources: https://gitlab.com/EugeneLoza)

Eugene Loza

  • Hero Member
  • *****
  • Posts: 729
    • My games in Pascal
Re: randomize
« Reply #13 on: October 05, 2016, 10:33:43 pm »
UPD: I've tested and XorShift algorithm above works 3.16 times faster than FPC random :)
My FOSS games in FreePascal&CastleGameEngine: https://decoherence.itch.io/ (Sources: https://gitlab.com/EugeneLoza)

ezlage

  • Guest
Re: randomize
« Reply #14 on: October 06, 2016, 01:29:13 pm »
So, basically you can use "randomzie" as often as you like. However... do you really need to? Once is perfectly enough.

No, I do not need to run it more than once. I can prevent the command to run for my class after having already been performed in another piece of code, just checking if the variable "RandSeed" is zero. So I wanted to know if I have to worry about the rest of the code of a program that uses my class.

So IMHO: If you don't need multiple randomize - don't do them. It'll just mess up your code without any good sense. If you accidentally or unavoidably have more than one randomize - don't care.

This helps me! Thank you, Eugene.

 

TinyPortal © 2005-2018