Собственно вот "мой" генератор псевдослучайных чисел. (не совсем мой конечно, слизал само собой, но на РНР его переписал я) Работает в диапазоне rand16() - 0-65535 И сам по себе прост как 3.1415926....... Код (Text): <?php /*********************************************************** *\ \ ___ __ /\ ____ ____ ____ __ | | * \ \ / /| | / \ | _ \ / __>/ \| || | * \ \/ / | | / /\ \ | | \ \\_ \_ | || || \ | * \ / | |__ / __ \ | |_/ / _\ \| || || \ | * \ / |_____|/__/ \ \|____/ <____/\____/| ||__| * \/ \ \ | | *********************************************************** * Title: Pseudorandom number generator * Version: 0.0.2 * * URL: http://dkflbk.nm.ru/ * E-Mail: dkflbk@nm.ru *********************************************************** * * This program is free software; you can redistribute * it and/or modify it under the terms of the GNU * General Public License as published by the Free * Software Foundation; either version 2 of the License * or anylater version. * **********************************************************/ Class VLD_Rand { var $seed1; var $seed2; var $seed3; function seed($seed1, $seed2, $seed3) { $this->seed1 = $seed1; $this->seed2 = $seed2; $this->seed3 = $seed3; } function rand16() { $a = $this->seed2; $b = $this->seed1; $b = ($a+$b)&65535; $this->seed1 = $a; $this->seed2 = $a = $this->seed3; $a = ($a+$b)&65535; return $this->seed3 = $a = ($a*2 > 65535) ? $a*2-65535 : $a*2; } } ?> Ну и примерчик использования Код (Text): <?php /** * Example **/ $rnd = new VLD_Rand(); $rnd->seed(1, 2, 3); for($i=0; $i<99; $i++) { echo $rnd->rand16().', '; } ?>
Ммм... а почему для генерации 16-значного ты перемножаешь два 8-значных? Это же зверски влияет на равномерность распределения результата, в частности, нечетные числа будут выдаваться с вероятностью 1/4, а не 1/2, как должно быть... Я тут недавно почитал статью про алгоритм для генерации СЧ под названием "Mersenne Twister" (это как раз тот, который используется в mt_rand). Достаточно несложная идея, просто суперские результаты (какой-то просто невообразимый период), мне очень понравилось.
Лично я не перемножаю (сам я его даже не запускал почти использовал кроме как при написании) а добавил (уже убрал) эти "перемножения" в последнюю минуту (сам не знаю зачем, может не выспался...)
А разьве ПХП не может читать из "/dev/random" ? А ещё может оказаться так, что система поддерживает аппаратный RNG.
mmaavv Это генератор не случайных чисел, а псевдо-случайных. (есть и у них свои области применения) Опять-же это написано сам не знаю зачем, в РНР есть встроенные функции которые справляются со всем этим "на ура" и ими лучше и пользоваться
А какой период данной ПСЧ (не диапазон генерируемых чисел, а именно период повторения последовательности)? Зависит ли он от начальных seed1,seed2,seed3?
Период не особо большой (конкретных чисел не назову) но зависит на прямую от начальных значений seed1,seed2,seed3 (алгоритм довольно старый, я его вычитал в журнале 92-го года, и уже там писали что он старый)
А почему бы не использовать более простой алгоритм типа: x(n+1)=A*x(n)+B mod M ? При грамотном выборе A и B период данной последовательности будет равен M, да и распределение можно подобрать приемлемым.
Просто потому что он не попался под руку, а попался этот. Добавлено: Для человека мрожет и простой, а вот для процессора очень тяжёлый.
Пытаюсь разобраться в математике алгоритма... Я не совсем понял, где в коде перемножение двух 8-значных? Это не ошибка? Именно 65535, а не 65536?
убрал (раньше было) нет не ошибка именно 65535 На ассемблере это выглядит так Код (Text): _rand_16: push dx mov ax,seed1 mov dx,ax mov ax,seed2 mov seed1,ax add ax,dx mov dx,ax mov ax,seed3 mov seed2,ax add ax,dx rcl ax,1 mov seed3,ax pop dx ret
как вам такая психоделика? :-D PHP: <?php ############################ # Лицензионнное соглашение # #--------------------------# # Вам запрещено читать # # этот текст. Немедленно # # закройте глаза во избе- # # жание поражения моска # ############################ # Desu. Desu? Desu! class Desu { var $data; function __construct( $props= array() ){ $this->data= (object)$props; } function __get( $name ){ $method= 'get__' . $name; if( method_exists( $this, $method ) ) return $this->{$method}(); return $this->data->{$name}; } function __set( $name, $value ){ $method= 'set__' . $name; if( method_exists( $this, $method ) ) return $this->{$method}( $value ); return $this->data->{$name}= $value; } function __clone( ){ $this->data= clone $this->data; } } # Бродяга, блуждающий по индексному массиву class Stranger extends Desu { function __construct( $array ){ $this->array= $array; $this->index= -1; } function get__haveNext( ){ # есть куда идти? return isset( $this->array[ ++$this->index ] ); } function get__current( ){ # а тут чо? return $this->array[ $this->index ]; } } # Историк, он записывает происходящие события class Historian extends Desu { function __construct( $array= array() ){ $this->memory= $array; } function get__tentacle( ){ # Хотим пройтись по памяти? Юзаем щупальцу! return new Stranger( $this->memory ); } function push( $values= array() ){ # О! Вспомнил! $this->memory= array_merge( array_reverse( $values ), $this->memory ); return $values; } function pop( ){ # Гм... забыл... return array_shift( $this->memory ); } } # Разумное, но тупое как пробка существо class Mind extends Desu { function __construct( $value= null ){ $this->employers= (object)array(); $this->value= $value; $this->weight= 1; } function touch( ){ # Щупаем ++$this->weight; } function grow( $years ){ # Прошло десять лет $this->weight/= $years; } function extradite( $value ){ # Выдай-ка мне своего подчинённого, занимающегося вышиванием крестиком return @$this->employers->{$value}; } function employ( $memoir, $employer ){ # Вот те новый подчинённый для вышивания крестиком $this->employers->{$memoir}= $employer; } } # Моск Нострадамиуса class Brain { function __construct( $memoirs= array() ){ $this->memory= new Historian( array( 0 ) ); $this->reason= new Mind( ); $this->population= 0; $this->train( $memoirs ); } function train( $values= array() ){ # Накачиваем моск историей foreach( $values as $value ): $tentacle= $this->memory->tentacle; $mind= $this->reason; while( $tentacle->haveNext && ( $employer= $mind->extradite( $tentacle->current ) ) ){ $mind->touch(); $mind= $employer; } $memoir= @$tentacle->current; if( !isset( $memoir ) ) $memoir= 0; if( $value !== $mind->value ) $mind->employ( $memoir, new Mind( $value ) ); $this->memory->push(array( $value )); endforeach; $this->population+= count( $values ); } function predict( ){ # Получаем астрологический прогноз на будущее $tentacle= $this->memory->tentacle; $mind= $this->reason; while( $tentacle->haveNext && ( $employer= $mind->extradite( $tentacle->current ) ) ) $mind= $employer; return $mind->value; } } # Бурный Белый Шумный Поток class WhiteStream extends Desu { function __construct( $initial= array() ){ $this->generator= new Brain( $initial ); } function get__value( ){ # а сейчас какое значение? $gen= $this->generator; $chit= 1 - $gen->predict(); $gen->train(array( $chit )); return $chit; } } $init= @$_GET[ 'input' ]; $init= $init ? explode( ',', $init ) : array(); $random= new WhiteStream( $init ); $stat= array(); for( $i= 1000; $i; --$i ): $rnd= $random->value; @++$stat[ $rnd ]; echo $rnd; endfor; echo '<pre>'; ksort( $stat ); print_r( $stat ); ?> два вечера угробил осталось приделать старение, вымирание при перенаселённости и поддержку любых значений, а не только 0 и 1...
Нормальный программист никогда не ставит комментариев. Что писалось с трудом, должно пониматься с трудом
я знаю! сценарии для хентая пишут на пхп! PHP: shounen::saw( $tentacle->virgin ) && shounen::comeIn(); $tentacle->shounen->woman; Daemon::comeIn(); foreach( Daemon::tentacles as $tentacle ) $tentacle->{ rand(2) ? 'man' : 'woman' } Daemon::force( array( 'Big Ben' => woman ) ); man::explode( 'tentacle', $daemon ); exit( 'happy endo' );
а что, есть программисты, которые не любят анимэ? палево! это кодеры обычные! хороший программист всегда, прежде чем писать код, понаблюдает за классами, свыкнится с объектами, проникнится их чувствами, усвоит взаимоотношения. и только после этого начинается действие!
Vladson. ИМХО. Судя по asm Код (Text): add ax,dx rcl ax,1 mov seed3,ax Последние две строки должны выглядеть так: PHP: <? // $a = ($a+$b)&65535; !!! Теряется Carry Flag // return $this->seed3 = $a = ($a*2 > 65535) ? $a*2-65535 : $a*2; // Не то условие проверки $a = $a+$b; return $this->seed3 = ( $a > 65535 ? $a*2+1 : $a*2) & 65535; ?>