Методы получения случайных комбинаторных объектов — различия между версиями
Cczy (обсуждение | вклад) |
Cczy (обсуждение | вклад) (→Доказательство корректности) |
||
Строка 22: | Строка 22: | ||
=== Доказательство корректности === | === Доказательство корректности === | ||
− | Докажем по индукции, что вероятность получить любой перфикс равна <tex> C(n)\over{S(P)} </tex>, где <tex> C(n) </tex> - число различных комбинаторных данного типа длины <tex> n </tex>, а <tex> S(P) </tex> - число различных комбинаторных обьектов с таким префиксом. | + | Докажем по индукции, что вероятность получить любой перфикс <tex> P </tex> равна <tex> C(n)\over{S(P)} </tex>, где <tex> C(n) </tex> - число различных комбинаторных данного типа длины <tex> n </tex>, а <tex> S(P) </tex> - число различных комбинаторных обьектов с таким префиксом. |
− | * | + | *Любой комбинаторный объеут имеет пустой перфикс, следовательно <tex> S(\varnothing)=C(n) </tex>. Вероятность получить любой префикс <tex> P </tex> длины <tex> 1 </tex> равна <tex> S(\varnothing)\over{S(P)} </tex>, что равно <tex> C(n)\over{S(P)} </tex>. |
+ | *Пусть вероятность получить префикс <tex> P </tex> длины <tex> l </tex> равна <tex> C(n)\over{S(P)} </tex> | ||
+ | *Тогда вероятность получить из <tex> P </tex> любой префикс <tex> P' </tex> длины <tex> l+1 </tex> равна <tex> C(n)\over{S(P)} </tex><tex>\cdot</tex><tex> S(P)\over{S(P')} </tex> , что равно <tex> C(n)\over{S(P)} </tex> | ||
== Битовые вектора == | == Битовые вектора == |
Версия 00:44, 8 декабря 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
Сложность алгоритма —
, так как в случае двоичных векторов постоянно и равно .