
Чет про программирование / асимптотика
.pdf
наторных объектов в литературе часто называют линейным. Хотя это название несёт дуализм9, оно оправдано, поскольку такие алгоритмы генерации имеют асимптотически наилучшую сложность. Мы также будет придерживаться этой терминологии.
1. Перестановки и алгоритмы их порождения
Определение 5. Перестановкой множества A называется произвольное взаимно-однозначное отображение α : A → A.
Обычно перестановка конечного множества A определяется с помощью таблицы с двумя строками, каждая из которых содержит все элементы множества A, причем элемент α(a) помещается под элементом a. Например, перестановку α : A → A множества A = {a, b, c, d} такую, что α(a) = d, α(b) = a, α(c) = c и α(d) = b, можно записать в виде следующей таблицы ( )
a b c d
α = . d a c b
Иногда перестановкой называется вторая строка такой таблицы, а сама функция α : A → A, заданная таблицей, называется подстановкой. Поскольку порядок элементов множества A будет всегда зафиксирован, мы используем термин перестановка как для обозначения самой функции α, так и для обозначения нижней строки таблицы, определяющей это отображение. Таким образом, в указанном примере перестановка есть последовательность (d, a, c, b). В общем случае для n-элементного множества A с зафиксированным порядком элементов a1, . . . , an перестановка — это произвольная последовательность длины n из различных элементов множества A. Так, последовательность (α1, . . . , αn), где все элементы αi A различны, есть перестановка.
Обычно природа элементов множества A несущественна, поэтому без уменьшения общности можно считать, что A = {1, 2, . . . , n} (ина-
9 Cравните с понятием линейного алгоритма из гл. 1.
21
че необходимо перейти к номерам элементов). Обозначим множество всех перестановок n-элементного множества через Sn. На множестве
Sn определена операция умножения перестановок α ◦ β как суперпозиция отображений α и β : α◦β(i) = α(β(i)). Вообще говоря, эта операция не коммутативна, т. е. α ◦ β ≠ β ◦ α. При этом выполняются следующие аксиомы группы:
•α Sn β Sn γ Sn α ◦ (β ◦ γ) = (α ◦ β) ◦ γ (ассоциативность);
•e Sn α Sn (α ◦ e = e ◦ α = α) (существование единичного элемента e);
•α Sn α−1 Sn (α ◦ α−1 = α−1 ◦ α = e) (существование обратного элемента α−1).
Тождественная перестановка e является единичным элементом, а для
( )
1 2 . . . n
e =
1 2 . . . n
нахождения обратной перестановки α−1 достаточно сначала поменять местами строки в таблице, определяющей перестановку α, а затем упорядочить столбцы в порядке возрастания по верхним элементам. Таким образом, множество перестановок Sn образует группу относительно операции умножения ◦, называемую симметрической группой степени n. Её порядок, т. е. число элементов множества Sn, равен n!.
Рассмотрим задачу генерации всех перестановок n-элементного множества. Возникновение этой задачи относят к началу XVII в., когда в Англии зародилось особое искусство колокольного боя, основанного, если говорить упрощённо, на выбивании на n различных колоколах всех n! перестановок. Перестановки эти следовало "выбивать по памяти", что способствовало разработке сторонниками этого искусства первых простых методов систематического перечисления всех перестановок без повторений. В Книге рекордов Гиннеса содержится упоминание о вы-
22

