Генератор псевдослучайных чисел

» опубликован
» Способ реализации: cJass
» Тип: Наработка
» Версия Warcraft: 1.26a

Введение

» Зачем это нужно?
Не редко случайный разброс используется при написании карт/игр. Начиная с выбора персонажа, дропа предмета, шанса крита, до генерации шума и создания карты высот.
» Почему не стандартный?
Нет исходников

Описание

1. Линейный конгруэнтный генератор
Использует простую формулу для получения последовательности:
Xn+1 = (a * Xn – c) mod M, где a, c, M – особые константы; X[0,M-1]
2. Запаздывающий генератор Фибоначчи
Позволяет получить более высокое "качество" псевдослучайных чисел.
В данной реализации Ki:
{ Ki-a – Ki-b, если Ki-a >= Ki-b
{ Ki-a – Ki-b + 1, если Ki-a < Ki-b

Функционал

  • получить/установить зерно (для линейного конгруэнтного генератора);
  • случайный real в диапазонах: [0,1], [0,max], [min,max];
  • случайный int в диапазонах: [0,max], [min,max].
Linear Congruent Generator.w3m
Lagged Fibonacci Generator.w3m
Используется один генератор, выбираемый при инициализации.
Multi Linear Congruent Generator.w3m
Multi Lagged Fibonacci Generator.w3m
Тут можно создать "объект" генератора. Подходит, если вам нужно несколько одинаковых генераторов или несколько разных генераторов.
» источники

Заключение

» почему не jass
Перегрузка функций;
Компактность и прозрачность кода.
» об integer
Из-за отсутствия беззнакового типа допущение переполнения int может привести к неопределенному поведению, что накладывает некоторые ограничения на реализацию линейного конгруэнтного генератора.
» тест на скорость
Тест оценивает, во сколько раз текущие генераторы сильнее нагружают лимит операций
относительно оригинальной функции. Эксперимент проводился с помощью:
» code
integer INT = 0
function MyCode takes nothing returns nothing
	// ...initialization
	TriggerSleepAction(0.)
  loop
    //q = LCG_randr(g,20.,100.)
    //i = LCG_randi(g,2,20)
    INT++
  endloop
endfunction

function PostMyCode takes nothing returns nothing
  TriggerSleepAction(0.3)
  printi(INT)
endfunction
Результаты:
\nativeLCGMLCGLFGMLFG
int(0,max) 23076 (1) 5172 (4.4) 3896 (5.9) 5768 (4) 4284 (5.3)
int(min,max) 21428 (1) 4545 (4.7) 3529 (6) 5001 (4.2) 3847 (5.5)
real(0,1) 23076 (1) 6382 (3.6) 4545 (5) 7316 (3.1) 5085 (4.5)
real(0,max) 21428 (1) 5882 (3.6) 4285 (5) 6665 (3.2) 4762 (4.4)
real(min,max) 18750 (1) 5084 (3.6) 3846 (4.8) 5658 (3.3) 4224 (4.4)
Как видно, native GetRandom_() "легче" в 3.1 - 6 раз.

Установка

Скопировать папку LCG/LFG себе в карту.


Просмотров: 371



prog #51 - 2 дня назад 0
quq_CCCP, т.е. последовательность SetRandomSeed(100500) GetRandomInt(0, 1000000) выдаст мне на выходе 100500, а не следующее число из потока после 100500?
Впрочем, это ничего не решает - всеравно придется жонглировать сидом туда-сюда постоянно, что не очень удобно.