Принцып работы функции MathRand() ?

 

Думаю, будет интересно всем - http://virlib.eunnet.net/books/numbers/.

В начале семидесятых годов нашего двадцатого века американское космическое агентство NASA, получив от Конгресса США несколько миллиардов долларов, решило осуществить запуск исследовательского спутника на Юпитер. Спутник склепали, напичкали дорогостоящей аппаратурой, назвали "Пионер" (лектору в этом месте рекомендуется характерный жест правой рукой наискосок об лоб), и запустили вверх. Для успешного управления дальнейшим полетом увороченного агрегата, ежику понятно, необходимо было постоянно перерасчитывать его траекторию, корректируя ее от случайных возмущений и целя в Юпитер, который, между прочим, хоть и большой, но летает от нас на расстоянии более 100 миллионов километров, поэтому попасть в него ужасно трудно.

Знатоки знают, что для расчета подобных траекторий нужно решать систему дифференциальных уравнений, которую не то что решать, а даже и писать-то не хочется, настолько она сложна и огромна. Но Пионер-то уже летит, как фанера над Парижем, а Конгресс внимательно следит за расходом средств налогоплательщиков, поэтому специалисты NASA вынуждены считать эти чертовы многомерные интегралы, причем в режиме реального времени. "В режиме реального времени" – это означает, что интеграл надо успеть посчитать до того, как спутник улетит вместо Юпитера в деревню Пропадайлово.

Знатоки опять знают, что единственный известный сегодня быстрый способ вычисления таких интегралов с использованием ЭВМ — это метод Монте-Карло (а это такой город, в отличие от Бойля-Мариотта). Далее буду краток. Монте-Карлу нужно многократное случайное бросание точки в многомерную область. Электронная машина не умеет генерировать случайные числа, так как она работает по программе, написанной заранее на языке FORTRAN (помните, был такой). FORTRAN разработали специально для запуска пионеров и вставили в него датчик (от слова "давать") случайных чисел RND(n), который, работая по некоторой наспех созданной схеме, выдавал последовательность "квазислучайных" чисел из отрезка [0; 1], равномерно на нем распределенную. Все было здорово.

Беда началась тогда, когда эти "квазислучайные" числа начали объединять в пары, тройки, и т. д., чтобы получить координаты "случайной" точки многомерной области. RND(n) оказался составленным настолько неудачно, что 60% "случайных" точек из единичного квадрата на плоскости (всего-то двухмерная область !) попадали в его нижнюю половину (а это даже в боксе — неэтично)! Монте-Карло не сработал, спутник промазал мимо Юпитера всего на каких-то 20 миллионов километров, и несколько миллиардов долларов вылетели в трубу.

Мораль: когда теоретик-числовик из заоблачных высот на несколько минут спускается на землю для сообщения процедуры получения случайных чисел с помощью эффектной цепочки делений и взятия остатков, убейте его сразу — дешевле будет. Народохозяйственное применение теории чисел здесь очевидно: она должна выдать такую процедуру получения случайных чисел, чтобы мы могли спокойно и спутники запускать, и землю пахать, и напильники коллекционировать. Вывод: изучайте теорию чисел, восторгайтесь ее красотами, любуйтесь ею, как произведением искусства, но помните, что вопреки эпиграфу к этому введению из "Портрета Дориана Грея", всякое искусство где-нибудь и когда-нибудь приносит пользу. Читателей же, заинтересовавшихся машинным получением случайных чисел, отсылаю к уникальной и великолепной книжке Д. Кнута "Искусство программирования для ЭВМ", том 2 "Получисленные алгоритмы", глава 3 "Случайные числа". Увлекательное чтиво!

 

А вот теперь надо взять и проверить наш MathRand() (который является оберткой сишной функции) на квадрате, как в тексте выше... WWer, ты собираешься брать многомерные интегралы?

 

Эту тему я создал потому что функция MathRand() не работает так как бы мне этого хотелось, тоесть я эксперементальным путем хотел

вычислить вероятности разных событий ( например вероятнось того что расстояние между фигурами из 10 "1" или "0" подряд будет

на единицу меньше чем нормальное расстояние (расстояние=1/вероятность такой фигуры)), но вот наткнулся на грабли, я написал 

скрипт и сделал много экпериментов, но никогда не получил фигуру из более чем 15 одинаковых значений подряд, хотя

вероятность например 16 подряд = (0.5)^16 = 0,0000152587890625, и если сделать 10 000 000 експ. то приблизительно

153 таких фигур должно быть.

int info[];

int ArrayInfo(int array[])
  {
   int len=ArraySize(array),
       res=1,
       max=1;
   for(int i=0;i<len-1;i++)
      {
       if(array[i]==array[i+1])
          res++;
       else
         {
          if(res>max) {max=res; ArrayResize(info,max+1);}
          info[res]++;
          res=1;
         }
      }
   if(res>max) {max=res; ArrayResize(info,max+1);}
   info[res]++;
   //--------------------------------
   string s=StringConcatenate(" max:  ",max,"\n");
   for(i=1;i<=max;i++)
       s=StringConcatenate(s,i,":  ",info[i],"\n");
   int sum=0;
   for(i=1;i<=max;i++)
       sum+=info[i]*i;
   s=StringConcatenate(s," sum:  ",sum,"\n");
   s=StringSubstr(s,0,StringLen(s)-1);
   Alert(s);
   //--------------------------------
   return(max);
  }


//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   int arr[10000000];
   MathSrand(GetTickCount());
   for(int i=0; i<size; i++) 
       arr[i]=MathRand()%2;
   ArrayInfo(arr);
//----
   return(0);
  }

А также ещё некоторые непонятки:


 

В принципе, возможно, этот эффект есть (не более 15 единичек, скажем), но он-то все равно незначим, не так ли? Есть такая гипотеза, что период этого генератора - порядка 2^31.