бивании всех 8!=40320 перестановок на 8 колоколах в 1963 г., на это потребовалось 17 часов 58,5 минут.
Далее в этом разделе мы познакомимся с несколькими алгоритмами генерации всех перестановок n-элементного множества. Сначала определим лексикографический порядок на множестве Sn, индекс перестановки относительно этого порядка и вектор инверсии. Затем рассмотрим алгоритмы порождения перестановок, связанные с этими понятиями. Наконец, детально изучим линейный алгоритм генерации перестановок в лексикографическом порядке и линейный алгоритм Джонсона – Троттера генерации перестановок в порядке минимального изменения.
1.1. Индекс перестановки
На множестве всех перестановок n-элементного множества определим бинарное отношение следующим образом:
(α1, α2, . . . , αn) (β1, β2, . . . βn) k ≥ 1 (αk < βk & i < k (αi = βi)).
Очевидно, что отношение удовлетворяет следующим аксиомам:
•α (α α) (рефлексивность);
•α β (α β & β α α = β) (антисимметричность);
•α β γ (α β & β γ α γ) (транзитивность);
•α β (α β β α) (сравнимость).
Таким образом, отношение есть линейный порядок на множестве Sn. Такой порядок называется лексикографическим10. Например, последовательность перестановок из S3, записанная в лексикографическом порядке, имеет вид 123, 132, 213, 231, 312, 321 (здесь перестановки перечислены в порядке возрастания получающихся чисел).
10 В общем случае лексикографический порядок определяется на множестве An
слов конечного алфавита A (с заданным упорядочиванием букв) фиксированной
длины n.
23
Ясно, что тождественная перестановка (1, 2, . . . , n) есть наименьший элемент в (Sn, ) (относительно порядка ), а перестановка (n, n − 1, n − 2, . . . , 1) — наибольший элемент.
В дальнейшем будем использовать следующие очевидные свойства перестановок. Рассмотрим различные элементы i1, . . . , ik {1, . . . , n}
и множество S(i1, . . . , ik) всех перестановок k-элементного множества
{i1, . . . , ik}. На множестве S(i1, . . . , ik) можно также рассмотреть лексикографический порядок .
Лемма 1.
(i)(S(i1, . . . , ik), ) — линейно упорядоченное множество.
(ii)Если α1, . . . , αk {i1, . . . , ik} и α1 > α2 > . . . > αk, то перестанов-
ки (α1, α2, . . . , αk) и (αk, αk−1, . . . , α1) являются наибольшим и наименьшим элементами линейно упорядоченного множества (S(i1, . . . , ik), )
соответственно.
(iii) Если перестановки α, β, γ Sn имеют общее начало длины k и α γ β, то αk+1 ≤ γk+1 ≤ βk+1 и (αk+1, . . . , αn) (γk+1, . . . , γn) (βk+1, . . . , βn).
Рассмотрим метод вычисления номера заданной перестановки в последовательности всех перестановок из Sn, записанных в лексикографическом порядке, т. е. установим соответствие между целыми числами
0, 1, 2, . . . , n! − 1 и n! перестановками из Sn. Для этого индукцией по n
определим отображение
In : Sn → {0, 1, . . . , n! − 1}.
При n = 1 полагаем I1(α) = 0, где α = (1) и S1 = {α}. Пусть отображения Ii : Si → {0, 1, . . . , i! −1}, i = 1, 2, . . . , n −1 уже определены. Для произвольной перестановки α = (α1, . . . , αn) Sn полагаем
In(α) = (α1 − 1)(n − 1)! + In−1(α′),
где α′ — последовательность n−1 элементов, полученная из перестанов24
ки α удалением α1 и уменьшением на единицу всех элементов, больших
α1. Нетрудно доказать, что α′ Sn−1 и In(α) ≤ n! − 1.
Теорема 2. Отображение In : Sn → {0, 1, . . . , n! − 1} есть изоморфизм линейно упорядоченных множеств (Sn, ) и ({0, 1, . . . , n! − 1}, ≤).
Доказательство проведем индукцией по n. Базис индукции при n = 1 очевиден. Предположим, что утверждение теоремы верно для n − 1, и докажем его для n. Конечные множества Sn и {0, 1, . . . , n! − 1}
равномощны. Поэтому если мы покажем, что In является разнозначным отображением, то In есть биекция. Пусть α, β Sn и In(α) =
In(β). Из определения отображения In имеем
In(α) = (α1 − 1)(n − 1)! + In−1(α′),
In(β) = (β1 − 1)(n − 1)! + In−1(β′).
Так как In−1(α′) |
< (n − 1)! |
и In−1(β′) < (n − 1)!, числа In−1(α′) |
|||||
и In−1(β′) |
имеют некоторые (n − 1)-факториальные представления |
||||||
(d ′ |
, . . . , d ′ |
|
) и (d ′ , . . . , d |
′ |
) соответственно. Тогда последователь- |
||
0 |
n−2 |
|
0 |
n−2 |
|
|
|
ность (d0 ′ , . . . , dn−′ |
2, α1 − 1) является n-факториальным представлени- |
||||||
|
|
|
|
|
|
′ |
′ |
ем числа In(α), а последовательность (d0 |
, . . . , dn−2, β1 − 1) есть n- |
факториальное представление числа In(β). Из единственности такого представления получаем α1 = β1. Следовательно, In−1(α′) = In−1(β′)
и α′ = β′ в силу индукционного предположения. Поэтому α = β. Таким образом, In есть биекция.
Докажем, что In — изоморфизм. Достаточно показать, что если
α, β Sn и α β, то In(α) ≤ In(β) (т. е. In сохраняет порядок). Пусть
α β. Тогда α1 ≤ β1. Если α1 ≠ β1, то In(α) ≤ (β1 − 2)(n − 1)! + (n −
1)!−1 = (β1 −1)(n−1)!−1 ≤ In(β). Пусть теперь α1 = β1. Тогда α′ β′, и по индукционному предположению имеем In−1(α′) ≤ In−1(β′). Следовательно, In(α) ≤ In(β). Теорема 2 доказана.
25
Определение 6. Пусть α Sn. Целое неотрицательное число
In(α) называется индексом перестановки α.
Теорема 2 показывает, что In является нумерацией всех перестановок из Sn, упорядоченных в лексикографическом порядке, а индекс
In(α) есть номер перестановки α Sn в этой последовательности. Индуктивное определение индекса перестановки α Sn фактически
задаёт n-факториальное представление (0, . . . , α1′ −1, α1−1) числа In(α), причём по n-факториальному представлению (d0, . . . , dn−1) индекса
In(α) также восстанавливается и сама перестановка α = (α1, . . . , αn).
Опустим формализацию процедуры P ConstrF (d0, . . . , dn−1), осуществляющей такое восстановление перестановки. Теперь мы можем порождать все перестановки из Sn в лексикографическом порядке следующим образом: изменяя индекс i от 0 до n!−1, находим n-факториальное представление числа i и по нему восстанавливаем перестановку.
Алгоритм P Index(n) генерации всех перестановок из Sn по индексам
for i = 0 to n! − 1 do |
|
begin |
% нахождение n-факториального |
F Decomp(n, i); |
% представления (d0, . . . , dn−1) числа i; |
P ConstrF (d0, . . . , dn−1); |
% восстановление перестановки α по |
write(α1, . . . , αn) |
% n-факториальному представлению |
end. |
|
Время работы алгоритма P Index(n) есть Ω(nn!), так как количество итераций for-цикла равно n!, и алгоритм F Decomp(n, i) требует времени
Θ(n). Такая сложность не является оптимальной, в следующем разделе мы познакомимся с линейным алгоритмом генерации всех перестановок из Sn в лексикографическом порядке.
26

