- •Анализ алгоритмов (Лекции 2000)
- •Глава 1. Модели вычислений.
- •Глава 3. Перестановки как абстрактный тип данных
- •3.1 Представление перестановок в естественной форме.
- •Var a : array [1..N] of Boolean;
- •Var I, j, k, m:1..N; a:array[1..N] of Boolean;
- •If a[I] then
- •Var I,j:1..N; s:boolean:
- •Var I,j,k:1..N: a:array[1..N] of boolean;
- •If a[I] then
- •3.2 Представление перестановок в циклической форме.
- •Procedure trsl(var f: tpe; var g: tpc);
- •Var I : 1..N; s : Boolean;
- •If a[I] then
- •Procedure u1(var f : tpe; var g : tpk);
- •Var r : real;
- •3.3 Представление перестановок в виде таблицы инверсий.
- •Var I : 0..N; s : Boolean;
- •Var I, j, k : integer;
- •Var c : array [0..N] of 0..1;
- •X : array [1..N] of real;
- •Function ч3 (var r :tpi) : Boolean;
- •Var k, I, j, s, : integer;
- •3.4 Задача о складывании карт.
- •Var I,a,b : integer;
- •Var z:integer;
- •Глава 4. Генерация перестановок
- •4.1Генерация перестановок в лексикографическом порядке.
- •Var р : array [0..N] of 0..N; { текущая перестановка}
- •Var p : array [1..N] of 1..N;
- •Генерация перестановок за минимальное число транспозиций
- •Var I,k : integer;
- •Var p:array [0..N1] of 1..N1;
- •I,j,k,t: integer;
- •Глава 5. Генерация подмножеств множества
- •5.1Генерация подмножеств в лексикографическом порядке.
- •5.2 Генерация подмножеств за счет их минимального изменения.
- •Var s : array [1..N] of 0..1;
- •I : integer;
- •Var s : array [1..N] of 0..1;
- •I,j,k,p : integer;
- •Var t : array [0..N] of 1..N1; {стек}
- •Var t : array [0..N1] of 1..N2;
- •I,p : integer;
- •5.3Генерация мультимножеств.
- •Глава 6. Генерация k-подмножеств
- •Var s : array[1..K] of 1..N;
- •I,p : integer;
- •6.1Генерация k-подмножеств заменой одного элемента.
- •Var I : integer;
- •Var I,m,h:integer;
- •Упражнение. Выполните приведенный алгоритм для деревьв
- •В режиме неполного вычисления
- •Глава 8 Теорема о сложности рекурсивных программ
- •Глава 9 Производящие функции
Var I : 1..N; s : Boolean;
begin s:=true;
for i:=1 to n do
if f[i]>0 then s:=not s;
ч2:=s
end;
Оба алгоритма О2 и Ч2 имеет временную сложность О(n).
Наряду с представлением перестановок в циклической форме с помощью разметки начала циклов, возможна несколько иная форма представления циклических перестановок.
Определение. Будем говорить, что перестановка, представленная в виде разложения на циклы, находится в канонической форме, если:
а) обязательно записываются все циклы;
б) в каждом цикле первым записывается элемент с наименьшим значением;
в) циклы располагаются в порядке убывания значений первых элементов.
Например, f=[3 1 6 7][5 4] представляется как [4 5][2][1 6 7 3].
Скобочная структура в канонической форме может быть опущена, так как первым элементам циклов соответствуют левосторонние локальные минимумы (ak, ikn, является левосторонним локальным минимумом f, если ai<ai, 1i<k).
В приведенном примере перестановка f может быть записана как (4 5 2 1 6 7 3), где круглые скобки указывают, что перестановка представлена в канонической форме.
Упражнение. Пусть f=<a1 ... an>, g=(a1 ... an),n1. Докажите, что fg.
Абстрактный тип ‘перестановка в канонической форме’(TPK) на языке Паскаль может быть описан так
tpk= array [1..n] of 1..n; {описание типа }
и верификационной функцией, совпадающей с верификационной функцией представления перестановок в естественной форме (function TYPEE была описана выше). Заметим, что абстрактные типы TPE и TPK имеют различные семантики.
Рассмотрим алгоритм перевода из естественного представления перестановки в каноническую форму:
procedure CANON(var f : TPE; var g : TPK);
var i,j : 0..n;
a : array [1..n] of Boolean;
procedure B(k : integer);
begin a[k]:=false; {1}
if k<>i then
begin
B(f[k]);
g[j]:=k; j:=j-1; {2}
end
end;
begin for i:=1 to n do a[i]:=true; j:=n;
for i:=1 to n do
If a[I] then
begin {3}
B(f[i]);
g[j]:=i; j:=j-1 {4}
end
end;
Тест: f=<6 2 1 5 4 7 3>
{3} |
i=1 |
j=7 |
|
|
{1} |
i=1 |
j=7 |
k=6 |
a[6]=false |
{1} |
i=1 |
j=7 |
k=7 |
a[7]=false |
{1} |
i=1 |
j=7 |
k=3 |
a[3]=false |
{1} |
i=1 |
j=7 |
k=1 |
a[1]=false |
{2} |
i=1 |
j=6 |
k=3 |
g[7]=3 |
{2} |
i=1 |
j=5 |
k=7 |
g[6]=7 |
{2} |
i=1 |
j=4 |
k=6 |
g[5]=6 |
{4} |
i=1 |
j=3 |
|
g[4]=1 |
{3} |
i=2 |
j=3 |
|
|
{1} |
i=2 |
j=3 |
k=2 |
a[2]=false |
{4} |
i=2 |
j=2 |
|
g[3]=2 |
{3} |
i=4 |
j=2 |
|
|
{1} |
i=4 |
j=2 |
k=5 |
a[5]=false |
{1} |
i=4 |
j=2 |
k=4 |
a[4]=false |
{2} |
i=4 |
j=1 |
k=5 |
g[2]=5 |
{4} |
i=4 |
j=0 |
|
g[1]=4 |
т. е. g = (4 5 2 1 6 7 3)
Работа алгоритма происходит следующим образом. Подобно алгоритму O1, в каждом цикле первым выбирается элемент с наименьшим значением (переменная i в точке {3}), при этом циклы следуют в порядке возрастания наименьших элементов. За счет рекурсивного вызова процедуры B осуществляется движение по каждому конкретному циклу до его замыкания. При этом глубина рекурсии равна числу элементов цикла. По выходу из каждого очередного уровня рекурсии в массив g заносится текущее значение цикла (точки {2},{4}), при этом массив g заполняется, начиная с больших значений индекса.
Нетрудно видеть, что процедура CANON имеет временную сложность О(n).
Упражнения.
-
Напишите вариант алгоритма CANON без использования рекурсии.
-
Напишите процедуру: