MathRand()はどのように値を生成するのですか? - ページ 3

 


比較のために
MathRandomUniformを スクリプトに追加してみましたポイント生成を1000000に設定 しました。分布を推定するために、1000000個の点をすべて1000×1000の正方形として画面に表示します。ポイントを打つ回数が多いほど、その色は鮮やかになります。
RNGの繰り返しを1000万回に設定 したので、平均して各ドットに10回当たるはずです。

以下はその結果である。
RNDです。


RandomIntegerの私の変形版です。


MathRand()について。


MathRandomUniform()にて


最初の2つのRNDは全く均等で、3と4はギャップがあり、つまり均等ではありません。
スキップは、MathRand resolution = 32767によるものです。 1000000の倍率の場合、1000000/32767=30点のスキップを得ることができる。MathRandomUniform はイメージ的に似ていて、おそらく、同じ30スキップを持って いると思います。

もう一つのバリエーション。最大値を30000としよう。
RNDと RandomIntegerは、あたかも100万のように等しい MathRand と MathRandomUniform は次のようになります(チャンクを拡大したもの)。


ギャップはありません(位置30000までの黒点)。しかし、中には明るさが際立つものもあります。30000/32767の四捨五入の不揃いです。11個目のドットごとにヒット数が2倍になる。

MathRandを最大3000にすると、何か均一なものが得られる...4000.


最初の2つは,RandomInteger 分解能 約10億)なら1億個 ,RNDなら40億 個と最大数に近づくと 丸めの関係で分布が不揃いになって きます.

ファイルを添付しましたので、実験を繰り返してください。
私は自分自身のために独自の関数を使用することにしました、それはRNDよりも25%遅いが、よりコンパクトで明確です、私はより多くの32767倍まで解像度を増やすことができます、ブログで
コードを参照してください。



記事からRND開発者が指摘したのは

seed=0 のとき、この関数は初期値をランダムに変更する。

再起動の度にseed=0にしましたが、再起動の度に分布のある絵は変わりません。すなわち、この文は誤りである。なぜランダムになるのかも、コードからはわかりません。そのため、ランダムに初期化するには、seed=GetTickCount() のように乱数を設定する必要があります。

RandomInteger()関数については、再起動の際にポイントの再分配が見られる。srand(0);を設定すると、再起動の際にも配信が繰り返されるようになります。つまり、この関数がランダムに初期化されるためには、srand を呼び出さないか、タイムスタンプも含めてMathSrand(GetTickCount()) を使う必要があります。

ファイル:
 

xor128 は特別なランダム性テストに合格しており、標準的な rand では

トレーディング、自動売買システム、ストラテジーテストに関するフォーラム

トレーディングにおける機械学習:理論、実践、トレーディングとその先へ

ロールシャッハ さん 2020.04.19 22:18

私は便利屋です、RSCHを壊しました((

#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通り:wは2のべき乗、kは4の倍数でなければならない

方法2:srandのコメントを解除する

方法2は、メルセン渦にも有効なはずです

 
Rorschach:

xor128 は特別なランダム性テストに合格しており、標準的な rand であれば



16回目のランドコールごとに表示していますね。この周期性から何らかのパターンが見えてくる。
すべて2本ずつの連続通話で使用しています。目視では、私の写真を見る限り、1000万回の繰り返しでxor128との差は見られません。
 
Rorschach:

xor128 は特別なランダム性テストに合格しており、標準的な rand であれば


自作の関数にxor128を代入してみたところ

#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()には、いくつかの割り算もあります。
xor128では良くなったが、バンディングがある。

通常の使用では(16分の1ではない)RandomInteger()のこのダッシュが効果を発揮するとは思えませんが...。しかも、その意味がよくわからない...。

でも、xor128の方が信頼性が高いと思います。

 
Rorschach:

xor128 は特別なランダム性テストに合格しており、標準的な rand であれば


Mersenのコードはありますか?OpenCLではどこかにあったのですが、MQL5への移植はできていません。比べてみると面白いかもしれませんね。

方法2は、Mersenの渦にも有効なはずです


 
Rashid Umarov:

Mersenのコードはありますか?OpenCLではどこかにあったのですが、MQL5への移植はできていません。比べてみると面白いかもしれませんね。

ここで、私自身は使ったことがない。

 
elibrarius:

16回目の呼び出しごとにランドを表示するんですね。この周期性から何らかのパターンが見えてくる。
すべて2本ずつの連続通話で使用しています。 目視では、私の写真を見る限り、1000万回の繰り返しでxor128との差は見られません。

使用目的が分からないので、驚きがあるかもしれないという警告だけです。

 
Rorschach:

ここで、私自身は使ったことがない。

ありがとうございます!OpenCLのときよりもコードが大きくなっていることがわかりました。今度、考えてみますね。

 

ter.ver、整数の魔法、丸め、モジュールの演算、ダブルのトリックについて親しみやすく解説しています :-)

f(x) :: 整数が (0;N) 上に一様 分布する場合、 g(x)=N/(double)f(x) が (0;1) 上に一様分布するわけではなく、また全てのテストに合格するわけではありません。

g(x) = f(x) mod Mについてもほぼ同様で、まれにN mod M = 0という例外があります。

ちなみにPS/とg(x)=f(x)/(double)Nも一様ではないでしょう。分裂の焦点は存在する。つまり、プロットにはモアレが発生する。

PPS/ランダム性の視覚的な「テスト」として、モジュロ・ブラント・スクエアに加え、「ウラム・スネイル」のバリエーションが適用されています。

 
Rorschach:

ここで、私自身は使ったことがない。

このコードからCRandomMersenneとCRandomMotherの性能を測定した。xor128の3倍遅いんです。これでは、とてもじゃないが満足できない。しかし、あなたがGSFを壊したコードによると、それらはxor128(縦棒なし)よりも良く見えます。

理由: