
- •§ 8. Диафантовы множества.
- •Теорема Лагранжа.
- •8.1. Разрешимость в натуральных числах.
- •Определение.
- •Определение.
- •Теорема 8.1.
- •Теорема 8.2.
- •Необходимость.
- •Достаточность.
- •8.2. Нумерация кортежей.
- •Канторова нумерация.
- •Геделево кодирование.
- •Определение.
- •Теорема 8.3.
- •Теорема 8.4.
- •Определение.
- •0.2. Машина с неограниченными регистрами (мнр) [Ктл, c.16]
- •0.3. Равнодоступные адресные машины (рам) [Ахо, с.22]
- •Типы операндов.
- •Команды.
- •0.4. Интерпретация программы как функции.
- •0.6. Вычислительная сложность рам-программ.
- •Определение.
- •Определение.
- •Определение.
- •Логарифмический критерий.
- •0.7. Модификации рам.
- •0.8. Неветвящиеся программы и равномерный весовой критерий.
- •Определение.
- •0.9. Неветвящиеся программы и логарифмический весовой критерий.
- •0.10. Ветвления.
- •0.11. Операции с двоичными векторами фиксированной длины. Определение.
- •Определение.
- •0.12. Машина Тьюринга (k-ленточная).
- •Определение.
- •Определение.
- •0.13. Связь мт и рам.
- •Теорема 0.1.
- •Утверждение 1.
- •Утверждение 2.
- •§ 1. Структуры данных. Определение.
- •1) Вставка.
- •2) Удаление.
- •1.1. Очередь и стек. Определение.
- •Определение.
- •1.2. Множества. Представление множеств.
- •1) Применение списков.
- •3) Представление в виде массивов.
- •4) Представление в виде графа.
- •Определение.
- •Определение.
- •§ 2. “Разделяй и властвуй”.
- •Теорема 2.1
- •§ 3. Динамическое программирование
- •Алгоритм 3.1.
- •§ 4. Редактирующее расстояние
- •Алгоритм 4.1.
- •Алгоритм 4.2.
- •§ 5. Порядковые статистики Определение.
- •Алгоритм 5.1
- •Теорема 5.2.
- •§ 6. Вхождение образца
- •Определение.
- •Алгоритм 6.1a.
- •Алгоритм 6.1б. Вычисление функции отказов.
- •Теорема 6.2.
- •Алгоритм 6.1.Б вычисляет f за o(n) шагов.
- •Конец пока
- •Алгоритм lz
- •Дельта – алгоритм
- •Арифметическое кодирование
4) Представление в виде графа.
Обозначим : G = < V, E > неориентированный граф,
G = < V, A > ориентированный.
Пусть p = V, q = E.
a) Матрица смежности
Если граф без кратных ребер и петель, то A: array [ 1..p, 1..p] of 0..1.
Время, необходимое для определения наличия ребра, O( 1 ).
Недостатки:
1) Размер матрицы по памяти O( p2)
2) Начальное заполнение требует времени O( p2), что сводит на нет алгоритмы сложности
O( p ) при работе с графами, содержащими только O ( p ) ребер.
б) Списки смежности.
Определение.
Списком смежности для узла v называется список всех узлов w, смежных с v.
Граф можно представить с помощью p списков смежностей, по одному для каждого узла.
Пример:
2
Размер требуемой памяти O ( p + q).
Представлением с помощью списков смежностей часто пользуются когда q << p2.
в) Деревья
Определение.
Дерево это связный ациклический граф.
Представление двоичных деревьев:
1. В виде двух массивов: LeftSon и RightSon. Пусть узлы двоичного дерева занумерованы
целыми числами 1..n.
LeftSon [ i ] = j тогда и только тогда, когда узел с номером j является левым сыном узла с номером i. LeftSon [ i ] = 0, если у узла i нет левого сына. RightSon [ i ] определяется аналогично.
Хорошо для небольших деревьев.
§ 2. “Разделяй и властвуй”.
Для решения той или иной задачи ее часто разбивают на части, находят их решения и затем из них получают решение всей задачи. Этот прием ( Divide & Conque ) , особенно если его применять рекурсивно, часто приводит к эффективному решению задачи, подзадачи которой представляют собой ее меньшие версии.
Пример 1.
Задача о нахождении наибольшего и наименьшего элементов множества S, S = n.
Пусть n = 2k.
1) Будем искать наибольший и наименьший элементы по отдельности.
Процедура Max находит наибольший элемент множества S, произведя n-1 сравнений его элементов.
procedure Max
begin
s0 = произвольный элемент из S;
MAX x0;
for ( s S \ { x0 } ) do
if x > Max then Max x;
end;
Аналогично можно найти наименьший элемент из остальных n - 1 элементов, произведя n - 2 сравнений.
Итак, для нахождения наибольшего и наименьшего элемента множества при n 2 потребуется 2n - 3 сравнений.
2) “Разделяй и властвуй”.
( int , int ) procedure MAXMIN ( S )
begin
if ( ||S|| == 2) then return (MAX( a, b), MIN(a, b)); else
begin
S = S1 S2; /* || S1 || || S2 || */
(max1, min1) = MAXMIN ( S1);
(max2, min2) = MAXMIN ( S2);
M: return (MAX ( max1, max2 ), MIN ( min1, min2 ));
end;
end;
Сложность этого алгоритма:
Пусть T( n ) число сравнений в процедуре MAXMIN, чтобы найти наибольший и наименьший элемент n-элементного множества.
T( 2 ) = 1
Если n > 2, то T( n ) - общее число сравнений, произведенных в двух вызовах процедуры MAXMIN, работающей на множествах размера n/2, и еще два сравнения в строке с меткой M.
Итак,
То есть T ( n ) = 3/2 n-2.
Можно показать, что для одновременного нахождения наибольшего и наименьшего элементов
n-элементного множества надо сделать не менее 3/2 n-2 сравнений его элементов. Следовательно, алгоритм процедуры MAXMIN оптимален в смысле числа сравнений между элементами из S, когда n = 2k.
В примере 1 прием “Разделяй и властвуй” позволил уменьшить число сравнений в фиксированное число раз. Но для рекурсии требуется стек, поэтому в памяти мы проиграли.
Пример 2. Умножение n-разрядных двоичных чисел.
-
Традиционный метод ( умножение “в столбик”) требует OБ( n2) битовых операций.
-
Следующий алгоритм типа “разделяй и властвуй” требует O ( n log 3).
Пусть n = 2k.
x, y - два n-разрядных числа.
Разобьем x и y на две равные части.
Если рассматривать каждую из этих частей как ( n/2 )-разрядное число, то можно представить произведение чисел x и y в виде
xy = ( a2 n/2 + b) ( c2 n/2 + d) = ac2n + ( ad + bc ) 2n/2 + bd.
Это равенство дает следующий способ вычисления z = xy:
begin
u ( a + b) * ( c + d );
v a * c;
w b * d;
z v * 2n + ( u - v - w ) * 2 n/2 + w;
end;
Будем считать, что числа a + b и c + d состоят из (n/2) разрядов. Изложенная схема для умножения n-разрядных чисел требует только трех умножений (n/2)-разрядных чисел и нескольких сложений и сдвигов. Для вычисления u, v, w можно применять эту программу рекурсивно. Сложения и сдвиги занимают OБ( n ) времени. Следовательно, временная сложность умножения двух n-разрядных чисел ограничена сверху функцией
a,
n=1
(*)
T (n)
=
3T
(n/2) +
an , n
> 1
где a - постоянная, отражающая сложение и сдвиги.
Можно показать, что T ( n ) = 3an log 3 - 2an.
ММИ по n, где n - степень числа 2.
1. Базис
n = 1 – тривиально.
2. Пусть T ( n ) = 3anlog 3 - 2kn удовлетворяет () при n = m.
Тогда T ( 2m ) = 3T ( m ) + 2am = 3[ 3anlog3 - 2an ] + 2am = 3a(2m)log3 - 2a ( 2m ).
Таким образом , T ( n ) удовлетворяет () и при n = 2m.
Отсюда следует, что T ( n ) 3anlog3.
Учтем, что числа a, b, c, вообще говоря, имеют n/2+1 разрядов. Поэтому произведение (a+b)(c+d) нельзя вычислить непосредственным применением нашего алгоритма к задаче размера n/2.
Запишем :
a + b = a12n/2 + b1, где a1 = 0 или 1 .
c + d = c12n/2 + d1, где c1 = 0 или 1.
Тогда
( a + b )( c + d ) = a1 c12n + (a1d1 + b1 c1 ) 2n/2 + b1d1. ()
Слагаемое b1d1 вычисляется с помощью рекурсивного применения нашего алгоритма умножения к задаче размера n/2. Остальные умножения в () можно сделать за время OБ (n), так как они содержат в качестве одного из аргументов либо единственный бит a1 или c1, либо степень числа 2.
При анализе рекурсивных алгоритмов типа “ разделяй и властвуй ” часто возникают рекуррентные уравнения следующего вида
() - это общая
рекурсивная формула при разбиении
задачи на a подзадач в c раз
меньше, причем слагаемое bn - линейное
время на слияние.