Изменения

Перейти к: навигация, поиск

Методы получения случайных комбинаторных объектов

253 байта добавлено, 23:03, 8 декабря 2018
Нет описания правки
Сложность алгоритма {{---}} <tex>O(nk) </tex>. Количества комбинаторных объектов с заданными префиксами считаются известными, и их подсчет в сложности не учитывается. Стоит отметить, что подсчет количества комбинаторных объектов с заданным префиксом зачастую является задачей с достаточно большой вычислительной сложностью.
=== Доказательство корректности ===
Докажем по индукции, что вероятность получить любой перфикс <tex> P </tex> равна <tex dpi = "120"> S(P)\over{C(n)} </tex>, где <tex> C(n) </tex> {{---}} число различных комбинаторных объектов данного типа длины <tex> n </tex>, а <tex> S(P) </tex> {{---}} число различных комбинаторных обьектов длины <tex> n </tex> с таким префиксом.
*Любой комбинаторный объект имеет пустой перфикс, следовательно <tex> S(\varnothing)=C(n) </tex>. Вероятность получить любой префикс <tex> P </tex> длины <tex> 1 </tex> равна <tex> S(P)\over{S(\varnothing)} </tex>, что равно <tex> S(P)\over{C(n)} </tex>.
*Вероятность получить из <tex> P </tex> любой префикс <tex> P' </tex> длины <tex> l+1 </tex> равна <tex> S(P')\over{S(P)} </tex> , следовательно вероятность получить префикс <tex> P' </tex> равна <tex> S(P)\over{C(n)} </tex><tex>\cdot</tex><tex> S(P')\over{S(P)} </tex> что равно <tex> S(P')\over{C(n)} </tex>
Результат работы алгоритма является префиксом <tex> P </tex> размера <tex> n </tex> и для любого такого префикса существует только один комбинаторный объект размера размера <tex> n </tex> , следовательно вероятность получения одинакова для всех различных результатов и равна <tex> 1\over{C(n)} </tex>.
== Примеры решения задач ==
Рассмотрим примеры использования данного алгоритма для генерации различных типов комбинаторных объектов.
=== Битовые вектора ===
Рассмотрим алгоритм получения случайного битового вектора. В битовом векторе может находиться только два типа элементов: <tex> 0 </tex> и <tex> 1 </tex>, следовательно <tex> k = 2 </tex>. Заметим что для любого префикса длины <tex> l </tex> число возможных комбинаторных объектов длины <tex> n </tex> одинаково и равно <tex> 2^{n-l} </tex>, следовательно на каждом шаге алгоритма небходмо выбирать с равной вероятностью <tex> 0 </tex> или <tex> 1 </tex>
Сложность алгоритма {{---}} <tex> O(n) </tex>, так как в случае двоичных векторов <tex> k </tex> постоянно и равно <tex> 2 </tex>.
=== Правильные скобочные последовательности ===
Рассмотрим алгоритм получения случайной [[Правильные скобочные последовательности|правильной скобочной последовательности]]. Правильная скобочная пследовательность состоит из двух типов элементов: открывающей и закрывающей скобок, следовательно <tex> k = 2 </tex>.
Итоговая сложность алгоритма {{---}} <tex> O(n) + O(n^2) </tex> на преподсчет.
=== Разбиения на множества ======= Разбиение на <tex> k </tex> подмножеств ====
Рассмотрим множество первых <tex> n </tex> натуральных чисел: <tex> N_n = \{1, 2, \ldots, n\} </tex>. Необходимо разбить его на <tex> k </tex> непустых подмножеств <tex> \{B_1, B_2, \ldots, B_k\} </tex> с равным распределением вероятности.
Так как на каждом шаге интервал случайных чисел разделяется только на на два диапазона, а всего шагов {{---}} <tex> n </tex> то итоговая сложность алгоритма {{---}} <tex> O(n) + O(n^2) </tex> на преподсчет чисел Стирлинга второго рода (если преподсчитать их динамически).
==== Разбиение на случайное число подмножеств ====
Описаный алгоритм можно применить для получения разбиения множества на случайное число подмножеств. Для этого достаточно случайным образом выбрать число подмножеств из интевала <tex> [1, n] </tex> , так чтобы вероятность получить число <tex> k </tex> была пропорциональна числу способов разбить <tex> n </tex> элементов на <tex> k </tex> подмножеств (что равно <tex dpi = "180">\lbrace{n\atop k}\rbrace</tex>).
74
правки

Навигация