СРСП_4

advertisement
Алгоритмическое решение задач, анализ алгоритмической сложности
Тема 1: Стратегии решения задач. Алгоритмы и поиск решений.
Концепции и свойства алгоритмов. Стратегии реализации алгоритмов.
Тема 2: Структуры данных. Различные виды блок-схем. Реализация
алгоритмов. Основные вычислительные алгоритмы. Анализ алгоритмов.
Цель работы: Изучить
концепции и свойства алгоритмов, способы
описания алгоритмов. Структуры данных: примитивные типы, массивы, строки.
Краткие сведения из теории
Понятие алгоритма
Понятие алгоритма – одно из фундаментальных понятий информатики. К
реализации определенных алгоритмов сводятся процессы управления в
различных системах, что делает понятие алгоритма близким к кибернетике.
Само слово «алгоритм» происходит от algorithmi – латинской формы написания
имени великого математика IX века аль-Хорезми, который сформулировал
правила выполнения арифметических действий.
Алгоритм - это точное предписание исполнителю совершить
последовательность действий, направленных на достижение поставленной цели
для некоторого исполнителя.
Алгоритм служит, как правило, для решения не одной конкретной задачи,
а некоторого класса задач. Так, алгоритм сложения применим к любой паре
натуральных чисел. В этом выражается его свойство массовости, то есть
возможности применять многократно один и тот же алгоритм для любой задачи
одного класса.
Для
разработки
алгоритмов
и
программ
используется
алгоритмизация — процесс систематического составления алгоритмов для
решения поставленных прикладных задач. Алгоритмизация считается
обязательным этапом в процессе разработки программ и решении задач на
ЭВМ. Именно для прикладных алгоритмов и программ принципиально важны
4
детерминированность, результативность и массовость, а также правильность
результатов решения поставленных задач.
Эффективность алгоритмов
Хотя в определении алгоритма требуется лишь конечность числа шагов,
требуемых для достижения результата, на практике выполнение даже хотя бы
миллиарда шагов является слишком медленным. Также обычно есть другие
ограничения (на размер программы, на допустимые действия). В связи с этим
вводят такие понятия как сложность алгоритма (временна́я, по размеру
программы, вычислительная и др.).
Для каждой задачи может существовать множество алгоритмов,
приводящих к цели. Увеличение эффективности алгоритмов составляет одну из
задач современной информатики. В 50-х гг. XX века появилась даже отдельная
её область — быстрые алгоритмы. В частности, в известной всем с детства
задаче об умножении десятичных чисел обнаружился ряд алгоритмов,
позволяющих существенно ускорить нахождение произведения.
Тео́рия алгори́тмов — наука, изучающая общие свойства и
закономерности алгоритмов и разнообразные формальные модели их
представления. К задачам теории алгоритмов относятся формальное
доказательство алгоритмической неразрешимости задач, асимптотический
анализ сложности алгоритмов, классификация алгоритмов в соответствии с
классами сложности, разработка критериев сравнительной оценки качества
алгоритмов и т. п.
Развитие теории алгоритмов начинается с доказательства К. Гёделем
теорем о неполноте формальных систем, включающих арифметику, первая из
которых была доказана в 1931 г. Возникшее в связи с этими теоремами
предположение о невозможности алгоритмического разрешения многих
математических проблем (в частности, проблемы выводимости в исчислении
предикатов) вызвало необходимость стандартизации понятия алгоритма.
Первые стандартизованные варианты этого понятия были разработаны в 30-х
годах XX века в работах А. Тьюринга, А. Чёрча и Э. Поста. Предложенные ими
машина Тьюринга, машина Поста и лямбда-исчисление Чёрча оказались
эквивалентными друг другу. Основываясь на работах Гёделя, С. Клини ввел
понятие рекурсивной функции, также оказавшееся эквивалентным
вышеперечисленным.
Одним из наиболее удачных стандартизованных вариантов алгоритма
является введённое А. А. Марковым понятие нормального алгоритма. Оно было
разработано десятью годами позже работ Тьюринга, Поста, Чёрча и Клини в
связи
с
доказательством
алгоритмической
неразрешимости
ряда
алгебраических проблем.
Следует отметить также немалый вклад в теорию алгоритмов, сделанный
Д. Кнутом, A. Ахо и Дж. Ульманом. Одной из лучших работ на эту тему
является книга «Алгоритмы: построение и анализ» Томаса Х. Кормена, Чарльза
И. Лейзерсона, Рональда Л. Ривеста, Клиффорда Штайна.
5
Маши́на Тью́ринга (МТ) — абстрактный исполнитель (абстрактная
вычислительная машина). Была предложена Аланом Тьюрингом в 1936 году
для формализации понятия алгоритма.
Машина Тьюринга является расширением конечного автомата и, согласно
тезису Чёрча — Тьюринга, способна имитировать все другие исполнители (с
помощью задания правил перехода), каким-либо образом реализующие процесс
пошагового вычисления, в котором каждый шаг вычисления достаточно
элементарен.
Свойства алгоритма
Любой алгоритм должен обладать следующими свойствами:
- Понятность. Используемые на практике алгоритмы составляются с
ориентацией на определенного исполнителя. Нужно знать, какие команды этот
исполнитель может понять и выполнить, а какие - нет.
- Дискретность - возможностью разбиения алгоритма на отдельные
элементарные действия.
- Детерминированность
(определенность,
точность).
Будучи
понятным, алгоритм не должен содержать предписаний, смысл которых может
восприниматься неоднозначно. Это означает, что одна и та же команда, будучи
выполнена разными исполнителями, после исполнения каждым из них должна
давать одинаковый результат.
- Результативность. При точном выполнении всех предписаний
алгоритма исполнитель должен получить определенный результат за конечное
число шагов. Вывод о том, что решения не существует — тоже результат.
Следовательно, результативность означает возможность получения результата
после выполнения конечного количества операций.
- Массовость (универсальность) - возможностью получения результата
при различных исходных данных для некоторого класса похожих задач.
Независимо от содержания и сложности любые данные в памяти ЭВМ
представляются последовательностью двоичных разрядов, или битов, а их
значениями являются соответствующие двоичные числа. Данные,
рассматриваемые в виде последовательности битов, имеют очень простую
организацию или, другими словами, слабо структурированы. Для человека
описывать и исследовать сколько-нибудь сложные данные в терминах
последовательностей битов весьма неудобно. Более крупные и содержательные,
нежели бит, "строительные блоки" для организации произвольных данных
получаются на основе понятия "структуры данного".
С определенностью непосредственно связана существенная особенность,
о которой нельзя забывать: исполнитель выполняет алгоритм формально,
абсолютно не задумываясь над смыслом производимых действий.
Структуры данных
Под структурой данных в общем случае понимают множество элементов
данных и множество связей между ними. Структурный подход, заключается в
6
том, что логическая структура программы может быть выражена комбинацией
трех базовых структур — линейная, разветвляющая, циклическая, то есть
алгоритм любой сложности может быть представлен комбинацией трех
базовых структур:
- композиция или следования;
- ветвления (альтернатива, если - то - иначе);
- итерация или цикл (с предусловием, с постусловием, с конечным
числом повторений).
Циклический алгоритм – это алгоритм, некоторые шаги которого
повторяются N-количество раз.
Тело цикла – шаги алгоритма, которые повторяются.
Параметр цикла – величина, от которой зависит число повторений в
цикле.
Цикл с предусловием:
Пока условие выполняется (результат логического выражения дает true),
будут выполняться действия тела цикла. После очередного выполнения
вложенных действий условие снова проверяется. Для того чтобы выполнение
алгоритма не зациклилось, в теле цикла (помимо прочих действий) должно
быть выражение, в результате выполнения которого будет изменяться
переменная, используемая в условии. Тело цикла может ни разу не выполнится,
если условие с самого начала давало false.
Цикл с постусловием:
7
В этом цикле первый раз условие проверяется лишь после выполнения
действий тела цикла. Если условие возвращает true, то выражения-действия
повторяются снова. Каким бы ни было условие, тело данного цикла хотя бы
раз, но выполнится.
Цикл с конечным числом повторений:
Данный цикл также называют циклом «Для» (for). В его заголовке
указывается три параметра: начальное значение переменной (от), конечно
значение (до) и ее изменение с помощью арифметической операции на каждом
«обороте» цикла (шаг).
Различаются простые (базовые, примитивные) структуры или типы
данных и интегрированные (структурированные, композитные, сложные).
Простыми называются такие структуры данных, которые не могут быть
расчленены на составные части, большие, чем биты.
Интегрированными называются такие структуры данных, составными
частями которых являются другие структуры данных - простые или в свою
очередь интегрированные.
В зависимости от отсутствия или наличия явно заданных связей между
элементами данных следует различать несвязные структуры (векторы, массивы,
строки, стеки, очереди) и связные структуры (связные списки).
Линейный однонаправленный список — это структура данных,
состоящая из элементов одного типа, связанных между собой.
В информатике линейный список обычно определяется как абстрактный
тип данных (АТД), формализующий понятие упорядоченной коллекции
данных.
На практике линейные списки обычно реализуются при помощи массивов
и связных списков. Иногда термин «список» неформально используется также
как синоним понятия «связный список».
К примеру, АТД нетипизированного изменяемого списка может быть
определён как набор из конструктора и четырёх основных операций:
 операция, проверяющая список на пустоту;
 операция добавления объекта в список;
 операция определения первого (головного) элемента списка;
 операция доступа к списку, состоящему из всех элементов исходного
