Blog. Just Blog

Быстрый поиск

Введите фрагмент названия статьи для поиска

Генерация случайных значений на PHP с заданной вероятностью

11.01.2019 | Категория: Web-мастеру и не только | Автор: ManHunter
Понадобилась функция, которая возвращает случайный элемент из определенного набора. Вроде бы простейшее решение в одну строчку. Но особенность задачи такова, что элементы должны появляться не просто случайно, а с определенной вероятностью: какие-то чаще, какие-то реже. То есть у каждого значения имеется весовой коэффициент, влияющий на частоту его появления. Например:
  1. // Массив значений и весовых коэффициентов
  2. $data=array(
  3.     'купить'=>50,
  4.     'заказать'=>5,
  5.     'приобрести'=>30,
  6. );
Для такого набора данных чаще всего должно появляться слово "купить", чуть реже "приобрести" и в очень редких случаях может проскакивать вариант "заказать". Готовая функция получилась следующей:
  1. //-------------------------------------------------------------
  2. // Получение случайного значения с заданной вероятностью
  3. //-------------------------------------------------------------
  4. function smart_rand($data) {
  5.     // Пустой массив не обрабатываем
  6.     if (count($data)==0) { return false; }
  7.  
  8.     // Отсортировать массив с сохранением ключей
  9.     arsort($data);
  10.  
  11.     // Сформировать массив с интервалами
  12.     $max_rand=0;
  13.     $weights=array();
  14.     foreach ($data as $key=>$value) {
  15.         $max_rand+=$value;
  16.         $weights[$max_rand]=$key;
  17.     }
  18.  
  19.     // Случайное число от 0 до суммы всех весовых коэффициентов
  20.     $rand=mt_rand(0,$max_rand);
  21.  
  22.     // Найти интервал, в который попадает случайное число
  23.     foreach ($weights as $key=>$value) {
  24.         if ($rand<=$key) {
  25.             break;
  26.         }
  27.     }
  28.     return $value;
  29. }
На входе передается массив значений с весовыми коэффициентами, на выходе одно из значений. Пример использования:
  1. // Вывести 100 вариантов написания
  2. for($i=0$i<100$i++) {
  3.     echo smart_rand($data).' ';
  4. }
Числовые значения весовых коэффициентов могут быть любыми и следовать в произвольном порядке, их количество также ничем не ограничено.

Просмотров: 2240 | Комментариев: 1

Генератор случайных чисел с использованием RANDOM.ORG

25.10.2016 | Категория: Образ мышления: Assembler | Автор: ManHunter

Генератор случайных чисел с использованием RANDOM.ORG

Тема генераторов случайных чисел является одной из основных в криптографии. Использование любых программных генераторов случайных чисел имеет один главный недостаток: последовательность чисел может называться случайной только если между символами, нету зависимости. А любой алгоритм так или иначе подразумевает зависимость от вычислений. Истинно случайные числа получаются только от аппаратных генераторов. Одним из таких генераторов является сайт RANDOM.ORG. По заявлению его владельцев, источником для случайных чисел является атмосферный шум. Не берусь утверждать, так это или нет, но этот сайт пользуется заслуженной популярностью среди разработчиков всего мира.

Читать статью целиком »
Просмотров: 4204 | Комментариев: 11

Генерация последовательности уникальных кодов на PHP