1.2.Генерация перестановок в лексикографическом порядке
Будем говорить, что перестановка β Sn непосредственно следует за перестановкой α Sn относительно лексикографического порядка ,
если выполняются следующие условия:
•α β11,
•не существует такой перестановки γ Sn, что α γ β.
При генерации перестановок в лексикографическом порядке, начиная с тождественной перестановки (1, 2, . . . , n), требуется переходить от уже построенной перестановки α = (α1, . . . , αn) к непосредственно следующей за ней перестановке β = (β1, . . . , βn) до тех пор, пока не получим наибольшую перестановку (n, n − 1, . . . , 1) (относительно лексикографического порядка).
Рассмотрим способ построения такой перестановки β. Просматриваем справа налево перестановку α = (α1, . . . , αn) в поисках самой правой позиции i такой, что αi < αi+1. Если такой позиции нет, то α1 > α2 >
. . . > αn, т. е. α = (n, n−1, . . . , 1) и генерировать больше нечего. Поэтому считаем, что такая позиция i есть. Значит, αi < αi+1 > αi+2 > . . . > αn.
Далее ищем первую позицию j при переходе от позиции n к позиции i
такую, что αi < αj. Тогда i < j. Затем меняем местами элементы αi и αj, а в полученной перестановке α′ = (α1′ , . . . , αn′ ) отрезок αi′+1, . . . , αn′ −1, αn′ переворачиваем. Построенную перестановку обозначим через β.
Например, пусть α = (2, 6, 5, 8, 7, 4, 3, 1). Тогда αi = 5 и αj = 7. Поменяем местами эти элементы, перевернём отрезок (8, 5, 4, 3, 1) и получим перестановку β = (2, 6, 7, 1, 3, 4, 5, 8).
Лемма 2. Перестановка β непосредственно следует за перестановкой α относительно лексикографического порядка.
11 , если и ≠ .
27
Доказательство. В силу построения βs = αs′ = αs для любой позиции s < i. Так как βi = αi′ = αj > αi, то α β.
Предположим, что α γ β, и покажем, что γ = α или γ = β.
Так как βs = αs для всех s < i, то из определения лексикографического порядка получаем γs = αs при s < i. Тогда αi ≤ γi ≤ βi = αj в силу леммы 1(iii). Предположим, что αi ≠ γi. Тогда γi {αi+1, . . . , αn}. Но
αj > αi < αi+1 > αi+2 > . . . > αn. Следовательно, γi ≥ αj в силу выбора j. Поэтому γi = αj. Таким образом, αi = γi или γi = βi.
Случай 1. αi = γi. Тогда (αi+1, . . . , αn) (γi+1, . . . , γn) по лемме 1(iii). В силу леммы 1(ii) имеем (γi+1 , . . . , γn) (αi+1, . . . , αn). Поэтому по лемме 1(i) получаем (αi+1, . . . , αn) = (γi+1, . . . , γn). Таким образом, справедливо равенство α = γ.
Случай 2. γi = βi. Покажем, что αi′+1, . . . , αn′ — убывающая последовательность. Действительно, последовательность αi+1, αi+2, . . . , αn
убывает в силу выбора i. Причём αj′ = αi, j > i и αs′ = αs для всех s таких, что s > i и s ≠ j. В силу выбора позиции j получаем
αj′ = αi ≥ αj+1 = αj′ +1, если j < n; αj′ −1 = αj−1 > αj > αi = αj′ , если j > i + 1.
Следовательно, αi′+1, . . . , αn′ — убывающая последовательность. После переворота этой последовательности получим возрастающую последовательность βi+1, . . . , βn. Тогда (βi+1, . . . , βn) (γi+1, . . . , γn) по лемме 1(ii) и (γi+1, . . . , γn) (βi+1, . . . , βn) по лемме 1(iii). Поэтому (βi+1, . . . , βn) = (γi+1, . . . , γn) по лемме 1(i). Таким образом, β = γ.
Лемма 2 доказана.
Перейдем к рассмотрению алгоритма генерации перестановок, в котором применяется описанный способ перестроения перестановки в непосредственно следующую за ней. При программной реализации этого алгоритма используется массив α размерности n + 1. В α1, . . . , αn
записываем текущую порождаемую перестановку из Sn, первоначально тождественную. Значение α0 не изменяется и равно 0, поэтому всегда справедливо неравенство α0 < α1. Это неравенство гарантирует нахож28
дение самой правой позиции i ≥ 0 такой, что αi < αi+1. Алгоритм заканчивает работу, когда значение i становится равным 0.
Алгоритм P Lex(n) генерации всех перестановок в лексикографическом порядке
for j = 0 to n do αj := j; i := 1;
while i ≠ 0 do begin
write (α1, . . . , αn); i := n − 1;
while αi > αi+1 do i := i − 1; j := n;
while αj < αi do j := j − 1;
Swap(αi, αj);
k := i + 1;
m := i + (n − i)/2 ; while k ≤ m do begin
Swap(αk, αn−k+i+1); k := k + 1
end end.
Пример 2. При n = 3 процесс работы алгоритма P Lex(n) генерации перестановок из S3 в лексикографическом порядке представлен следующей последовательностью перестроений перестановок αi:
α1 = (1, 2, 3), αi1 = 2, αj1 = 3; α2 = (1, 3, 2), αi2 = 1, αj2 = 2; α3 = (2, 1, 3), αi3 = 1, αj2 = 3; α4 = (2, 3, 1), αi4 = 2, αj4 = 3; α5 = (3, 1, 2), αi5 = 1, αj5 = 2; α6 = (3, 2, 1), i = 0.
29
Теорема 3. Алгоритм P Lex(n) корректен и строит все перестанов-
ки из Sn без повторений в лексикографическом порядке за время O(n!).
Доказательство. Используя лемму 2, нетрудно обосновать кор-
ректность алгоритма P Lex(n).
Оценим сложность T (n) алгоритма P Lex(n). Рассмотрим разбиение множества Sn на n подмножеств Snk, k = 1, . . . , n. Множество Snk состоит из всех перестановок, на первом месте которых стоит число k. Тогда Snk содержит (n − 1)! перестановок. Относительно лексикографического порядка каждая перестановка из Snk предшествует произвольной перестановке из Snm при k < m, а упорядочивание на Snk соответствует лексикографическому упорядочиванию множества всех перестановок
S({1, . . . , n} \ {k}). Таким образом, последовательность α1, α2, . . . , αn!
всех перестановок из Sn, упорядоченных лексикографически, разбива-
ется на следующие n блоков:
(1, . . .) · · · (1, . . .) · · · (k, . . .) · · · (k, . . .) · · · (n, . . .) · · · (n, . . .) . |
||||||||||||||
| |
|
{z |
|
} |
| |
|
{z |
|
} |
| |
|
{z |
|
} |
|
S1 |
|
|
|
Sk |
|
|
|
Sn |
|
||||
|
|
n |
|
|
|
|
n |
|
|
|
|
n |
|
В силу леммы 1(ii) перестановки (k, 1, 2, . . . , k − 1, k + 1, . . . , n) и (k, n, n−1, . . . , k + 1, k −1, . . . , 1) являются первой и последней перестановкой из Snk соответственно. Введём следующие обозначения:
•tn0 — число операций, выполняемых в алгоритме P Lex(n) до печати перестановки α1;
•tni — число операций, выполняемых в алгоритме P Lex(n), начиная с печати αi и до печати αi+1;
•tnn! — число операций, выполняемых в алгоритме P Lex(n), начиная с печати αn! и до окончания работы программы.
30