списка, кроме первого.
8
Характеристики списков. Длина списка. Количество элементов в
списке
Списки могут быть типизированными или нетипизированными. Если
список типизирован, то тип его элементов задан, и все его элементы должны
иметь типы, совместимые с заданным типом элементов списка. Обычно списки,
реализованные при помощи массивов, являются типизированными.
Список может быть сортированным или несортированным
В зависимости от реализации может быть возможен произвольный доступ
к элементам списка.
Массив — упорядоченный набор данных, для хранения данных одного
типа, идентифицируемых с помощью одного или нескольких индексов. В
простейшем случае массив имеет постоянную длину и хранит единицы данных
одного и того же типа.
Количество используемых индексов массива может быть различным.
Массивы с одним индексом называют одномерными, с двумя — двумерными и
т. д. Одномерный массив нестрого соответствует вектору в математике,
двумерный — матрице. Чаще всего применяются массивы с одним или двумя
индексами, реже — с тремя, ещё большее количество индексов встречается
крайне редко.
Динамическим называется массив, размер которого может меняться во
время исполнения программы. Для изменения размера динамического массива
язык программирования, поддерживающий такие массивы, должен
предоставлять встроенную функцию или оператор. Динамические массивы
дают возможность более гибкой работы с данными, так как позволяют не
прогнозировать хранимые объёмы данных, а регулировать размер массива в
соответствии с реально необходимыми объёмами. Обычные, не динамические
массивы называют ещё статическими.
Алгоритмы обработки одномерных числовых массивов
Под структурой данных типа массив понимают однородную структуру
однотипных данных, одновременно хранящихся в последовательных ячейках
оперативной памяти. Эта структура должна иметь имя и определять заданное
количество данных (элементов). Однотипность данных определяет
возможность использования циклических алгоритмов для обработки всех
элементов массива. Количество итераций цикла определяется количеством
элементов массива. Одновременное хранение в памяти всех элементов массива
позволяет решать большой набор задач, таких как, поиск элементов,
упорядочение и изменение порядка следования элементов.
Доступ к любому элементу массива осуществляется по его номеру
(индексу). Поэтому для обращения к элементу массива используют имя массива
(номер элемента), например: А(5).
Рассмотрим несколько более сложных алгоритмов, в которых
осуществляется изменение порядка следования элементов в одномерном
массиве. К таким алгоритмам относят алгоритмы с перестановкой элементов
местами, алгоритмы удаления некоторых элементов или циклического переноса
9
некоторых элементов в начало или конец массива. Основным требованием при
составлении алгоритмов обработки массивов является использование
минимально необходимых переменных. Чтобы точнее уяснить постановку
задачи следует сначала рассмотреть частные решения для некоторых значений
входных данных (провести анализ), затем обобщить полученное решение и
определить набор решаемых задач. Составив визуальный алгоритм, его следует
проверить на различных наборах исходных данных. Эти наборы исходных
данных требуется подбирать таким образом, чтобы при заполнении таблиц
трассировок проверить все пути вычислений данного алгоритма от начальной
вершины до конечной.
Пример. Составить алгоритм определения в одномерном числовом
массиве А из N элементов суммы положительных элементов.
Решение. Алгоритм представлен на рисунке 4.1. В этом алгоритме
переменная К - является счетчиком элементов массива, S - сумма элементов
массива, она вычисляется по формуле S=S+A(K). Ввод количества и значений
элементов массива осуществляется вначале в отдельном блоке ввода.
нет
да
да
нет
Рисунок 1- Алгоритм вычисления суммы положительных элементов
10
Стек (англ. stack — стопка) — структура данных с методом доступа к
элементам LIFO (англ. Last In — First Out, «последним пришёл — первым
вышел»). Чаще всего принцип работы стека сравнивают со стопкой тарелок:
чтобы взять вторую сверху, нужно снять верхнюю.
Добавление элемента, называемое также проталкиванием (push),
возможно только в вершину стека (добавленный элемент становится первым
сверху). Удаление элемента, называемое также выталкивание (pop), возможно
также только из вершины стека, при этом, второй сверху элемент становится
верхним.
Стеки широко применяются в вычислительной технике — в частности,
для отслеживания точек возврата из подпрограмм используется стек вызовов,
который является неотъемлемой частью архитектуры большинства
современных процессоров. Языки программирования высокого уровня также
используют стек вызовов для передачи параметров при вызове процедур
О́чередь — структура данных с дисциплиной доступа к элементам
«первый пришёл — первый вышел» (FIFO, First In — First Out). Добавление
элемента (принято обозначать словом enqueue — поставить в очередь)
возможно лишь в конец очереди, выборка — только из начала очереди (что
принято называть словом dequeue — убрать из очереди), при этом выбранный
элемент из очереди удаляется.
Применение очередей
Очередь в программировании используется, как и в реальной жизни,
когда нужно совершить какие-то действия в порядке их поступления, выполнив
их последовательно. Примером может служить организация событий в
Windows. Когда пользователь оказывает какое-то действие на приложение, то в
приложении не вызывается соответствующая процедура (ведь в этот момент
приложение может совершать другие действия), а ему присылается сообщение,
содержащее информацию о совершенном действии, это сообщение ставится в
очередь, и только когда будут обработаны сообщения, пришедшие ранее,
приложение выполнит необходимое действие.
Способы описания алгоритмов
Алгоритмы можно представить различными способами: с помощью
графического или словесного описания, в виде таблицы, последовательностью
формул, записанным на алгоритмическом языке:
 Словесная или описательная – алгоритм составлен на естественном, в
