
- •Предисловие
- •Введение
- •Алгоритмы и их сложность
- •Примеры задач и алгоритмов
- •Задачи на графах: «Коммивояжер», «Кратчайшие пути», «Остовные деревья»
- •Приближенные алгоритмы: «Составление расписаний»
- •«Сортировка слиянием»
- •«Быстрая сортировка»
- •Формально об алгоритмах. Несложно о сложности
- •«RAM»: машины с произвольным доступом
- •Сложность в худшем случае
- •Сложность в среднем
- •Полиномиальные алгоритмы
- •Полиномиальность и эффективность
- •Аппроксимация с гарантированной точностью
- •Алгоритмы с оценками точности
- •Жадные алгоритмы для «Покрытия множеств»
- •Приближенные алгоритмы для «Вершинного покрытия»
- •Жадный алгоритм для «Рюкзака»
- •Алгоритм Кристофидеса
- •Аппроксимация с заданной точностью
- •«Рюкзак»: динамическое программирование
- •Полностью полиномиальная приближенная схема для «Рюкзака»
- •Вероятностный анализ детерминированных алгоритмов
- •Сложность и полиномиальность в среднем
- •Задача упаковки
- •Выполнимость КНФ
- •Точность алгоритма для почти всех входов
- •«Рюкзак»: полиномиальность в среднем
- •Вероятностные алгоритмы и их анализ
- •Вероятностная проверка тождеств
- •Максимальное по включению независимое множество в графе
- •Протокол византийского соглашения
- •Вероятностное округление
- •Максимальный разрез в графе
- •Методы дерандомизации
- •Метод условных вероятностей
- •Метод малых вероятностных пространств
- •Полиномиальная проверка простоты
- •Основы теории сложности вычислений
- •Сложность вычислений
- •Машины Тьюринга и вычислимость
- •Сводимость по Куку
- •Недетерминированные алгоритмы
- •Сводимость по Карпу
- •Вероятностные вычисления
- •Вероятностно проверяемые доказательства
- •Схемы и схемная сложность
- •Коммуникационная сложность
- •Диаграмма классов сложности
- •Приложения
- •Введение в Python
- •Глоссарий
- •Предметный указатель
- •Список алгоритмов

