Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Теория алгоритмов. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
☆
5.1. Введение в теорию сложности вычислений
Рисунок 2
, , , , z y, , xyyzxzzxyx
y z
Рисунок 2
, , , , z y, , xyyzxzzxyx
z
y
z
y z
zx
zx
y
zx
yx
z x
y
zx
yx
z x
y
z x
y
zx
yx
yz
z x
y
z x
y
кое именно кольцо нужно перекладывать, так как мы мо­жем по условию взять только самое верхнее кольцо.
Нетрудно догадаться, что для того чтобы перенести пирамидку из двух колец необходимо совершить следую­щие перекладывания:
Рисунок 3
— 151 —
z x
Глава 5. ВВЕДЕНИЕ В ТЕОРИЮ СЛОЖНОСТИ АЛГОРИТМОВ
( )
( )
Наша задача — показать, как можно переместить лю­бое количество колец со стержня x на стержень y, соблю­дая указанные выше правила.
Пусть на стержне x находиться три кольца. Временно забудем про нижнее, самое большое кольцо. Тогда останет­ся пирамидка из двух колец, которую мы уже умеем пере­кладывать. Давайте переместим ее со стержня x на стер­жень z. (Это делается за несколько шагов, но для нас сейчас это как бы один шаг.) После этого вспомним про са­мое большое кольцо, лежащее на стержне x, и переложим его на стержень y, который пока пуст. Теперь, если опять забыть про самое большое кольцо, лежащее на стержне y, мы можем переместить два кольца со стержня z на стер­жень y. Все эти действия изображены на рис. 4.
Можно считать, что у нас есть процедура переклады­вания двух колец, которую мы вызываем дважды.
Далее, используя перекладывание трех колец, мы мо­жем переложить четыре кольца со стержня x на стержень y (достаточно заменить на рис. 4 пирамидку из двух колец на пирамидку из трех).
После этого можно переложить пять колец, используя перекладывание четырех колец и т.д.
Выше изложенное можно оформить в виде рекурсив­ной процедуры
,,,Hanoi n x y z
Hanoi n x y z
0 1
if n then x y
>→
Описанная процедура (ее корректность мы доказали выше) показывает, что головоломка «Ханойские башни» имеет решение, и на ее основе мы можем написать про­грамму для компьютера, которая укажет какие именно пе­рекладывания мы должны совершать.
  
Hanoi n z y x
1, , ,
−
1, , ,
−
( )
— 152 —
( )
5.1. Введение в теорию сложности вычислений
y
y
z x
y
z y x
x
Рисунок 4
— 153 —
z
z x
Глава 5. ВВЕДЕНИЕ В ТЕОРИЮ СЛОЖНОСТИ АЛГОРИТМОВ
=
( )
( )
21
+
21
= +
= =+>
1
21
nn
≥+

Теперь определим число выполненных нами перекла­дываний при переносе n колец, если мы будем следовать процедуре (1).
Обозначим это число через nt . Если 0n=, то процеду­ра (1) сразу завершает свою работу. Следовательно, 00t
.
Предположим, что 0n>. Тогда для того чтобы пе­ренести n колец со стержня x на стержень y, следуя ука­заниям (1), мы должны сделать nt перекладываний. При этом мы должны поступать следующим образом. Сначала перенести
1n − кольцо со стержня x на стержень z. Для
этого нам потребуется 1nt− перекладываний, поскольку за указаниями, каким образом нам это сделать, мы обра­щаемся к процедуре (1). Далее мы перекладываем одно кольцо со стержня x на стержень y и после этого снова обра­щаемся к процедуре (1) за указаниями, как нам перенести
1n − кольцо со стержня z на стержень y. Указания мы по-
лучили. Следуя им, мы совершаем 1nt− перекладываний. Очевидно, всего мы совершали Следовательно,
tt
nn
1
−
.
перекладываний.
1
nt−
Таким образом, оценивая эффективность рекурсивной процедуры (1), мы приходим к рекуррентному соотноше­нию
0
t
0
2 1, 0.
tt n
nn
1
−
Попробуем узнать, можем ли мы за реальное время пе­реложить, например, 64 кольца?
Пусть nt — наименьшее число перекладываний, кото­рые необходимо совершить, чтобы перенести n колец.
Проводя индукцию по n покажем что
tt
для любого n ≥ 1.
−
Базис индукции. Если колец нет, то и перекладывать ничего не надо, а для перекладывания одного кольца необ­ходимо одно перекладывание, т.е.
— 154 —
5.1. Введение в теорию сложности вычислений
01
0 1.tt= =
nn
tt
≥+

21

0t =
=+>
и
Шаг индукции. Предположим, что нам требуется
перенести n+1 кольцо. Очевидно, перенести самое боль­шое кольцо можно только, если выполнены два условия: на нем нет ни одного кольца и имеется пустой стержень, на который его можно одеть. Однако для этого все осталь­ные кольца должны быть одеты на каком-нибудь одном стержне. Наименьшее число перекладываний, необходи­мых для достижения такого расположения, мы обозначи­ли через nt. Поэтому достигнуть того, чтобы все кольца, кроме самого большого, были одеты на один стержень, менее чем за nt перекладываний мы не можем. Потом мы должны одеть самое большое кольцо на имеющийся пустой стержень; меньше чем за одно перекладывание сделать этого нельзя. Но после этого мы должны на стер­жень с одетым на нем большим кольцом одеть оставшиеся n колец, что также требует не менее чем nt перекладыва- ний. Следовательно,
2 1.
1
+
Однако nt
— это наименьшее число перекладываний,
поэтому
tt
= +
nn
для любого n ≥ 1, что вместе с
1
−
дает рекуррентное со-
0
отношение
0,
t
=
0

2 1, 0.
tt n
nn
1
−
Таким образом, для n=64, меньше чем за t64 перекла­дываний перенести 64 кольца нельзя, а за t64 перекладыва­ний мы сделать это сможем, если будем следовать указани­ям процедуры (1).
С помощью компьютера легко установить, что t64 ~ 1019. Теперь если предположить, что за одну секунду перекла­дывать одно кольцо, то 64 кольца можно переложить
— 155 —
Глава 5. ВВЕДЕНИЕ В ТЕОРИЮ СЛОЖНОСТИ АЛГОРИТМОВ
приблизительно за 316 231 532 тыс. лет, что в реальное время недостижимо.
Таким образом, различают реально выполнимые и ре-
ально не выполнимые алгоритмы.
Задача называется полиномиальной, если для ее ре-
шения существует полиномиальный алгоритм.
Задача называется экспоненциальной, если ее нельзя
решить за полиномиальное время.
В практических вычислениях основной вопрос отно­сительно функции f состоит не в том, вычислима ли f, а скорее в том, вычислима ли f практически. Другими словами, существует ли алгоритм, вычисляющий функ­цию f за полиномиальное время (или в том объеме па­мяти), которым мы располагаем? Ответ отчасти зависит от мастерства в написании программ и возможностей ком­пьютеров, но интуитивно понятно, что имеется дополни­тельный фактор, который можно назвать «внутренней сложностью функции f». Исследованием подобных вопро­сов занимается теория вычислительной сложности (ТВС), о которой мы будем говорить в этой главе.
Развитие ТВС по существу началось с появлением первых ЭВМ. С того момента интерес многих специалистов по абстрактной теории алгоритмов начал постепенно сме­щаться от вопросов существования алгоритмов для тех или иных алгоритмических задач к изучению их эффек- тивности и пригодности с практической точки зрения. Этот переход во многом стимулировался пониманием того, что даже для наиболее базисных задач эти две вещи — дале­ко не одно и то же.
Например, имеются универсальные алгоритмы, позво­ляющие проверять истинность любого утверждения про вещественные числа (которые можно записать в стандарт­ном языке математической логики первого порядка — от­метим, что путем введения декартовых координат к такому
— 156 —
5.1. Введение в теорию сложности вычислений
виду можно привести, например, любую задачу элемен­тарной геометрии). Первый такой алгоритм был придуман известным логиком А. Тарским ещё в 1948 г. Однако алго­ритм Тарского оказался неэффективен со всех мыслимых
точек зрения, а в 1974 г. было строго доказано, что время работы любого алгоритма для этой задачи по крайней мере экспоненциально от длины исходного утверждения.
Этот пример относится к области применения ЭВМ, считавшейся в 60-е годы чуть ли не единственной, и кото­рую условно называют классические вычисления, в наибо- лее широком смысле этого термина. Отличительными свой­ствами классического вычисления является традиционная схема
Программа Р + входные данные х => вычислительное
устройство =>ответ Р(х)
и отсутствие интерактивности.
Другими словами, классическое вычисление — это все, для чего каждый программист может использовать та­кие почтенные языки как АЛГОЛ или PASCAL ABC и не испытывать при этом существенных неудобств.
Строгие математические модели, позволяющие из­учать внутреннюю сложность алгоритмических задач (и доказывать про неё нетривиальные результаты) были соз­даны в 60-е годы, и относились к классическим вычисле­ниям.
В дальнейшем при изложении ТВС мы будем придер­живаться понятия вычислимости в классическом вариан­те.
При построении математических моделей изучения внутренней сложности алгоритмических задач в качестве наиболее существенных факторов берутся следующие принципы:
— 157 —
Глава 5. ВВЕДЕНИЕ В ТЕОРИЮ СЛОЖНОСТИ АЛГОРИТМОВ
MM
tn Tx
( )
tn
( )
tn
( )
tn
( )
tn
Первый принцип. При фиксированном размере вход-
ных данных п сложность алгоритма (в этой роли чаще все­го выступают время работы, используемая память и т.д.) измеряется «в наихудшем случае», т.е. берется максимум по всем входным данным длины п. Допускается, что для большинства разумных (полиномиальных) алгоритмов ка­чество их работы не должно сильно зависеть от структуры исходных данных (коль скоро известна их битовая длина), а если это оказывается не так, то, скорее всего, плоха изна­чальная постановка задачи (не учтена какая-либо важная специфика). Наиболее известное исключение: симплекс-ме­тод, который хорошо работает для большинства задач ли­нейного программирования, но требует экспоненциальных по п числу итераций в отдельных патологических случаях.
При этом для оценки сложности алгоритма исполь­зуется так называемый подход «сложности в наихудшем случае» определяемый следующей формулой:
def
max
=
( ) ( )
xn
≤
где х — битовая длина двоичного слова х.
Из всех слов битовой длины, не превышающей n, вы­бираем то, на кото ром наша машина работает хуже всего (т.е. дольше всего). Время работы на таком слове и назы­ваем сложностью
M
. За время
машина гаранти-
M
рованно закончит работу на любом входном слове длины, не превышающей п. Может, конечно, случиться, что на ка­ких-то словах работа завершится раньше.
Иными словами, сложность в наихудшем случае
гарантирует исследователям, что вычисление за-
M
кончится за это время на любом входном слове х, коль ско­ро битовая длина последнего не превышает п.
Практика показывает, что на уровне функции
M
возможно успешное построение математической теории для сравнения сложности различных алгоритмов.
— 158 —
5.1. Введение в теорию сложности вычислений
**
( )
tn
M
′
( ) ( )
MM
t n tn
Пусть теперь имеется алгоритмическая задача, запи-
санная в виде задачи вычисления отображения
: 0,1 0,1f →
{ } { }
множества конечных двоичных слов любого размера в себя.
Если для каждой вычислимой функции f существует вычисляющий ее алгоритм М, оптимальный с точки зре­ния асимптотического поведения сложности в наихудшем случае
, то дальнейшее построение теории сложности
M
можно существенно упростить. Однако, по теореме об уско­рении — это невозможно, т.е. существуют вычислимые
функции f , для которых любой алгоритм ее вычисления может быть произвольно ускорен.
Мы приводим упрощенный вариант теоремы об уско­рении: на самом деле, вместо log в ней можно взять любую сколь угодно быстро растущую вычислимую функцию.
Теорема. Существует такая вычислимая функция f , что любую машину М, вычисляющую f , можно ускорить следующим образом: существует другая машина же вычисляющая f и такая, что
log
≤ для поч-
′
, так-
ти всех п.
Теорему об ускорении Блюм доказал с помощью диа­гонального метода, и получающаяся функция не имеет ни­какого отношения к реальной практике вычислений.
Доказательство теоремы об ускорении достаточно сложно, однако чтобы продемонстрировать технику, ис­пользуемую при ее доказательстве, докажем следующую теорему.
Теорема. Для любой всюду определенной вычислимой функции g можно построить всюду определенную вычис­лимую функцию f, принимающую значения 0 и 1 и име­ющую такую сложность, что любая машина, которая вы­числяет f(n), делает больше чем g(n) шагов для бесконечно многих значений n.
— 159 —
Глава 5. ВВЕДЕНИЕ В ТЕОРИЮ СЛОЖНОСТИ АЛГОРИТМОВ
( )
fn m
( )
( )
( )
Доказательство. Дана функция g, а функция f должна
быть определена. В нашем случае она определяется с помо­щью диагонального метода. Для вычисления f(n) имитиру­ется n-я машина nZ на выходе n. Если nZ останавливается менее чем за g(n) шагов с некоторым выходом m, полагаем
≠ . В противном случае f(n) может быть определена
произвольно.
Тогда любая машина iZ , которая делает на входе i меньше чем g(i) шагов, не может вычислять f. Но каждая машина встречается в приведённом выше списке бесконеч­но много раз (или мы можем так изменить список, чтобы добиться этого), в частности, бесконечно много раз встре­чается каждая машина, вычисляющая f.
Второй принцип. Алгоритмы изучаются с точки зрения их асимптотической сложности, т.е. когда п стремится к бес­конечности. Допускается, что асимптотическое поведение в подавляющем большинстве случаев адекватно отражает поведение алгоритма для тех малых значений п, которые на самом деле представляют интерес. Например, ожидается, что разумный алгоритм, работающий за время окажется и на практике лучше
Наиболее известное исключение: быстрые алгоритмы перемножения матриц. Именно, п х п матрицы можно пе­ремножать, используя лишь подразумеваемая под О, мультипликативная константа настолько велика, что алгоритм имеет смысл лишь для астрономических значений п.
Условно справедлива такая формула:
<общее время> = <число операций> · <время на одну
операцию>
Улучшение обоих членов в этой простой формуле — вещи более-менее независимые. Грубо говоря, программы (software) отвечают за первый сомножитель, а процессоры (Hardware) — за второй.
— 160 —
2
On — алгоритма.
2.376
On умножений, однако,
logOn n ,
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]