Comment MathRand() génère-t-il des valeurs ? - page 2

 
yu-sha:

Veuillez me dire comment MathRand() obtient des valeurs.

Peut-on s'attendre à ce que MathRand() soit distribué uniformément dans l'intervalle déclaré ?

voici un exemple, il existe bien sûr d'autres algorithmes plus complexes...

source rand.c :

/***
*rand.c - random number generator
*
*       Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
*
*Purpose:
*       defines rand(), srand() - random number generator
*
*******************************************************************************/

#include <cruntime.h>
#include <mtdll.h>
#include <stddef.h>
#include <stdlib.h>

#ifndef _MT
static long holdrand = 1 L;
#endif  /* _MT */

/***
*void srand(seed) - seed the random number generator
*
*Purpose:
*       Seeds the random number generator with the int given.  Adapted from the
*       BASIC random number generator.
*
*Entry:
*       unsigned seed - seed to seed rand # generator with
*
*Exit:
*       None.
*
*Exceptions:
*
*******************************************************************************/

void __cdecl srand (
       unsigned int seed
       )
{
#ifdef _MT

       _getptd()->_holdrand = (unsigned long)seed;

#else  /* _MT */
       holdrand = (long)seed;
#endif  /* _MT */
}


/***
*int rand() - returns a random number
*
*Purpose:
*       returns a pseudo-random number 0 through 32767.
*
*Entry:
*       None.
*
*Exit:
*       Returns a pseudo-random number 0 through 32767.
*
*Exceptions:
*
*******************************************************************************/

int __cdecl rand (
       void
       )
{
#ifdef _MT

       _ptiddata ptd = _getptd();

       return( ((ptd->_holdrand = ptd->_holdrand * 214013 L
           + 2531011 L) >> 16) & 0x7fff );

#else  /* _MT */
       return(((holdrand = holdrand * 214013 L + 2531011 L) >> 16) & 0x7fff);
#endif  /* _MT */
}
 

Une fonction RNG est requise avec le nombre Int de 0 à n'importe quelle valeur.

Puisque la valeur maximale de Int =2147 483 647, nous calculons jusqu'à elle.

Nous avons obtenu cette fonction. Je pense que la distribution est uniforme.

int RandomInteger(int max_vl){//случайное Int от 0 до  Max Int
        //srand(0);//если нужна повторяемость.  MathSrand(GetTickCount()) если нужна неповторяемость
        int r=MathRand();// от 0 до 32767.
        double k=32767.0;
        if(max_vl>32767){
                r=r+MathRand()*32767;//0...32767 + 0.. 32767*32767(с шагом 32767)  max=1073709056 > 1 mlrd
                k=k*k;
                if(max_vl>1073709056){// int type max alue =2 147 483 647 > 2 mlrd
                        r=r*2+MathRand()%2;//0...2 147 483 647 > to max int number c шагом 2 + (0 или 1)
                        k=k*2;
                }
        }
        return (int)MathFloor(r/k*max_vl);
}
 
L'article a un générateur à 4294967295
 
Rorschach:
L'article a un générateur jusqu'à 4294967295

Alglib SB possède un oscillateur de haute précision

UPD : J'ai essayéhttps://www.mql5.com/ru/forum/324066#comment_13500222 , cela semble fonctionner, mais il n'y a pas de documentation pour Alglib dans MQL5, vous devriez la lire sur le site web d'Alglib.

 
Rorschach:
L'article a un générateur à 4294967295

Merci, je l'ai comparé en termes de vitesse de calcul.
Ma fonction sur le standard rand() s'est avérée être 2 fois plus lente. Bien que le code semblait beaucoup plus simple...


 
Igor Makanu:

Alglib SB possède un oscillateur de haute précision

UPD : J'ai essayéhttps://www.mql5.com/ru/forum/324066#comment_13500222 , cela semble fonctionner, mais il n'y a pas de documentation pour Alglib dans MQL5, vous devriez la lire sur le site web d'Alglib.

Je l'ai vu mais je le veux sans alglib. De plus, cette fonction a beaucoup de */%. Je n'ai pas comparé sa vitesse puisqu'elle est évidemment plus lente. Le générateur de l'article fonctionne avec des décalages de bits - c'est plus rapide.

 

Réécriture de ma fonction pour optimiser la vitesse :

int RandomInteger(int max_vl){return (int)MathFloor((MathRand()+MathRand()*32767.0)/1073741824.0*max_vl);}//случайное Int от 0 до  Max Int
La distribution s'est avérée être uniforme. Voir les images de l'expérience sur le blog https://www.mql5.com/ru/blogs/post/735953.

J'ai réécrit le RNG à partir de l'article.
J'ai jeté les choses inutiles, et voilà ce que j'ai obtenu :

//если из define переместить в код RNDUint, то скорость работы увеличится на 30% для 10 млн повторов с 600 мс до 850 мс
#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 RNDUint{
protected:
   uint      x,y,z,w,xx,t;
public:
        RNDUint(void){inidat;};
        ~RNDUint(void){};
   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;}
   };
};

La distribution s'est également avérée être uniforme.

J'ai comparé la vitesse des deux fonctions, l'originale de l'article et la simple MathRand() :


L'original de l'article rnd.Rand_01() - 602 ms.
Raccourci selon l'article rnu.Rand_01() - 596 ms
Ma version optimisée de RandomInteger() - 840 ms (ancienne version 1200 ms, c'est-à-dire 25% plus rapide)
Juste par MathRand() - 353 ms (le plus rapide, mais la distribution sera inégale. Si la plage de nombres requise est supérieure à 32767, le résultat sera ignoré. Si elle est inférieure à 32767, par exemple i=31111. alors les arrondis seront plus fréquents à certains points).

Profitez-en)
Rand 0 ... Max Int с равномерным распределением
Rand 0 ... Max Int с равномерным распределением
  • www.mql5.com
Потребовалась функция ГСЧ с гнерацией числа Int от 0 до любого значения.Получилась такая функция. Думаю распределение получилось равномерным. int RandomInteger(int max_vl){return
 
elibrarius:
Intéressant. J'ai trouvé un autre hasard dans la bibliothèque standard, mais il est peu probable qu'il soit meilleur.
 

Pourquoi compliquer les choses à ce point ?

Vous pouvez procéder de la manière suivante (en gros) :

if (MathRand()%100>50) => Buy

if (MathRand()%100<50) => Sell

Et si vous voulez jouer avec ou voir ce qu'il montre, vous pouvez le faire :

int x=1;

if (MathRand()%100>50) x=1;

if (MathRand()%100<50) x=2;

Comment(x);

et voir comment cela change les valeurs.

 
elibrarius:

J'ai réécrit ma fonction pour optimiser la vitesse :

La distribution est régulière. Voir les images de l'expérience sur le blog https://www.mql5.com/ru/blogs/post/735953.

J'ai réécrit le RNG à partir de l'article.
J'ai jeté les choses inutiles et c'est ce que j'ai obtenu :

La distribution s'avère également uniforme.

Je l'ai comparé avec la distribution de l'aide, je ne vois pas de différence.

Dossiers :
Raison: