Функции, убывающие по ходу выполнения алгоритма

Часто выполнение алгоритма является последовательностью однотип­ных шагов (итераций). Если все шаги равнозатратны по времени, то общее их число с точностью до постоянного множителя эквивалентно временным затратам рассматриваемого алгоритма для данного вхо­да, и важной задачей является определение или хотя бы оценивание числа этих шагов.

Пример 9.1.Пусть а0, а1 —натуральные числа, а01. Поиск наи­большего общего делителя (нод) чисел а0, а1 по алгоритму Евклида требует выполнения серии однотипных шагов, каждый из которых— деление с остатком:

a0 = q1a12, а1 = q2a2 3,

(9.1) ап-3 = Чп-2ап-2 + ап-1

a„-2 = q n-1 a„-1 + a n ,

ап-1 = Чпап.

В этом случае ап = нод(а0, а1), так как

нод(а0, а1) = нод(а1, а2) =... = нод(ап, 0) = ап.

Последовательность получаемых остатков убывает (остаток меньше делителя), при этом все остатки — неотрицательные целые. Не су­ществует убывающей бесконечной последовательности, элементами которой являются неотрицательные целые числа, поэтому выполне­ние алгоритма Евклида (будем обозначать его буквой E) завершается для любых натуральных а0, а1, и число делений с остатком не пре-


§ 9. Функции, убывающие по ходу выполнения алгоритма 75

восходит аг. Обозначив через СЕ0г) исследуемое число делений с остатком, получаем

СЕ(.а01)^а1 (9.2)

(для упрощения записи мы пишем СЕ(,а0г) вместо С^{а0, аг)). Это говорит о том, что если аг рассматривается как размер входа или ес­ли а0, аг рассматриваются как два параметра размера входа, то слож­ность алгоритма Евклида по числу делений не превосходит аг. Как мы увидим, эта оценка является весьма грубой, но, привлекая сход­ные рассуждения, можно получать и более тонкие оценки.

Формализуем те соображения, которые привели нас к этой первой оценке. Каждый шаг алгоритма имеет дело с парой неотрицатель­ных целых {_ъ at) и при условии at ф 0 перерабатывает эту пару в {ahai+1), где ai+1 равно остатку от деления а(_г на at. На множе­стве пар неотрицательных целых чисел к, I мы определяем функцию L(fc,Z), принимающую неотрицательные целые значения. Эта функ­ция такова, что когда при выполнении алгоритма Евклида мы пере­ходим от пары {_ъ at) к паре ь ai+1), значения функции убыва­ют: L{ai_1,ai)>L{ai,ai+1). Так как функция целочисленна, то ее зна­чение убывает с каждым шагом по крайней мере на единицу. От­сюда следует, что общее число шагов не превзойдет значения функ­ции L на исходной паре чисел. Мы рассмотрели функцию L{k,l) = l, и это привело нас к выводу, что число шагов не превзойдет значения Ца01)=а1.

Для обоснования того, что число делений в алгоритме Евклида растет медленнее, чем аъ было бы достаточно найти соответствую­щую функцию I(fc,Z), значения которой при больших к,1 оказывают­ся существенно меньшими, чем Z. Эта функция по-прежнему должна быть определена для любых неотрицательных целых k,l, М Z, прини­мать неотрицательные целые значения и убывать при замене пары М парой I, г, где г — остаток от деления к на Z. Хотя бы одна па­ра целых неотрицательных k,l, к^1, должна обращать L(M) в нуль, иначе вместо L{k,l) можно взять функцию L'(M) = ДМ) - 1 и т.д.

Предложение 9.1.Пусть к,1&П+, к>1, и пусть г —остаток от деления к на I. Тогда

(i) A(fc) > А(г), где, как обычно, А(-) — битовая длина данного числа;

(ii) функция

L(M) = A(fc) + A(Z)-2 (9.3)

такова, что L(k, l) > L(l, r).


76 Глава 3. Оценивание числа шагов (итераций) алгоритма

Доказательство. (i) Имеем k = ql + r, q^l, откуда k ^ l + r > 2r. Следовательно, A(k)>A(r).

(ii) Из A(k) > А(r) следует A(k) + A(l) - 2 > A(l) + А(r) - 2. П

Очевидно, что функция (9.3) неотрицательна. Таким образом, справедлива оценка

CЕ(a0,a1)^А(a0)+А(a1)-2. (9.4)

Но если a0 очень велико в сравнении с aг, то А(a0) + А(aх) - 2 > aг. Тем не менее, теперь для CЕ{a0,aг) уже легко выводится хорошая оценка. Пусть число делений с остатком больше 1. Имеем

CЕ(a0, aг) = CЕ{aъ a2) + 1 s= Х{aг) + А(a2) - 1 s= 2А(aх) - 1.

Оценка

CЕ(a0,a1)^2А(a1)-1, (9.5)

очевидно, верна и в случае единственного деления: CЕ(a0, aг) = 1 при том, что \{aг) ^ 1.

Если взять aг за размер входа {a0,aг), то для сложности по числу делений будем иметь

TЕ{aг) = шах CЕ(a0, a) s= 2А(aх) - 1 = 2Llog? aj + 2 - 1 «S 2 logo aг + 1.

Доказанное нами можно переформулировать так:

Если рассматривать aг как размер входа a0, aг алгоритма Евкли­да, то для сложности TЕ(aх) по числу делений выполнено неравенство

TE(a1)^21og2a1 + l. (9.6)

Эта же оценка имеет место и при рассмотрении двух параметров a0, aг размера входа.

Для достаточно больших aг верхняя оценка (9.6) существенно луч­ше, чем TЕ{aг) s= aг. (Несколько более точная, чем (9.6), оценка дается в задаче 52.)

Рассматривая далее оценки сложности по числу делений алгорит­ма Евклида, мы будем использовать значение aг в качестве размера входа (значение a0 может быть очень большим в сравнении с aъ но первое же деление с остатком приведет к aг,a2, где a2 <aг).

Известно, что алгоритм Евклида допускает разнообразные обоб­щения и расширения. Прежде всего, вместе с нод(a0, aг) можно на­ходить целые s, t такие, что

sa0 + ta1 = HOfl(a0ja1). (9.7)


§ 9. Функции, убывающие по ходу выполнения алгоритма 77

Чтобы это показать, обратимся к (9.1). Пусть уже известны a0,aъ ... ..., ai , 1 ^ i ^ n - 1, и пусть для них найдены множители s0, t0; slstx; ... ...;si, ti такие, что

s0a0 + t0aг=a0, s1a0 + t1a1=a1, ..., si-1a0 + ti-1a1=ai-1, sia0 + tia1=ai.

После выполнения очередного деления с остатком ai-г = qiai + ai+1 имеем ai+1 = ai-x - qiai и