частности, математическом языке.
 Запись алгоритма на одном из языков программирования последовательность команд на языке программирования, предназначенная для
исполнения на компьютере.
 Способ, использующий псевдокоды. Псевдокоды это интерпретации
шагов алгоритма на обычном языке, которая описывает действия команды.
11
Псевдокод используется в листингах, чтобы показать общую структуру
программ, не применяя реальных операторов языка программирования.
 Графическая (блок-схема) – алгоритм составлен в виде специальных
графических знаков с указанием связи между ними. Блок-схема – стандартный
способ записи алгоритма, существует государственный стандарт, содержащий
перечень правил построение блок-схем.
Рассмотрим пример словесного способа представления алгоритма:
Какую последовательность действий нужно выполнить, чтобы позвонить по
телефону автомату?
1. Вставить телефонную карточку.
2. Снять трубку.
3. Набрать номер.
Машинный код
Машинный код (также употребляются термины собственный код, или
платформенно-ориентированный код, или родной код, или нативный код — от
англ. native code) — система команд конкретной вычислительной машины,
которая
интерпретируется
непосредственно
микропроцессором
или
микропрограммами данной вычислительной машины.
Каждая модель процессора имеет свой собственный набор команд, хотя во
многих моделях эти наборы команд сильно перекрываются. Говорят, что
процессор A совместим с процессором B, если процессор A полностью
«понимает» машинный код процессора B. Если процессор A знает несколько
команд, которых не понимает процессор B, то B несовместим с A.
«Слова» машинного кода называются машинными инструкциями. Каждая из
них описывает элементарное действие, выполняемое процессором, такое как
«переслать байт из памяти в регистр». Программа — это просто длинный
список инструкций, выполняемых процессором. Раньше процессоры просто
выполняли инструкции одну за другой, но новые суперскалярные процессоры
способны выполнять несколько инструкций за раз. Прямой поток выполнения
команд может быть изменён инструкцией перехода, которая переносит
выполнение на инструкцию с заданным адресом. Инструкция перехода может
быть условной, выполняющей переход только при соблюдении некоторого
условия.
Псевдоко́д — компактный (зачастую неформальный) язык описания
алгоритмов, использующий ключевые слова императивных языков
программирования, но опускающий несущественные подробности и
специфический
синтаксис.
Псевдокод
обычно
опускает
детали,
несущественные
для
понимания
алгоритма
человеком.
Такими
несущественными деталями могут быть описания переменных, системнозависимый код и подпрограммы. Главная цель использования псевдокода —
обеспечить понимание алгоритма человеком, сделать описание более
воспринимаемым, чем исходный код на языке программирования. Псевдокод
12
широко используется в учебниках и научно-технических публикациях, а также
на начальных стадиях разработки компьютерных программ.
Блок-схемы можно раcсматривать как графическую альтернативу
псевдокоду.
В
отличие
от
стандартизации
синтаксиса
языков
программирования, на синтаксис псевдокода обычно не устанавливается
стандартов, так как последний непосредственно не компилируется в
исполняемую программу. Поэтому можно сказать, что обычно автор каждый
публикации применяет свой оригинальный псевдокод, однако чтобы быть
максимально понятным читателям, авторы публикаций содержащих псевдокод,
как правило, заимствуют нужные им конструкции из какого-либо языка
программирования. Зачастую источником псевдокода служат несколько
языков, и таким образом псевдокод часто не содержит специфических
признаков конкретного языка программирования. Кроме того, математические
выражения часто включаются в псевдокод в том виде, как их принято
записывать в математике, а не в языках программирования, а некоторые
фрагменты псевдокода могут быть фразами естественного языка (русского,
английского и т. д.). Однако при этом конструкции некоторых языков
программирования чаще используются для псевдокода. Так, например, очень
часто используется синтаксис, похожий на синтаксис языка Паскаль. Это
объясняется тем, что Паскаль создавался как язык, ориентированный на задачи
обучения программированию, и поэтому синтаксис этого языка особенно
приспособлен для восприятия человеком. Часто используются и другие языки:
Си, Алгол, Фортран и другие.
При описании в виде блок-схем алгоритм изображается
геометрическими фигурами (блоками), связанными по управлению линиями
(направлениями
потока)
со
стрелками.
В
блоках
записывается
последовательность действий.
Таблица 1- Основные блоки
Наименование
Процесс
Ввод-вывод
(данные)
Условие
Обозначение
Функции
Выполнение операций, в результате
которых изменяется значение,
форма представления или
расположение данных.
Преобразование данных в форму,
пригодную для обработки (ввод) или
отображения результатов (вывод).
Выбор направления выполнения
алгоритма в зависимости от
некоторых переменных условий.
13
Продолжение таблицы 1- Основные блоки
Наименование
Обозначение
Функции
Предопределённы
й (типовой)
процесс
Документ
Использование ранее созданных и
отдельно написанных программ
(подпрограмм)
Вывод данных на бумажный
носитель.
Магнитный диск
Ввод-вывод данных, носителем
которых служит магнитный диск
Пуск-останов
Начало, конец, прерывание процесса
обработки данных.
Соединитель
Указание связи между прерванными
линиями, соединяющими блоки
Приведем пример записи алгоритма в виде блок-схемы, псевдокодов и на
языке Паскаль. Необходимо грамотно составить алгоритм с помощью блоксхемы, а уже затем, зная, как записываются команды на конкретном языке
программирования, набрать программу на компьютере и получить результат,
запустив ее на исполнение.
Рассмотрим линейный алгоритм, представленный в таблице 2.
Таблица 2 - Способы описания линейного алгоритма
14
Приведем пример записи разветвляющегося алгоритма для нахождения
наибольшего из двух чисел (таблица 3). Алгоритм представим в виде блоксхемы, псевдокодов и на языке Паскаль.
Таблица 3 - Способы описания разветвляющегося алгоритма
Рассмотрим циклический алгоритм нахождения суммы первых
натуральных нечетных чисел до n. Представим запись алгоритма тремя
способами: в виде блок-схемы, в виде псевдокодов и на языке
программирования Pascal. Пример представлен в таблице 4.
Блок-схема состоит из следующих базовых структур:
 две составные команды (команда следования и команда повторения с
предусловием);
 простая команда.
