Wie erzeugt MathRand() Werte? - Seite 2

 
yu-sha:

Bitte sagen Sie mir, wie MathRand() Werte erhält.

Kann man erwarten, dass MathRand() gleichmäßig im angegebenen Bereich verteilt ist?

Hier ist ein Beispiel, natürlich gibt es auch andere, komplexere Algorithmen...

Quelle 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 */
}
 

Es wird eine RNG-Funktion mit der Zahl Int von 0 bis zu einem beliebigen Wert benötigt.

Da der Höchstwert von Int =2.147.483.647 ist, rechnen wir bis zu diesem Wert.

Wir haben diese Funktion erhalten. Ich denke, die Verteilung ist gleichmäßig.

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);
}
 
Der Artikel hat einen Generator für 4294967295
 
Rorschach:
Der Artikel hat einen Generator bis zu 4294967295

Alglib SB hat einen hochpräzisen Oszillator

UPD: Ich habe es ausprobierthttps://www.mql5.com/ru/forum/324066#comment_13500222 , es scheint zu funktionieren, aber es gibt keine Dokumentation für Alglib in MQL5, Sie sollten es auf der Alglib Website lesen

 
Rorschach:
Der Artikel hat einen Generator für 4294967295

Danke, ich habe es in Bezug auf die Berechnungsgeschwindigkeit verglichen.
Meine Funktion auf Standard rand() erwies sich als 2-mal langsamer. Obwohl der Code viel einfacher zu sein schien...


 
Igor Makanu:

Es gibt einen hochpräzisen Generator in Alglib

UPD: Ich habe es ausprobierthttps://www.mql5.com/ru/forum/324066#comment_13500222 , es scheint zu funktionieren, aber es gibt keine Dokumentation für Alglib in MQL5, Sie sollten es auf der Alglib Website lesen

Ich habe es gesehen, aber ich möchte es ohne alglib. Außerdem enthält diese Funktion eine Menge */%. Ich habe seine Geschwindigkeit nicht verglichen, da er offensichtlich langsamer ist. Der Generator aus dem Artikel arbeitet mit Bitverschiebungen - er ist schneller.

 

Ich habe meine Funktion umgeschrieben, um die Geschwindigkeit zu optimieren:

int RandomInteger(int max_vl){return (int)MathFloor((MathRand()+MathRand()*32767.0)/1073741824.0*max_vl);}//случайное Int от 0 до  Max Int
Die Verteilung erwies sich als gleichmäßig. Bilder des Experiments finden Sie im Blog https://www.mql5.com/ru/blogs/post/735953

Ich habe den RNG aus dem Artikel umgeschrieben.
Ich habe Unnötiges weggeworfen, und das ist das, was ich bekommen habe:

//если из 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;}
   };
};

Auch die Verteilung war gleich.

Ich habe die Geschwindigkeit der beiden Funktionen verglichen, das Original aus dem Artikel und die einfache MathRand():


Das Original aus dem Artikel rnd.Rand_01() - 602 ms
Gekürzt nach dem Artikel rnu.Rand_01() - 596 ms
Meine optimierte Version von RandomInteger() - 840 ms (alte Version 1200 ms, d.h. 25% schneller)
Nur durch MathRand() - 353 ms (am schnellsten, aber die Verteilung wird ungleichmäßig sein. Wenn der erforderliche Zahlenbereich größer als 32767 ist, wird das Ergebnis übersprungen. Wenn weniger als 32767, z. B. i=31111. dann wird häufiger auf einige Punkte gerundet).

Nutzen Sie den Vorteil)
Rand 0 ... Max Int с равномерным распределением
Rand 0 ... Max Int с равномерным распределением
  • www.mql5.com
Потребовалась функция ГСЧ с гнерацией числа Int от 0 до любого значения.Получилась такая функция. Думаю распределение получилось равномерным. int RandomInteger(int max_vl){return
 
elibrarius:
Interessant. Ich habe in der Standardbibliothek einen anderen Zufallswert gefunden, der aber wahrscheinlich nicht besser ist.
 

Warum die Dinge so kompliziert machen?

Sie können es so machen (grob gesagt):

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

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

Und wenn Sie etwas herumspielen oder sehen wollen, was es zeigt, können Sie dies tun:

int x=1;

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

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

Comment(x);

und sehen Sie, wie sich die Werte ändern.

 
elibrarius:

Ich habe meine Funktion umgeschrieben, um die Geschwindigkeit zu optimieren:

Die Verteilung ist gleichmäßig. Sehen Sie sich die Bilder des Experiments auf dem Blog https://www.mql5.com/ru/blogs/post/735953 an.

Ich habe den RNG aus dem Artikel umgeschrieben.
Ich habe Unnötiges weggeworfen, und das ist es, was ich bekommen habe:

Die Verteilung ist ebenfalls einheitlich.

Ich habe es mit der Verteilung aus der Hilfe verglichen, ich sehe keinen Unterschied

Dateien:
Grund der Beschwerde: