Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Качество потока случайных чисел, создаваемого функцией rand
 
 автор: Владимир55   (30.01.2010 в 10:35)   письмо автору
6.1 Кб
 
 

В описании функции rand не видно указаний на то, какое распределение имеет вырабатываемый ею поток случайных чисел, а потому показалось любопытным взглянуть на него.
<?php
    
for ($i=1$i <= 1000000000$i++)
    {
        
$n rand(11000);
        
$tmp[$n]++;
    }
Скриншот работы анализатора в Приложении.
Вероятно, создатели сделали упор на быстродействие, ибо статистические качества настолько низки, что как-то модифицоировать этот поток не имеет смысла.

  Ответить  
 
 автор: Владимир55   (30.01.2010 в 10:41)   письмо автору
11 Кб
 
   для: Владимир55   (30.01.2010 в 10:35)
 

Ради любопытства можно просуммировать два потока, которые при этом, по идее, должны нормализоваться:
<?php
    
for ($i=1$i <= 1000000000$i++)
    {
        
$n rand(1500) + rand(1500);
        
$tmp[$n]++;
    }
Скриншот в Приложении.

Вероятно, mt_rand даст лучшие результаты, а функцию rand имеет смысл использовать только в самых простейших случаях, когда к качеству статистики не предъявляется никаких требований.

  Ответить  
 
 автор: Trianon   (30.01.2010 в 11:51)   письмо автору
 
   для: Владимир55   (30.01.2010 в 10:41)
 

1. а почему всего два отсчета?
Везде предлагают 5 - 12 отсчетов суммировать.

2.IMHO вызывать эту функцию с параметрами диапазона для целей поверки несколько некорректно.
По-моему, следует получить неиспорченное внутренними нормализациями значенние генератора rand(), соотнести его со шкалой 0...getrandmax() (т.е. нормализовать руками в 0...1 ), а затем уже суммировать, учитывать и т.п.

  Ответить  
 
 автор: Владимир55   (30.01.2010 в 17:15)   письмо автору
 
   для: Trianon   (30.01.2010 в 11:51)
 

На самом деле я сделал несколько вариантов, но привел результаты только суммы двух источников как характеризующую ситуацию вцелом. При увеличении количества суммируемых источников нормализация происходит, но очень слабо.

rand мне показался неперспективным.

  Ответить  
 
 автор: Trianon   (30.01.2010 в 17:17)   письмо автору
 
   для: Владимир55   (30.01.2010 в 17:15)
 

rand() или rand(p, q) ?

mt_rand, конечно, более качественный. Его затем и делали.

  Ответить  
 
 автор: Владимир55   (30.01.2010 в 19:51)   письмо автору
5.7 Кб
 
   для: Trianon   (30.01.2010 в 17:17)
 

rand() или rand(p, q) ?
Имелось в виду rand(p, q)

mt_rand, конечно, более качественный
Сумма пятидесяти источников mt_rand имеет вполне приличный вид (в Приложении).

  Ответить  
 
 автор: Trianon   (30.01.2010 в 20:10)   письмо автору
 
   для: Владимир55   (30.01.2010 в 19:51)
 

А как ведут себя 50 (rand()/$rmax)
где $rmax = getrandmax();
,можно посмотреть?

Что-то хвосты ошибок не видны...

  Ответить  
 
 автор: Владимир55   (30.01.2010 в 20:48)   письмо автору
4.4 Кб
 
   для: Trianon   (30.01.2010 в 20:10)
 

Если так:
    $rmax = getrandmax();
    for ($i=1; $i <= 1000000; $i++)
    {
        $n = 0;
        for ($ii=1; $ii <= 50; $ii++)
        $n += (rand())/$rmax ;
        $tmp[$n]++;
        
    }
то графическое представление не впечатляет - (в Приложении), а в табличном виде первая сотня значений $n
26.5152439955
26.8640095218
25.3816644795
26.5761589404
23.2675862911
24.0890224921
22.9855952635
26.7153233436
23.3481551561
24.7672658467
25.1677907651
27.5576342051
21.2567827387
26.3986632893
26.4280831324
25.6029847102
23.4936674093
25.483108005
23.2663655507
25.3515121921
27.5587328715
25.5207068087
24.1828974273
24.3031403546
23.9516891995
27.0114749596
23.6775109104
21.9578539384
25.1729178747
24.4552446059
22.2502212592
26.8159123508
26.7222815638
22.3521530808
24.4011658071
27.376964629
23.0996124149
24.2023071993
22.6301156652
24.1410260323
24.8052308725
23.505508591
24.4372997223
26.6083864864
25.3389385662
29.7620471816
23.3225196081
25.2787560656
24.2007202368
24.4713583789
25.785973693
22.652211066
26.8907437361
26.1340067751
23.3274025697
19.228766747
20.9086275826
25.2497024445
23.4470351268
29.508865627
23.7549058504
26.3185827204
23.6447950682
24.9916379284
23.9292275765
23.840479751
24.4206976531
28.1777703177
21.9316080203
26.3156529435
25.2747276223
21.566728721
25.2622760704
22.2437513352
25.7068697165
26.6591692862
25.4209723197
27.1252479629
23.2170476394
21.9544358654
25.9078035829
25.4596697897
23.3054292428
24.9530625324
26.2227546007
21.747154149
22.471907712
24.1546983245
24.8657795953
25.4879909665
24.2165898618
26.059541612
26.3370159001
24.1817987609
26.0393993957
26.1674550615
23.1362346263
26.3288369396
27.4403210547
24.9784539323

  Ответить  
 
 автор: Trianon   (30.01.2010 в 22:12)   письмо автору
3.3 Кб
 
   для: Владимир55   (30.01.2010 в 20:48)
 

rand при десятке см. ===>аттач

<?php
   $num 
1000000;
   
$q 10;
   
$w 800$h 600;
   
$m 0;
   
$gis array_fill(0$w0);
   
$mrand getrandmax();
   for(
$i $c 0$i $num$i++)
   {
       for(
$n 0$j 0$j $q$j++)
           
$n += rand();
       
$n /= $q*$mrand;
       
$x intval($n * ($w-1));
         
$y = @++$gis[$x];
         
$m $y $m $y $m;
         ++
$c;
   }
   
$im imagecreate($w$h);
   
$c_wht imagecolorallocate($im255255255);
   
$c_blk imagecolorallocate($im0,0,0);
   
$c_red imagecolorallocate($im25500);
   
imagefilledrectangle($im00$w-1$h-1$c_wht);
   
imageline($im$w>>10$w>>1$h-1$c_blk);
   for(
$i=0$i $w$i++)
   {
     
$j $h-1-intval($gis[$i]*($h-1)/$m);
     
imageline($im$i$j+1$i+1$j$c_red);
     
imageline($im$i$j$i+1$j+1$c_red);
   }
   
header("image/gif");   imagegif($im);
?>

  Ответить  
 
 автор: Trianon   (30.01.2010 в 22:12)   письмо автору
3.3 Кб
 
   для: Владимир55   (30.01.2010 в 20:48)
 

mt_rand при десятке см. ===>аттач
<?php
   $num 
1000000;
   
$q 10;
   
$w 800$h 600;
   
$m 0;
   
$gis array_fill(0$w0);
   
$mrand mt_getrandmax();
   for(
$i $c 0$i $num$i++)
   {
       for(
$n 0$j 0$j $q$j++)
           
$n += mt_rand();
       
$n /= $q*$mrand;
       
$x intval($n * ($w-1));
         
$y = @++$gis[$x];
         
$m $y $m $y $m;
         ++
$c;
   }
   
$im imagecreate($w$h);
   
$c_wht imagecolorallocate($im255255255);
   
$c_blk imagecolorallocate($im0,0,0);
   
$c_red imagecolorallocate($im25500);
   
imagefilledrectangle($im00$w-1$h-1$c_wht);
   
imageline($im$w>>10$w>>1$h-1$c_blk);
   for(
$i=0$i $w$i++)
   {
     
$j $h-1-intval($gis[$i]*($h-1)/$m);
     
imageline($im$i$j+1$i+1$j$c_red);
     
imageline($im$i$j$i+1$j+1$c_red);
   }
   
header("image/gif");   imagegif($im);
?>

  Ответить  
 
 автор: Владимир55   (31.01.2010 в 00:38)   письмо автору
 
   для: Trianon   (30.01.2010 в 22:12)
 

На мой взгляд, с такой оснасткой для большинства задач обе функции достаточно хороши.

  Ответить  
 
 автор: cheops   (30.01.2010 в 10:59)   письмо автору
 
   для: Владимир55   (30.01.2010 в 10:35)
 

Есть алгоритмы достаточно равномерных генераторов (которые здорово улучшают параметры стандартных функций) - их можно поискать (у меня, к сожалению, они только на Fortran и то сейчас не под рукой). В свое время работая методом Монте-Карло тоже долго подбирал равномерные генераторы.

  Ответить  
 
 автор: Владимир55   (30.01.2010 в 11:17)   письмо автору
 
   для: cheops   (30.01.2010 в 10:59)
 

Я тоже этим когда-то занимался - строил М-последовательности на сдвиговых регистрах с сумматорами по модулю два в обратной связи.

Кстати, тоже на Фортране. Очень давно.

  Ответить  
 
 автор: STEVER   (30.01.2010 в 17:40)   письмо автору
 
   для: Владимир55   (30.01.2010 в 11:17)
 

респект за стат и графический вывод =)

я могу с уверенностью сказать что Хороших программных генераторов не существует!
только аппаратные.

  Ответить  
 
 автор: Trianon   (30.01.2010 в 17:52)   письмо автору
 
   для: STEVER   (30.01.2010 в 17:40)
 

>Хороших программных генераторов не существует!
>только аппаратные.

Каким пользуетесь Вы лично?

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования