- •Анализ алгоритмов (Лекции 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 Производящие функции
логических
выражений оператор
repeat можно
заменить
оператором
while
(sp[k]=nil)
or (sp[k].r<>nil)
do k:=k+1;В режиме неполного вычисления
rab:=false;
if sp[k]=nil then k:=k+1
else
if sp[k]^.r<>nil then k:=k+1
else rab:=true
until rab;
a:=sp[k]^.i; pr[j]:=a;
sp[k]:=nil;
x:=sp[a];
while ( x^.i<>k) do begin y:=x; x:=x^.r end;
if sp[a]=x then sp[a]:=x^.r else y^r:=x^.r
end ;
end{inpruff};
Процедура восстановления дерева по коду Прюфера выглядит так:
procedure outpruff; {преобразует код Прюфера в список смежности }
procedure bk(var a,b:integer); {включить вершины a,b в список смежности}
begin new(x); new(y);
x^.i:=a; x^.r:=sp[b]; sp[b]:=x;
y^.i:=b; y^.r:=sp[a]; sp[a]:=y
end{bk};
begin{ outpruff }
for i:=1 to n do sp[i]:=nil; pr[0]:=n;
a:=pr[n-2];
if a=n then i:=n-1 else i:=n; bk(a,i);
for j:=n-2 downto 1 do
{1} if sp[pr[j-1]]=nil then bk(pr[j-1],pr[j])
else begin while sp[i]<>nil do i:=i-1;
bk(i,pr[j])
end
end{outpruff};
Комментарий. Нулевой элемент в описании типа pru введен для корректного вычисления, в случае j=1, логического выражения в условии оператора {1}. В массиве pr, используемого процедурой outpruff в качестве значения кода Прюфера, нулевому элементу присвоено значение равное n.
Замечание. Код Прюфера является оптимальным по памяти кодирования деревьев. В самом деле, W =Wn, где Wn – конечные множества. Предположим, что при каком-то способе кодирования элементов из W для запоминания одного элемента из Wn используется самое большое f(n) бит памяти. Кодирование f(n) называется оптимальным, если =1, где h(n) = log2 Wn.
Для оценки энтропия h(n) для множества деревьев с n вершинами по теореме Кэли имеем h(n) = (n-2)log2n. Отсюда следует, что кодирование деревьев кодом Прюфера необходимо f(n) = (n-2)log2n , бит памяти, и поэтому =1.
При задании дерева списками смежности имеем =3 для неориентированных графов, и =2 для ориентированных.
В. А. Евстигнеев. Применение теории графов в программировании. Наука. 1985.
Статистическая теория деревьев (по А. Реньи).
Начнем со следующего вопроса: сколько висячих вершин может быть у дерева с n вершинами? На первый взгляд ответ кажется тривиальным. Число t висячих вершин всегда удовлетворяет неравенству 2tn-1, причем как предельные случаи (прямолинейный маршрут и звезда), так и все промежуточные случаи осуществимы. Но такой ответ на поставленный нами вопрос нельзя считать исчерпывающим. Действительно, если число n очень велико, то среди огромного числа возможных конфигураций (напомним, что существует nn-2 вариантов строения помеченных деревьев с n вершинами) предельные случаи t=2 и t=n-1 крайне редки: случай t=n-1 встречается только n раз, а случай t=2 встречается n!/2 раз. Хотя число n!/2 само по себе велико, оно все же (как следует из формулы Стирлинга) очень мало по сравнению с nn-2. Учитывая это, поставим наш вопрос несколько иначе: сколько помеченных деревьев с n вершинами имеют ровно t висячих вершин? В частности, сколько помеченных деревьев с n вершинами обладают наибольшим числом висячих вершин? В новой постановке наш вопрос можно сформулировать также следующим образом: если nn-2 различных помеченных деревьев с n вершинами сложить в большую шляпу и вытягивать их оттуда наугад по одному, каждый раз подсчитывая у извлеченного дерева число висячих вершин, то с какой вероятностью будет встречаться то или иное число? Более кратко тот же вопрос можно поставить и так: сколько висячих вершин у “типичного” дерева с n вершинами?