MathRand() nasıl değerler üretir? - sayfa 3

 

Senaryomda karşılaştırma için eklendi MatematikRastgeleÜniforma
Puan oluşturmayı 1000000'e kadar ayarladım. Dağılımı değerlendirmek için 1000000 noktanın hepsini 1000*1000 kare şeklinde ekranda gösteriyorum. Bir noktaya ne kadar çok RNG çarparsa, rengi o kadar parlak olur.

Ortalama olarak 10 milyon RNG tekrarı ayarladım , her nokta 10 kez vurmalıdır.

Sonuçlar burada:
RND:


RandomInteger seçeneğim:


MathRand() üzerinde:


Üzerinde MathRandomÜniforma ():


İlk iki RNG oldukça üniform, 3 ve 4 boşluklu, yani. düzensiz.
Boşluklar MathRand = 32767 çözünürlüğünden kaynaklanmaktadır. 1000000 çarpanıyla 1000000/32767=30 puanlık boşluklar elde ederiz. MathRandomUniform , resimde benzer, görünüşe göre 30 birimlik aynı boşluklar.

Başka bir varyant. Maksimum sayıyı 30000 olarak ayarlayalım.
RND ve RandomInteger, bir milyonda olduğu gibi aynıdır. Matematik Rand ve MatematikRastgeleÜniforma şuna benziyor (daha büyük bir parçayla):


Boşluk yok (siyah noktalar 30000 konumuna kadar). Ancak bazıları belirgin şekilde daha parlaktır. Bu, 30000/32767'nin yuvarlama eşitsizliğidir. Her 11 puan, iki kat daha fazla isabet alır.

Üniforma bir şey elde edilebilir MathRand maksimum 3000...4000'de. İşte 3500 için büyütülmüş bir versiyon:


İlk iki seçenek,
RandomInteger ( yaklaşık 1 milyar çözünürlüğe sahip) için maksimum sayı 100 milyona ve RND için 4 milyar çözünürlükte 400 milyona yaklaştığında da yuvarlamadan dolayı eşit olmayan bir şekilde dağılmaya başlayacaktır.

Dosya ektedir, deneyi tekrarlayabilirsiniz.
Kendi işlevimi kendim için kullanmaya karar verdim, RND'den %25 daha yavaş, ancak daha kompakt ve daha net, çözünürlüğü 32767 kat daha artırabilirsiniz, blogdaki koda bakın.


Not:
Makaledeki RND geliştiricisi şunu belirtti:

Seed=0 ile fonksiyon başlangıç değerlerini rastgele değiştirir.

Her yeniden başlatmada, tohum = 0 olarak ayarladım, ancak yeniden başlatmalar sırasında dağılımların olduğu resim değişmiyor. Onlar. ifade yanlış. Kod ayrıca neden rastgele olması gerektiğini de göstermiyor. O. rastgele başlatma için, tohum rastgele bir sayıya ayarlanmalıdır, örneğin tohum= GetTickCount();

RandomInteger() işlevi için, yeniden başlatmalarda noktaların yeniden dağıtımı görünür. srand(0) ayarlarsanız; daha sonra yeniden başlatmalarda dağıtım da tekrar etmeye başlar. Onlar. bu işlev için, rastgele başlatma için, ya srand'ı ya da MathSrand(GetTickCount()) zaman damgasını çağırmamalısınız.

Dosyalar:
 

Lütfen xor128'in rastgelelik için özel testlerden geçtiğini ve standart rand ile olabileceğini unutmayın.

Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum

Ticarette makine öğrenimi: teori, uygulama, ticaret ve daha fazlası

Rorschach , 2020.04.19 22:18

