Получение объекта по номеру — различия между версиями
Строка 34: | Строка 34: | ||
множества за <tex>O( log {n}) </tex>. Например декартово дерево по неявному ключу. | множества за <tex>O( log {n}) </tex>. Например декартово дерево по неявному ключу. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== Битовые вектора == | == Битовые вектора == | ||
− | |||
− | |||
== См. также == | == См. также == | ||
[[Получение номера по объекту|Получение номера по объекту]] | [[Получение номера по объекту|Получение номера по объекту]] | ||
[[Категория: Дискретная математика и алгоритмы]] | [[Категория: Дискретная математика и алгоритмы]] | ||
[[Категория: Комбинаторика]] | [[Категория: Комбинаторика]] |
Версия 06:20, 30 октября 2011
Содержание
Общий алгоритм получения комбинаторного объекта по номеру в лексикографическом порядке
Получим элементы объекта по порядку: сначала определим какой элемент будет стоять на 1-м месте, 2-м и т.д. Пусть мы нашли первые i элементов нашего объекта. Для всех вариантов элемента, который может стоять на (i+1)-ой позиции, посчитаем диапазон номеров, который будет соответствовать объектам с данным префиксом. Если искомый номер входит в один из диапазонов, то, очевидно, мы нашли элемент, который должени стоять на (i+1)-ом месте. (Диапазоны номеров не пересекаются, значит, на это место больше нельзя поставить никакой другой элемент, соответственно, это единственный элемент, который может стоять на этой позиции).
//В начале каждого шага numOfObject — номер комбинаторного объекта среди объектов с заданным префиксом. for i = 1 to n do //n — количество элементов в комбинаторном объекте for j = 1 to n do //перебираем елементы в лексикографическом порядке if элемент j можно поставить на i-e место then if numOfObject > (количество комбинаторных обектов с данным префиксом) then numOfObject -= (количество комбинаторных обектов с данным префиксом) else then ans[i]=j //поставим на i-e место текущий элемент, т.к. еще не все объекты с этим префиксом - меньше перейти к выбору следующего элемента
Несложно понять, что корректность алгоритма следует из его построения. Сложность алгоритма комбинаторных объектов.
, где - сложность вычисления количества комбинаторных объектов с данным префиксом. Основную сложность при построении алгоритмов генерации комбинаторных объектов составляет вычисление количества комбинаторных объектов с данным префиксом. Приведем примеры способов нахождения количества некоторых изПерестановки
Рассмотрим алгоритм получения i-ой в лексикографическом порядке перестановки размера n.
— количество перестановок размера n permutation[n] — искомая перестановка was[n] — использовали ли мы уже эту цифру в перестановке for i = 1 to n do //n - количество цифр в перестановке alreadyWas = (numOfPermutation-1) div // сколько цифр уже полностью заняты перестановками с меньшим номером numOfPermutation = ((numOfPermutation-1) mod ) + 1 //сейчас мы должны поставить ту цифру, которая еще полностью не занята, т.е. alreadyWas+1, которая еще не занята for j = 1 to n do if was[j] = false then cntFree++ if cntFree = alreadyWas+1 then ans[i] = j was[j] = true
Данный алгоритм работает за
. Мы можем посчитать за . Асимптотику можно улучшить до , если использовать структуры данных, которые позволяют искать i-ый элемент множества и удалять элемент множества за . Например декартово дерево по неявному ключу.