Глава 7
Приложения
7.1Введение в Python
Краткое введение в язык Python для понимания представленных на нем алгоритмов.
Вообще, трудно найти другой такой язык, одновременно пригодный для обучения, с одной стороны, и достаточно мощный для реализации реальных приложений (включая научные) — с другой. Дело в том, что автор Python’а (Guido van Rossum) долгое время участвовал в проекте создания языка обучения программированию ABC, который должен был заменить BASIC, и вынес из проекта несколько ценных идей, как минимизировать синтаксические накладные расходы, которые необходимы в реальном языке программирования (сложные декларации, открытия/закрытия блоков), избежав при этом каббалистического минимализма — понятной только адептам магии спецсимволов типа «%$ˆ») Perl’о-подобных языках.
337
338 |
Глава 7. ПРИЛОЖЕНИЯ |
В Python’е была применена идея синтаксического выделения блоков с помощью отступов (в пределах блока отступ должен быть одинаков), кроме того, операторы, начинающие вложенный блок, должны для повышения читаемости отделяться двоеточием:
i f l e n ( EP ) > 0 : |
|
|
|
||
f o r i i n x r a n g e ( l e n ( EP ) ) : |
|
||||
|
|
i f G . degree ( EP [ i ] ) > 0 : |
|
||
|
|
v = EP [ i ] |
|
|
|
e l s e : |
|
break |
|
|
|
|
|
# |
|
|
|
v |
= |
G . nodes ( ) [ 0 ] |
добавляемпервую |
|
|
EP . append ( v ) |
# |
попавшуюсявершинув |
EP |
||
i |
= |
0 |
|
|
|
Далее, все переменные в Python’е являются однотипными ссылками на объекты. Таким образом, устраняется необходимость декларации переменных, переменная определяется в момент первого присваивания, и тип хранимого в ней объекта может быть переопределен последующими присваиваниями.
def e u l e r _ c i r c u i t ( G ) : |
|
EP = [ ] # Эйлеровцикл |
массиввершин . |
Кстати, можно присваивать одно и то же значение нескольким переменным одновременно:
>>> |
x |
= y = z = 0 # Обнулимпеременные x , y , z |
>>> |
x |
|
0 |
|
|
Также интерпретатор берет на себя все управление памятью (резервирование, сборка мусора и т. п.).
7.1. ВВЕДЕНИЕ В PYTHON |
339 |
Непосредственно в язык встроены не только примитивные типы данных, такие, как числа и строки, но и более сложные структуры. Например, так выглядят кортежи (tuples):
>>>a = (3, 2, 1)
>>>print a[0]
3
>>> print a[2] 1
>>>
К сожалению, индексы в P ythonе, так же, как и в C, начинаются с нуля, что несколько снижает наглядность алгоритмов, ведь людям привычно начинать отсчет с единицы, а не нуля.
Эффективно реализованные словари или хэши (hash):
>>>passwords={’stas’: ’mysecret555’, ’olga’: ’mobydick’}
>>>print passwords[’stas’]
mysecret555
>>>print passwords[’olga’] mobydick
>>>passwords[’oleg’] = ’hellraiser’
>>>print passwords[’oleg’] hellraiser
Списки или последовательности (list) (включая операции «среза» и др.):
>>> a = [1, 2, 4, 8, 16, 32]
340 |
Глава 7. ПРИЛОЖЕНИЯ |
>>>print a[3]
8
>>>print a[3:] [8, 16, 32]
>>>print a[:3] [1, 2, 4]
>>>print a[1:3] [2, 4]
>>>a.append(64)
>>>print a
[1, 2, 4, 8, 16, 32, 64]
>>>a.insert(0, -22)
>>>print a
[-22, 1, 2, 4, 8, 16, 32, 64]
Вообще, Python — современный, очень популярный, красивый, мощный и удобный интерпретируемый, расширяемый и встраиваемый объектно-ориентированный язык (со множественным наследованием), включающий даже элементы функционального программирования. т. е. это живой язык, активно использующийся для программирования как «обычных» пользовательских приложений, с переносимым оконным интерфейсом (см. например wxPython) или веб-приложений (см. например, Zope, Django, TurboGears), так и в научной сфере для прототипирования и разработки новых алгоритмов, для анализа или визуализации данных (см., например, Scien fic Python, http://www.scipy.org).
Здесь мы рассмотрим только базовые свойства синтаксиса, чтобы можно было устранить непонимание текстов, отдельных, не больше страничек, функций и процедур на Python. Желающим узнать больше рекомендуем книгу [Суз06] или интернет-курс дистанционного обучения [Суз07], а дальше — добро по-
7.1. ВВЕДЕНИЕ В PYTHON |
341 |
жаловать на сайт http://www.python.org.
Теперь перечислим основные операторы. Оператор if:
i f |
x |
< |
0 : |
|
|
|
x |
= |
0 |
|
|
e l i f |
x |
== |
0 : |
|
|
|
p r i n t |
’ Это число |
нуль ’ |
||
e l i f |
x |
== |
1 : |
|
|
|
p r i n t |
’ Это число |
1 ’ |
||
e l s e : |
|
|
|
|
|
|
p r i n t |
Это ‘ числобольшеединицы ’ |
|||
Оператор for имеет вид |
|
||||
f o r |
некаяпеременная_ i n |
некийдиапазон_ : |
Блок кода после заголовка выполняется до тех пор, пока некая_переменная принадлежит некоему_диапазону (причем этот диапазон может быть списком, числовой последовательностью, массивом каких-либо значений), а если нужно просто организовать цикл «от a до b», то для этого можно воспользоваться функцией range(a, b+1), которая вернет соответствующий список:
f o r i i n range ( 0 , l e n ( EP ) ) : i f G . degree ( EP [ i ] ) > 0 :
v = EP [ i ] break
Отметим, что для выхода из цикла можно использовать оператор break. Есть и цикл while, который выполняется пока истинно указанное выражение:
342 |
|
|
|
Глава 7. ПРИЛОЖЕНИЯ |
w h i l e |
N > |
0 : |
|
|
i f |
( N % |
2 ) |
== 0 : |
|
|
X |
= X * X % m |
||
|
N |
= |
N / |
2 |
e l s e : |
|
|
|
|
|
y |
= y * X % m |
||
|
N |
= N |
1 |
|
p r i n t |
N , |
X , |
y |
Декларация любой функции или процедуры (заметим, что декларации могут быть вложенными):
def gcd ( a , b ) :
p r i n t |
a |
, b |
i f a |
== |
0 : |
r e t u r n b
r e t u r n gcd ( b % a , a )
Для возврата значений (тип которых, кстати, может быть тоже любым) используется return. Оператор print печатает содержимое переданных ему аргументов, пытаясь придать «читаемый» вид кортежам, спискам и словарям.
В заключение заметим, что мы приводим алгоритмы не на «чистом» Python’е, а в автоматически «облагороженном» виде, где форматированием выделены операторы и идентификаторы, логические операторы представлены математическими символами («:», «^», «_»), оператор присваивания показан в виде « » и т. п.
Также мы приводим в тексте только ключевую часть алгоритма, различные вспомогательные функции (инициализация данных, печать и вывод иллюстраций и т. п.) остаются за скобками. Все это сделано,