Методы получения случайных комбинаторных объектов — различия между версиями
Cczy (обсуждение | вклад) (→Битовые вектора) |
Cczy (обсуждение | вклад) |
||
| Строка 22: | Строка 22: | ||
== Битовые вектора == | == Битовые вектора == | ||
| − | Рассмотрим алгоритм получения случайного битового вектора. В битовом векторе может находиться только два типа элементов: <tex> 0 </tex> и <tex> 1 </tex>, следовательно <tex> k = 2 </tex>. Заметим что для любого префикса длины <tex> l </tex> число возможных комбинаторных объектов одинаково и равно, следовательно на каждм шаге алгоритма небходмо выбирать с равной вероятностью | + | Рассмотрим алгоритм получения случайного битового вектора. В битовом векторе может находиться только два типа элементов: <tex> 0 </tex> и <tex> 1 </tex>, следовательно <tex> k = 2 </tex>. Заметим что для любого префикса длины <tex> l </tex> число возможных комбинаторных объектов одинаково и равно, следовательно на каждм шаге алгоритма небходмо выбирать с равной вероятностью <tex> 0 </tex> или <tex> 1 </tex> |
| + | |||
| + | '''vector<int>''' randomBitVector(n: '''int'''): <font color = green> // <tex> n </tex> {{---}} размер битового вектора.</font> | ||
| + | '''for''' i = 1 '''to''' n | ||
| + | r = random(0, 1) | ||
| + | v[i] = r | ||
| + | '''return''' prefix | ||
| + | |||
| + | Сложность алгоритма {{---}} <tex>O(n) </tex>, так как в случае двоичных векторов <tex> k </tex> постоянно и равно <tex> 2 </tex>. | ||
Версия 23:48, 7 декабря 2018
Описание алгоритма
| Задача: |
| Необходимо сгенерировать случайный комбинаторный объект размера с равномерным распределением вероятности, если в наличии есть функция для генерации случайного числа в заданном интервале. |
Пусть - множество различных элементов, которые могут находиться в данном комбинаторном объекте.
Будем получать элементы по порядку: сначала определим, какой элемент будет стоять на первом месте, потом на втором и так далее. Считаем, что мы построили префикс длинны : . Будем выбирать элемент из множества всех возможных так, чтобы вероятность выбора элемнта , была пропорциональна числу комбинторных обьектов размера с префиксом . Для этого разобъем отрезок натуральных чисел . где - число различных комбинаторных объектов с текущим префиксом, на диапазонов так, чтобы размер диапазаоны был равен числу объектов с префиксом . С помощью функция для генерации случайного числа получим число в интервале и добавим к префиксу элемент соответствующий диапазону отрезка в которм находится полученное число.
object randomObject(n: int, k: int): // — размер комбинторного объекта, — число различных элемнтов. for i = 1 to n s = number(prefix) // число комбинаторных объектов с текущим префиксом. r = random(1, s) for j = 1 to k if number(prefix + B[j]) < r // — множество всех возможных элементов. r = r - number(prefix + B[j]) // если не попало в текщий диапазон — перейдем к следующему. else prefix[i] = b[j] break return prefix
Сложность алгоритма — . Количества комбинаторных объектов с заданными префиксами считаются известными, и их подсчет в сложности не учитывается. Стоит отметить, что подсчет количества комбинаторных объектов с заданным префиксом зачастую является задачей с достаточно большой вычислительной сложностью.
Битовые вектора
Рассмотрим алгоритм получения случайного битового вектора. В битовом векторе может находиться только два типа элементов: и , следовательно . Заметим что для любого префикса длины число возможных комбинаторных объектов одинаково и равно, следовательно на каждм шаге алгоритма небходмо выбирать с равной вероятностью или
vector<int> randomBitVector(n: int): // — размер битового вектора.
for i = 1 to n
r = random(0, 1)
v[i] = r
return prefix
Сложность алгоритма — , так как в случае двоичных векторов постоянно и равно .