(si --qisiao + Cti --qitia^a^.

Можем положить

si+1=si-1-qisi, ti+1 = ti-1-qiti, i = l,...,n-l; (9.8)

при этом

s0 = l, t0 = 0; s1 = 0, t1 = l. (9.9)

Решение поставленной задачи дают числа

s = sn, t = tn.

В процессе применения этого алгоритма к числам a0 = 39, aг = 15 возникают остатки 9, 6, 3, 0 и соответствующие ненулевым остаткам пары множителей суть 1, -2; -1, 3; 2, -5. Имеем 2 · 39 + (-5) ·15 = 3 = = нод(39,15).

Этот алгоритм мы назовем расширенным алгоритмом Евклида и будем его обозначать буквами ЕЕ, от его английского названия extended Euclidean—расширенный евклидов. Каждый шаг расширен­ного алгоритма Евклида содержит три мультипликативных опера­ции— одно деление с остатком и два умножения.

Если рассматривать aг как размер входа a0, aг расширенного алго­ритма Евклида, то для мультипликативной сложности TЕЕ{aг) этого алгоритма имеем Tш{aг) s=6 log2 aг + 3.

Расширенный алгоритм Евклида дает возможность решать в це­лых числах линейные уравнения с целыми коэффициентами (см. за­дачу 56), он также играет существенную роль в модулярной арифме­тике (см. § 22).

Если дополнить расширенный алгоритм Евклида еще одним ша­гом, то получатся sn+1, tn+1 такие, что

sn+iao + tn+iai = 0. (9.10)

Например, для a0 = 39, aг = 15 имеем s5 = -5, t5 = 13. Легко доказать, что

| si|^|s2|^|s3|, |ti|^|t2|<|t3L (9.11)


78 Глава 3. Оценивание числа шагов (итераций) алгоритма

и при п>2

|s3|<|s4|<...<|sn+1|, |t3|<|t4|<...<|tn+1|. (9.12)

Несколько труднее, но также возможно доказать, что \st | и \tt | взаим­но просты при i = 1, 2,..., п + 1 (см. задачу 57). Из (9.10) и взаимной простоты sn+1 и tn+1 следует

lsn+1l= нод(а0,а1), lf"+1l= нод(а0,а1).

Вместе с (9.11), (9.12) это дает нам

IsJsSd1, \tn\<a0. (9.13)

Эти неравенства пригодятся нам в дальнейшем.

Пример 9.2.Бинарный поиск места (т. е. значения р, 1 ^ р ^ ^ п + 1,—как объяснено в приложении A) элемента у в упорядочен­ном массиве из п элементов х1 < х2 < ... < хп:

р :=1; q :=п + 1; while p<q do

r:= I ^-^ I ; if xr<y then p:=r + 1 else q:=r fi od

Обозначим этот алгоритм буквами BS от его английского названия binary search—бинарный поиск. Будем считать число элементов сег­мента массива длиной этого сегмента (при рассмотрении задач сор­тировки и поиска мы называем сегментом массива любую упорядо­ченную часть xs < xs+1 < ... < xt_1 < xt данного массива). Легко видеть,

что от сегмента длины к мы переходим к сегменту длины 2 или

2 — 1. Это говорит о том, что с каждым шагом алгоритма функция L(fc) = A(fc), где положительное к является длиной сегмента, рассмат­риваемого на данном шаге, убывает по крайней мере на единицу, пока не приходим к сегменту, содержащему один элемент, после че­го еще одно сравнение полностью решает задачу. Отсюда сложность бинарного поиска не превосходит A(n) = Llog2 п\ + 1. Мы видим так­же, что если у меньше минимального элемента рассматриваемого сегмента длины к > 1, то длина сегмента на следующем шаге будет

равна \-2\. Поэтому если изначально у <х1, то в ходе бинарного по­иска будут рассматриваться сегменты длины


п l-l2 2 , 2

n,2 i2^,...,1


§ 9. Функции, убывающие по ходу выполнения алгоритма 79

соответственно (битовая длина каждого следующего элемента после­довательности на единицу меньше битовой длины предыдущего), и в целом потребуется в точности A(n) = Llog2 n\+ 1 сравнений. Исполь­зуя утверждение, содержащееся в задаче 2, мы можем сформулиро­вать установленное свойство бинарного поиска так:

Сложность TBS (n) бинарного поиска места элемента в массиве дли­ны n по числу сравнений равна Llog2 n\+ 1, или, что то же самое, [log2(n + l)l.

Выражение |"log2(n + l)lдля указанной сложности иногда бывает удобнее, чем Llog2 n\+ 1, потому что оно имеет смысл и в вырожден­ном случае n = 0.

Бинарный поиск находит широчайшее применение при поиске ин­формации в разнообразных таблицах. Укажем здесь еще одно его применение, касающееся вычислительной геометрии: он позволяет быстро определять, принадлежит ли произвольная точка Q выпук­лому n-угольнику, заданному вершинами PЪP2, ...Pn. Можно легко построить какую-нибудь внутреннюю точку O данного n-угольника. В силу его выпуклости точка Q — внутренняя, если и только если Q и O лежат в одной полуплоскости относительно любой из прямых PгP2, ...,Pn_1Pn,PnP1. Это соображение приводит к имеющему времен­ную сложность 6(n) алгоритму. Но допустим, что проведены n доба­вочных лучей (рис. 12), исходящих из точки O и проходящих через



Q

 


Рис. 12. Точка Q лежит между двумя лучами, проведенными из внутренней точки O многоугольника через его вершины.

вершины (считаем, что O = Q, иначе мы сразу бы заключили, что Q принадлежит многоугольнику). Можно установить, какому из углов ∠P1OP2, ..., ∠Pn1OPn, ∠PnOP1 принадлежит точка Q: если углы прону-


80 Глава 3. Оценивание числа шагов (итераций) алгоритма

мерованы в указанном порядке, то бинарным поиском определяется номер m угла, 1 ^ m ^ n; при этом если Q лежит на одном из про­веденных лучей, то из двух значений m берется любое. Узнав m, мы проверяем согласованность расположения точек O и Q по отношению к прямой, являющейся продолжением той стороны многоугольника, концы которой лежат на сторонах m-го угла.

Теперь заметим, что в самом проведении лучей OPъOP2, ...,OPn нет необходимости: сравнение Z.PxOQ с LPxOPi требует ограниченно­го числа операций и в том случае, когда нам лишь известны коорди­наты точек O,Q,P1,Pi.

Основывающийся на бинарном поиске алгоритм распознавания принадлежности точки выпуклому n-угольнику имеет сложность O(logn) по общему числу операций и пространственную сложность O(1).

Полезным для решения ряда задач является то обстоятельство, что если точка не принадлежит данному выпуклому n-угольнику, то с по­мощью этого алгоритма мы дополнительно определяем одну из сто­рон n-угольника, которая из этой точки видна целиком (рис. 13).



Q


Рис. 13. Для точки Q, не принадлежащей данному выпуклому n-угольнику, находим сторону n-угольника, которая из Q видна целиком.

Пример 9.3.Установим число этапов слияния при сортировке, предложенной Дж. фон Нейманом (которая является одним из вари­антов сортировки слияниями). При сортировке фон Неймана шаг за шагом происходят переброски элементов исходного массива в допол­нительный массив и наоборот, и каждая переброска сопровождает­ся слиянием соседних сегментов массива (рис. 14). В данном слу­чае в качестве вспомогательного размера массива удобно рассмот­реть k— число сегментов (первоначально k = n, затем, шаг за ша­гом, k довольно быстро убывает). При анализе бинарного поиска места элемента мы фактически использовали, что если 2m~1 ^ k < 2m,


§ 9. Функции, убывающие по ходу выполнения алгоритма 81

а) б) в)