Ben bir işleyiciyim, RNG bozuldu (((

 #include <Canvas\Canvas.mqh>
void OnStart ()
  {CCanvas C;
   int h= 1024 ;
   int w= 2048 ;
   C.CreateBitmapLabel( "11" , 100 , 100 ,w,h);
   for ( int y= 0 ;y<h;y++)
     { //srand(GetMicrosecondCount());
       for ( int x= 0 ;x<w;x++)
        { uchar c= 0 ;
         for ( int k= 0 ;k< 16 ;k++)
           {c= uchar ( 255 .* rand ()/ 32767 .);
           }
         C.PixelSet(x,y,ARGB( 255 ,c,c,c));
        }
     }
   C.Update();

1 yol: w 2'nin kuvveti olmalı, k 4'ün katıdır

Yöntem 2: uncomment srand

Yöntem 2 ayrıca Mersen Vorteksinde de çalışmalıdır.

 
Rorschach :

Lütfen xor128'in rastgelelik için özel testlerden geçtiğini ve standart rand ile olabileceğini unutmayın.



Her 16. aramayı Rand ile eşleştirirsiniz. Bu periyodiklikten gelen düzenliliğin ne olduğu gösterilir.
Tüm aramaları arka arkaya, her birinde 2 tane kullanıyorum. Görsel olarak, resimlerime göre, 10 milyon tekrar için xor128 ile bir fark görmüyorum.
 
Rorschach :

Lütfen xor128'in rastgelelik için özel testlerden geçtiğini ve standart rand ile olabileceğini unutmayın.


Kendi işlevimi ve xor128'i işlevinize değiştirmeye çalıştım

#include <Canvas\Canvas.mqh>
void OnStart()
  {CCanvas C;
  RND rn;   rn.SRand(0);
   int h=1024;
   int w=2048;
   C.CreateBitmapLabel("11",100,100,w,h);
   for(int y=0;y<h;y++)
     {//srand(GetMicrosecondCount());
     rn.SRand(GetMicrosecondCount());
      for(int x=0;x<w;x++)
        {uchar c=0;
         for(int k=0;k<16;k++)
           //{c=uchar(255.*rand()/32767.);}
           //{c=uchar(255.*RandomInteger(1073741824)/1073741824.0); }
           {c=(uchar)(255.0*rn.Rand_01()); }
         C.PixelSet(x,y,ARGB(255,c,c,c));
        }
     }
   C.Update();
   }
  
   int RandomInteger(int max_vl){return (int)MathFloor((MathRand()+MathRand()*32767.0)/1073741824.0*max_vl);}//случайное Int от 0 до  1073741824


//если из define переместить в код RNDUint, то скорость работы увеличится на 30% для 10 млн повторов с 600 мс до 850 мс. Это почти как RandomInteger()

#define xor32  xx=xx^(xx<<13);xx=xx^(xx>>17);xx=xx^(xx<<5)
#define xor128 t=(x^(x<<11));x=y;y=z;z=w;w=(w^(w>>19))^(t^(t>>8))
#define inidat x=123456789;y=362436069;z=521288629;w=88675123;xx=2463534242

class RND{
protected:
   uint      x,y,z,w,xx,t;
public:
      RND(void){inidat;};
    ~RND(void){};
   uint      RandMaxUI(uint max_v)   {xor128;return((uint)MathFloor((double)w/UINT_MAX*max_v));};//равномерное распределение на отрезке [0,max_v]. uint
   int       RandMaxI(int max_v)     {xor128;return((int) MathFloor((double)w/UINT_MAX*max_v));};//равномерное распределение на отрезке [0,max_v]. int
   uint      Rand()    {xor128;return(w);};//равномерное распределение на отрезке [0,UINT_MAX=4294967295].
   double    Rand_01() {xor128;return((double)w/UINT_MAX);};//равномерное распределение на отрезке [0,1].
   void      Reset()   {inidat;};//сброс всех исходных значений в первоначальное состояние.
   void      SRand(uint seed)  {//установка новых исходных значений генератора.seed= [0,UINT_MAX=4294967295]. При seed=0 функция меняет начальные значения случайным образом.
      int i;if(seed!=0){xx=seed;}for(i=0;i<16;i++){xor32;}xor32;x=xx;xor32;y=xx;xor32;z=xx;xor32;w=xx;for(i=0;i<16;i++){xor128;}
   };
};


RandomInteger() ile de bazı hileler var.
xor128 ile daha iyi, ancak bir tür grup var:

Genel olarak, normal kullanımda (ve 16'dan 1'i değil) RandomInteger'den () bu boşanmaların bir şekilde etkileyeceğinden emin değilim ... Ve ne anlama geldikleri açık değil ...

Ancak belki de xor128'in kullanımı daha güvenilirdir.

 
Rorschach :

Lütfen xor128'in rastgelelik için özel testlerden geçtiğini ve standart rand ile olabileceğini unutmayın.


Mersen kodunuz var mı? OpenCL'de bir yerim vardı, ellerim MQL5'e geçmek için ulaşmadı. Karşılaştırmak ilginç olurdu.

Yöntem 2 ayrıca Mersen Vorteksinde de çalışmalıdır.


 
Rashid Umarov :

Mersen kodunuz var mı? OpenCL'de bir yerim vardı, ellerim MQL5'e geçmek için ulaşmadı. Karşılaştırmak ilginç olurdu.

Burada , kendim kullanmadım.

 
elibrarius :

Her 16. aramayı Rand ile eşleştirirsiniz. Bu periyodiklikten bu düzenliliğin ne olduğu gösterilir.
Tüm aramaları arka arkaya, her birinde 2 tane kullanıyorum. Görsel olarak, resimlerime göre, 10 milyon tekrar için xor128 ile bir fark görmüyorum.

Kullanım amacınız nedir bilmiyorum, sadece sürprizler olabileceğine dair bir uyarı.

 
Rorschach :

Burada , kendim kullanmadım.

Teşekkür ederim! Kodun OpenCL'den daha büyük olduğu ortaya çıktı. Bir şekilde çözmeye çalışacağım.

 

ter.ver.'de dostça popados, tamsayıların büyüsü, yuvarlama, modüler aritmetik ve çift hileler :-)

f(x) :: tamsayı eşit olarak dağıtılırsa (0;N] bu, g(x)=N/(double)f(x)'in (0;1] üzerinde eşit olarak dağıtılacağı ve aynı zamanda tümünü geçeceği anlamına gelmez. testler.

g(x) = f(x) mod M için hemen hemen aynı, nadir istisna N mod M = 0.

PS/ Bu arada, g(x)=f(x)/(double)N de tek tip olmayacaktır. Bölme hileleri olacak. Yani, hareli grafiklerde görünecektir.

PPS / rastgelelik için görsel bir "test" için, bir künt kare moduloya ek olarak, "Ulam salyangozu" varyasyonları kullanılır

 
Rorschach :

Burada , kendim kullanmadım.

CRandomMersenne ve CRandomMother'ın performansını bu koddan ölçtüm. xor128'den 3 kat daha yavaştırlar. Bu pek hoş değil. Ancak kodunuza göre, RNG'yi kırdığınız yer, xor128'den daha iyi görünüyorlar (dikey çubuk yok).