12.10.2013 | Категория: Web-мастеру и не только | Автор: ManHunter
Иногда возникает задача генерации последовательности уникальных кодов по определенному формату. Это могут быть какие-нибудь одноразовые токены, коды лотерейных билетов, серийные номера, scratch-карты, да мало ли чего. Простое использование ГСЧ в этом случае не дает 100% гарантии, так как выдаваемые им значения могут повторяться, а при большом количестве кодов количество повторений будет только расти. Предлагаю вам следующее решение:
  1. // Набор символов для генерации кодов
  2. $str='1234567890ABCDEF';
  3. // Длина кода без учета разделителей
  4. $code_length=16;
  5. // Нужное количество кодов
  6. $codes_count=300000;
  7. // Позиции разделителя (0 - не надо)
  8. $code_separartor=4;
  9.  
  10. $tmp=array();
  11. $str_length=strlen($str)-1;
  12.  
  13. // Цикл до заполнения массива
  14. while (count($tmp)<$codes_count) {
  15.     // Сгенерировать индекс массива
  16.     $code='';
  17.     for ($i=0$i<$code_length$i++){
  18.         // Разделитель можно не добавлять
  19.         if ($i>&& $code_separartor>&& $i%$code_separartor==0) { $code.='-';}
  20.         $code.=substr($strmt_rand(0,$str_length), 1);
  21.     }
  22.     // Или в массив добавится новый элемент, или
  23.     // перепишется поверх уже имеющийся
  24.     $tmp[$code]=1;
  25. }
  26. // Теперь в массиве $codes уникальные коды
  27. $codes=array_keys($tmp);
Коды генерируются гарантированно уникальные (в пределах одной сессии). Это достигается за счет того, что в качестве кода сперва используются ключи массива, а не значения. Даже если какой-либо код будет сгенерирован повторно, то просто перезапишется уже имеющийся элемент массива, а не добавится новый. Отсутствие проверок типа in_array значительно повышает скорость работы генератора. Главный недостаток этого алгоритма в том, что для генерации больших объемов данных потребуется много оперативной памяти. Для особо критичных случаев при выборе символов, составляющих код, лучше использовать не программный ГСЧ, а какой-нибудь аппаратный, чтобы обеспечить максимальную непредсказуемость данных.

Читать статью целиком »
Просмотров: 11829 | Комментариев: 6

Еще один генератор случайных чисел на Ассемблере

17.05.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
В закромах Родины нашлась реализация еще одного генератора случайных чисел. Он более громоздкий, чем минимальный генератор Парка-Миллера, использует операции с плавающей точкой и кольцевой буфер, но результаты выдает гораздо лучше. Кроме большого кода ему также требуется больше места и в сегменте данных:
  1. section '.data' data readable writeable
  2.  
  3. ; Данные для генератора случайных чисел
  4. JJ      =       10             ; lag 1
  5. KK      =       17             ; lag 2, size of circular buffer
  6. R1      =       19             ; rotate count
  7. R2      =       27             ; rotate count
  8. randp1  dt      1.5            ; used for conversion to float
  9.         dw      0              ; alignment
  10. p1      dd      0              ; pointer in circular buffer
  11. p2      dd      0              ; pointer in circular buffer
  12. randbuf dd      (2*KK) dup(?)  ; circular buffer
Перед первым использованием генератор требуется инициализировать, вызвав функцию WRandomInit с каким-нибудь случайным значением, например, количеством тиков таймера:
  1.         ; Инициализация генератора случайных чисел
  2.         invoke  GetTickCount
  3.         stdcall WRandomInit,eax
  4.         ...
После инициализации генератор можно использовать в двух режимах: генерация одиночного случайного числа размером в два двойных слова (функция WRandom) или генерация случайного числа в заданном диапазоне от 1 до 0FFFFFFFEh (функция WIRandom). Формулировка "одиночное случайное число", наверное, не совсем подходит по смыслу к выполняемому действию, но тавтология "произвольное случайное число" мне показалась хуже.

Читать статью целиком »
Просмотров: 11720 | Комментариев: 10

Генератор случайных чисел на Ассемблере

03.09.2008 | Категория: Образ мышления: Assembler | Автор: ManHunter

Генератор случайных чисел на Ассемблере

При написании программ часто возникает необходимость получить последовательность случайных чисел. В языках высокого уровня существуют штатные функции, а для Ассемблера я использую так называемый "Минимальный генератор Парка-Миллера" (Minimal portable random generator by Park and Miller).

Читать статью целиком »
Просмотров: 31723 | Комментариев: 7

01 02 next
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2025
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 3 (0.0015 сек.) / Память: 4.5 Mb
Наверх