Все команды соединены последовательно. Конструкции оформлены
стандартным образом, поэтому их легко распознать и перевести на язык
программирования. Каждая конструкция имеет один вход и один выход.
Пунктирные стрелки в таблице отражают последовательность
выполнения технологической цепочки. После записи алгоритма в виде блоксхемы каждая команда переводится на алгоритмический язык, а уже затем на
язык программирования.
15
Таблица 4 - Способы описания циклического алгоритма
Анализ алгоритмов затраты
стандартные классы сложности
по
объему
памяти
и
времени,
Традиционно в программировании понятие сложности алгоритма связано
с использованием ресурсов компьютера: насколько много процессорного
времени требует программа для своего выполнения, насколько много при этом
расходуется память машины? Учет памяти обычно ведется по объему данных и
не принимается во внимание память, расходуемая для записи команд
программы. Время рассчитывается в относительных единицах так, чтобы эта
оценка, по возможности, была одинаковой для машин с разной тактовой
частотой и с незначительными вариациями в архитектуре.
Такой подход сложился исторически и ориентируется, прежде всего, на
научные и инженерные приложения теории алгоритмов: объемы данных
значительно превышают размеры самой программы, а программа может
выполняться несколько часов. Если не считать офисных и бухгалтерских
применений вычислительных машин, то производительность и объем памяти
компьютера никогда не казались программистам чрезмерными и постоянной
задачей является сделать программу работающей хотя бы немного быстрее и
попытаться заставить ее работать в стесненных условиях ограниченного поля
памяти.
16
Если в научных и инженерных приложениях большое время вычислений
доставляет лишь неудобство пользователям, то в ряде других областей ресурсы
настолько критичны, что может возникнуть проблема целесообразности всего
проекта из-за неэффективной работы программы. К таким областям относятся
системы реального времени (real-time systems), которые управляют процессами
в реальном мире или обрабатывают информацию, служащую для принятия
оперативных решений. Примерами систем реального времени являются
бортовые компьютерные системы космических кораблей, самолетов, других
транспортных средств; компьютерные системы, управляющие непрерывным
химическим
производством,
ядерными
реакторами;
системы
противовоздушной обороны, управления огнем и др.
Существует ряд важных практических причин, побуждающих нас
заниматься анализом алгоритмов. Одной из них является потребность
получения оценок или границ для объема памяти и времени работы,
необходимых алгоритму для успешной обработки входных данных. Следует
избегать разработки программы, которая за отведенное студенту машинное
время не успеет обработать входные данные достаточно большого размера
(например, следует признать неудовлетворительной программу обработки
графов, если из-за нехватки времени она не дает ответа для графа, состоящего
из десяти вершин). Лучше заранее (еще при разработке алгоритма) с помощью
карандаша и бумаги оценить объем памяти и время, необходимые
разрабатываемому алгоритму, а затем улучшать его (или разработать новый,
более эффективный). Хороший анализ может выявить узкие места в ваших
программах (например, те части программы, на выполнение которых
расходуется большая часть времени), а также выбрать более подходящий
алгоритм из широкого класса алгоритмов, решающих одно и то же задание.
Одну и ту же задачу могут решать много алгоритмов. Эффективность
работы каждого из них описывается разнообразными характеристиками.
Прежде чем анализировать эффективность алгоритма, нужно доказать, что
данный алгоритм правильно решает задачу, а потом решать, насколько это
решение эффективно.
При анализе алгоритма определяется количество «времени», необходимое
для его выполнения. Это не реальное число секунд или других промежутков
времени, а приблизительное число операций, выполняемых алгоритмом. Число
операций и измеряет относительное время выполнения алгоритма. Таким
образом, иногда «временем» называют вычислительную сложность алгоритма.
Фактическое количество секунд, требуемое для выполнения алгоритма на
компьютере, непригодно для анализа, т.к. обычно интересует только
относительная эффективность алгоритма, решающего конкретную задачу.
Действительно, время, требуемое на решение задачи,- не очень хороший способ
измерять эффективность алгоритма, потому что алгоритм не становится лучше,
если его исполнять на более медленном.
На самом деле фактическое количество операций алгоритма на тех или
иных входных данных не представляет большого интереса и не очень много
17
сообщает об алгоритме. Реально определяется зависимость числа операций
конкретного алгоритма на тех или иных входных данных. Можно сравнить два
алгоритма по скорости роста числа операций. Именно скорость роста играет
ключевую роль, поскольку при небольшом размере входных данных алгоритм
А может требовать меньшего количества операций, чем алгоритм В, но при
росте объема входных данных ситуация может поменяться на
противоположную.
Для алгоритма A мы определили функцию временной сложности ВРЕМЯ
А(n), дающую верхнюю границу для максимального времени его работы. Эта
функция зависит от максимального числа основных операций (сложения,
сравнения и т.д.), которые должен выполнить алгоритм при решении задачи на
входных данных размером n. Аналогично можно определить функцию
емкостной сложности ПАМЯТЬ А (n), дающую границу для максимального
числа одновременно существующих скалярных значений при выполнении А на
входных данных размером n.
Хорошим критерием качества алгоритма является скорость роста его
сложности в зависимости от увеличения размера входа. В таблицах 1 и 2
показано
влияние порядка роста сложности алгоритма на увеличение
максимально допустимого размера входных данных, которого можно достичь
увеличением скорости ЭВМ, а также эффект применения более эффективного.
В общем случае следует иметь в виду, что повышение скорости работы
алгоритма может потребовать увеличения необходимой ему памяти. Например,
рекурсивный алгоритм порождения перестановок в порядке минимального
изменения совсем не производит сравнений, но имеет емкостную сложность , в
18
то время как емкостная сложность нерекурсивного алгоритма равна . Этот же
пример показывает справедливость обратного утверждения: за счет увеличения
временной сложности алгоритма можно понизить его емкостную сложность.
Как правило, более эффективный алгоритм приводит к программе
большего размера и требует больших усилий, как на его разработку, так и на
его обоснование.
Классы сложности
В рамках классической теории осуществляется классификация задач по
классам сложности (P-сложные, NP-сложные, экспоненциально сложные и др.).
К классу P относятся задачи, которые могут быть решены за время,
полиномиально зависящее от объёма исходных данных, с помощью
детерминированной вычислительной машины (например, машины Тьюринга).
К классу NP относятся задачи, которые могут быть решены за
полиномиально выраженное время с помощью недетерминированной
вычислительной машины, то есть машины, следующее состояние которой не
всегда однозначно определяется предыдущими. Работу такой машины можно
представить как разветвляющийся на каждой неоднозначности процесс: задача
считается решённой, если хотя бы одна ветвь процесса пришла к ответу. Другое
определение класса NP: к классу NP относятся задачи, решение которых с
помощью дополнительной информации полиномиальной длины, данной нам
свыше, мы можем проверить за полиномиальное время. В частности, к классу
NP относятся все задачи, решение которых можно проверить за
полиномиальное время. Класс P содержится в классе NP.
Поскольку класс P содержится в классе NP, принадлежность той или
иной задачи к классу NP зачастую отражает наше текущее представление о
способах решения данной задачи и носит неокончательный характер. В общем
случае нет оснований полагать, что для той или иной NP-задачи не может быть
найдено P-решение. Вопрос о возможной эквивалентности классов P и NP (то
есть о возможности нахождения P-решения для любой NP-задачи) считается
многими одним из основных вопросов современной теории сложности
алгоритмов. Ответ на этот вопрос не найден до сих пор. Сама постановка
вопроса об эквивалентности классов P и NP возможна благодаря введению
понятия NP-полных задач. NP-полные задачи составляют подмножество NPзадач и отличаются тем свойством, что все NP-задачи могут быть тем или иным
способом сведены к ним. Из этого следует, что если для NP-полной задачи
будет найдено P-решение, то P-решение будет найдено для всех задач класса
NP. Примером NP-полной задачи является задача о конъюнктивной форме.
Примерами алгоритмов класса P являются стандартные алгоритмы
целочисленного сложения, умножения, деления, взятия остатка от деления,
перемножения матриц, выяснение связности графов и некоторые другие.
Класс P вмещает все те проблемы, решение которых считается
«быстрым», то есть полиномиально зависящим от размера входа. Сюда
19
относится сортировка, поиск во множестве, выяснение связности графов и
многие другие.
Класс NP включает в себя класс P, а также некоторые проблемы, для
решения которых известны лишь алгоритмы, экспоненциально зависящие от
размера входа (т.е. неэффективные для больших входов). В класс NP входят
многие знаменитые проблемы, такие как задача коммивояжёра, задача
выполнимости булевых формул, факторизация и др.
Асимптотическая сложность. Несмотря на то, что функция временной
сложности алгоритма в некоторых случаях может быть определена точно, в
большинстве случаев искать точное её значение бессмысленно. Дело в том, что
во-первых, точное значение временной сложности зависит от определения
элементарных операций (например, сложность можно измерять в количестве
арифметических операций или операций на машине Тьюринга), а во-вторых,
при увеличении размера входных данных вклад постоянных множителей и
слагаемых низших порядков, фигурирующие в выражении для точного времени
работы, становится крайне незначительным. Рассмотрение входных данных
большого размера и оценка порядка роста времени работы алгоритма, приводит
к понятию асимптотической сложности алгоритмов. Обычно алгоритм с
меньшей асимптотической сложностью является более эффективным для всех
входных данных, за исключением лишь, возможно, данных малого размера.
Например, «пропылесосить ковер» требует время, линейно зависящее от
его площади , то есть на ковер, площадь которого больше в два раза, уйдет в
два раза больше времени. Соответственно, при увеличении размера ковра в сто
тысяч раз, объем работы увеличивается строго пропорционально в сто тысяч
раз, и т. п.
Следующий пример - «найти имя в телефонной книге» требует всего
лишь время, логарифмически зависящее от количества записей (O(log2(n))), так
как открыв книгу примерно в середине, мы уменьшаем размер «оставшейся
проблемы» вдвое (за счет сортировки имен по алфавиту).
Словарь основных понятий и терминов
Алгоритм - это точно определенная последовательность действий для
некоторого исполнителя, выполняемых по строго определенным правилам и
приводящих через некоторое количество шагов к решению задачи.
Алгоритмизация - процесс составления алгоритмов решения задачи.
Альтернатива - это нелинейная управляющая конструкция, не
содержащая итерацию. Она предназначена для описания различных процессов
обработки информации, выбор которых зависит от значений входных данных.
Ветвление - это структура, обеспечивающая выбор между
альтернативами.
20
Визуальные алгоритмы - это алгоритмы, представленные графическими
средствами.
Двумерный массив - это структура однотипных элементов,
расположенных в виде таблицы значений. Такое представление значений
соответствует математическому понятию двумерный массив. Каждый элемент в
двумерном массиве идентифицируется номером строки и номером столбца, на
пересечении которых он расположен.
Исполнитель алгоритмов - одушевленный или неодушевленный объект,
который знает и может выполнить некоторый набор элементарных действий, из
которых формируется алгоритм.
Итерация - это циклическая управляющая структура, которая содержит
композицию и ветвление. Она предназначена для организации повторяющихся
процессов обработки последовательности значений данных.
Композиция (следование) - это линейная управляющая конструкция, не
содержащая альтернативу и итерацию. Она предназначена для описания
единственного процесса обработки информации.
Линейные алгоритмы - алгоритмы, не содержащие блока условия. Они
предназначены для представления линейных процессов.
Массив - это однородная структура однотипных данных, одновременно
хранящихся в последовательных ячейках оперативной памяти. Эта структура
должна иметь имя и определять заданное количество данных (элементов).
Метод структурной алгоритмизации. Этот метод основан на визуальном
представлении алгоритма в виде последовательности управляющих
структурных фрагментов. Выделяют три базовые управляющие процессом
обработки информации структуры: композицию, альтернативу и итерацию. С
помощью этих структур можно описать любые процессы обработки
информации.
Метод парных перестановок сортировки массива основан на принципе
сравнения и обмена пары соседних элементов. Процесс перестановок пар
повторяется просмотром массива с начала до тех пор, пока не будут
отсортированы все элементы, т.е. во время очередного просмотра не
произойдет ни одной перестановки.
Метод модифицированный простого выбора сортировки основывается на
алгоритме поиска минимального элемента. В массиве А(1..n) отыскивается
минимальный элемент, который ставится на первое место . Для того, чтобы не
потерять элемент , стоящий на первом месте , этот элемент устанавливается на
место минимального . Затем в усеченной последовательности, исключая
первый элемент, отыскивается минимальный элемент и ставится на второе
место и так далее n-1 раз пока не встанет на свое место предпоследний n-1
элемент массива А, сдвинув максимальный элемент в самый конец.
Модель - упрощенное представление о реальном объекте, процессе или
явлении.
21
Моделирование построение моделей для исследования и изучения
моделируемого объекта, процесса, явления с целью получения новой
информации при решении конкретных задач.
Одномерный массив - это однородная структура однотипных данных, для
получения доступа к его элементам достаточно одной индексной переменной.
Одномерные символьные массивы -это массивы, составленные из
определенной последовательности символов, которые образуют тексты.
Переменные данные - это данные, которые изменяют свои значения в
процессе решения задачи.
Последовательность значений - это набор однотипных величин, которые
вводятся и обрабатываются циклически.
Постоянные данные - это такие данные, которые сохраняют свои
значения в процессе решения задачи (математические константы, координаты
неподвижных объектов) и не зависят от внешних факторов.
Разветвленные алгоритмы в своем составе содержат блок условия и
различные конструкции ветвления. Ветвление - это структура, обеспечивающая
выбор между альтернативами.
Сортировка - процесс перестановки объектов данного массива в
определенном порядке. Целью сортировки являются упорядочение массивов
для облегчения последующего поиска элементов в данном массиве.
Таблица трассировки - это таблица содержащая столько столбцов,
сколько переменных и условий в алгоритме, в ней мы выполняем действия шаг
за шагом от начала до конца алгоритма для конкретных наборов входных
данных.
Циклические алгоритмы - являются наиболее распространенным видом
алгоритмов, в них предусматривается повторное выполнение определенного
набора действий при выполнении некоторого условия. Такое повторное
выполнение часто называют циклом. Существуют два основных видов
циклических алгоритмов: циклические алгоритмы с предусловием,
циклические алгоритмы с постусловием. Они отличаются друг от друга
местоположением условия выхода их цикла.
Условно-постоянные данные - это такие данные, которые могут иногда
изменять свои значения, но эти изменения не зависят от процесса решения
задачи, а определяются внешними факторами.
Содержание отчета
1. Цель работы.
2. Описание задания к работе.
3. Наличие выполненного задания в виде отчета.
4. Ответы на контрольные вопросы.
22
Задание к работе
1. Из таблицы 5 на поставленный вопрос выбрать правильный номер
ответа (правильный ответ только один).
Таблица 5 - Задание
№
вопроса
1
2
3
4
5
6
7
8
9
10
11
№
ответа
Вопрос
Набор всех действий, которые понимает
и может выполнить исполнитель
В зависимости от особенностей своего
построения алгоритмы делятся на
Алгоритм,
записанный
на
языке
программирования
Исполнителем алгоритма может быть
Основные способы записи алгоритмов
Графическое
изображение
последовательности выполнения шагов
алгоритма, для обозначения которых
используются
определенные
геометрические фигуры - это
Один и тот же алгоритм может быть
использован.
Возможность разбиения алгоритма на
отдельные элементарные действия- это
Шаг
циклической
конструкции
алгоритма - это
Алгоритм должен приводить к решению
задачи (или к ответу, что решения нет)
за конечное число шагов-это…
Однородная структура однотипных
данных, одновременно хранящихся в
последовательных ячейках оперативной
памяти - это
1
2
3
4
5
6
7
8
9
Ответ
линейный,
разветвляющийся или
циклический.
для решения одной
задачи.
словесный, графический,
в виде машинного кода.
может быть записан
разными способами.
результативность
для решения
однотипного класса
задач.
называется программой.
человек или
автоматическое
устройство.
только человек.
называется алгоритмом.
10
дискретность
11
12
13
14
блок-схема
итерация
массив
2. Составить алгоритм задачи. Даны действительные числа X, Y (X ≠ Y).
Меньшее из этих двух чисел заменить их полусуммой, а большее – их
удвоенным произведением.
3. Составить алгоритм задачи. Даны действительные числа X, Y. Если
X и Y отрицательны, то каждое значение заменить его модулем.
23
4. Составить алгоритм задачи. По заданным значениям трех углов
определить является треугольник тупоугольным или нет.
5. Составить блок-схему задачи.
Вычислить значение Y, исходя из условия:
4(x-2z), если x >= z
Y=
3x+z+1, если x < z
6. Составить алгоритм задачи. Даны действительные числа X, Y. Если
отрицательно одно из них, то оба значения увеличить на 0,5.
7. Даны действительные числа X, Y. Если оба значения неотрицательны,
то оба значения уменьшить в 10 раз.
8. Составить алгоритм для вычисления периметра пятиугольника, если
известны его стороны.
9. Составить
алгоритм
для
вычисления
длины
окружности
произвольного радиуса.
10. Составить алгоритм для вычисления площади треугольника, если
известны его стороны.
11. Составить алгоритм. Вывести все простые числа P в указанном
интервале (A;B).
12. Составить алгоритм. Дано целое число. Если оно является
положительным, то прибавить к нему 1; в противном случае вычесть из него 2.
Вывести полученное число.
Контрольные вопросы
1. Что такое алгоритмизация?
2. Основные свойства алгоритмов.
3. Что представляет из себя машина Тьюринга?
4. Что значит "алгоритм исполняется формально"?
5. Дайте определение одномерного массива.
6. Что такое циклический алгоритм?
7. Назовите базовые структуры алгоритма.
8. Что такое вербальная форма представления алгоритма?
9. Что такое ветвление?
10. Какие данные являются постоянными?
11. Что означает свойство – детерминированность?
12. Приведите пример линейного алгоритма.
13. Что является алгоритмом: книга, справочник, энциклопедия,
инструкция?
14. Классификация задач по их сложности.
24
Список использованных источников
1. Вирт Н. Алгоритмы и структуры данных. СПб: Невский диалог, 2001.
2. Ахо А., Хопкрофт Д., Ульман Д. Структуры данных и алгоритмы. –
М.:Вильямс, 2001.
3. Информатика / Под ред. С. В. Симоновича. – СПб., 2004.
4. Могилев А.В. Информатика. М.: Издательский центр «Академия»,
2003-2004.
5. Кнут Д. Искусство программирования, 3-е изд. – М.: Вильямс, 2001.
25
Download