- •Программирование и алгоритмические языки. Курс за второй семестр. Абстрактные типы данных.
- •Задача о раскраске.
- •Перечисление последовательностей фиксированной длины.
- •Var I:tСтраны; c:tЦвет;
- •Два взгляда на диаграммы – графы и автоматы.
- •Деревья
- •Как сократить перебор с возвратом. Перечисление последовательностей переменной длины
- •Словарный порядок на последовательностях произвольной длины
- •Статическая реализация стеков.
- •Очереди. Статическая реализация.
- •Статическая реализация деревьев.
- •Автоматы как структуры данных
- •Статическая реализация графов. Проблема фрагментации памяти. Списочные структуры.
- •Общая схема реализации автомата как списка.
- •Обработка кучи.
- •Динамическая реализация абстрактных типов ссылками. Ссылочные типы Паскаля.
- •Ссылочные типы Паскаля. Синтаксис типов.
- •Объявление списочной структуры в Паскале.
- •Реализация стеков.
- •Реализация очередей.
- •Основные операции над списками.
- •Обработка деревьев. Деревья выражений.
- •Поиск атома.
- •Различные объединения типов. Записи типов с вариантами.
- •Создание дерева. Перевод из префиксной записи. Представление записи.
- •Анализ алгоритма вычисления. Дерево как последовательность ветвей.
- •Задача синтаксического анализа.
- •Графы-выражения.
- •Раздельное описание абстрактных типов. Модульное программирование.
- •Проблема с кратным использованием модулей.
- •Деревья как структуры данных.
- •Деревья поиска.
- •Поиск в дереве поиска.
- •Включение в дерево поиска.
- •Другие обходы дерева. Обход в ширину.
- •Рекурсивные процедуры и функции. Примеры применения.
- •Поиск в дереве.
- •Проблемы с семантикой рекурсии.
- •Введение в машинно-ориентированное (ссылочное) программирование. Оператор Goto.
- •Создание новых структурных операторов.
- •Формальная семантика goto и неструктурных программ.
- •Мини-Паскаль.
- •Представление сложных типов. Адресная арифметика.
- •Проблемы реализации ввода-вывода. Идея буферизации.
- •Реализация процедур read и write.
- •Реализация структур управления.
- •Путь наверх. Реализация процедур-подпрограмм.
- •Передача параметров.
- •Сохранение и восстановление значений. Соглашение о связях.
- •Введение в теоретическое программирование. Границы программирования. Принципиальная и практическая неразрешимость.
- •О формальной спецификации. Мир задачи как автомат.
- •Процедуры как функции на множестве состояний. Процедуры как преобразователи предикатов.
- •Универсальные методы решения задач.
Var I:tСтраны; c:tЦвет;
Begin
кончились:=false;
i:=последняя страна;
c:=раскраска[i];
while not Кончились and (раскраска[i]последний цвет) do
begin
раскраска[i]:=первый цвет;
i:=i-1;
кончились:=i=0;
end;
if not Кончились then раскраска[i]:=succ(раскраска[i]);
end;
{Поддерживается быстрое вычисление конъюнкции}
Упражнение. Завершить первый вариант решения задачи.
Привлекательное своей простотой наше решение грешит единственным недостатком – оно неэффективно. Непосредственный выбор структуры данных под алгоритм игнорирует вопросы компактного хранения. Но основная сложность – эффективность по времени. Полный перебор раскрасок даёт (число цветов – число стран) – экспоненциальный алгоритм. Потратится много времени. Такие алгоритмы в программировании считаются практически невыполнимыми за реальное время.
Вопрос: нужно ли было писать такой алгоритм???
Ответ: несомненно, ДА!!!
Правильные программы имеет смысл улучшать. Преобразовывать программы эквивалентно проще, чем писать новые, но основной туш таков: достоинство плохих решений – простые решения универсальны и служат исходной точкой для решения очень широкого круга задач. Теория даёт простые решения.
Два взгляда на диаграммы – графы и автоматы.
Нахождение решений как поиск пути в графе. Полный перебор как универсальный алгоритм.
Графом называется некоторое множество вершин Х, соединённых рёбрами F.
GraphXXV
С каждым графом можно связать функцию, ставящую в соответствие каждой паре вершин некоторое ребро (либо его отсутствие). Для этого нужно ввести некоторое неопределённое значение. В самом простом случае интересно лишь наличие, либо отсутствие ребра, т.е. функция вида Graph(i,j)=trueboolean. Это в классической дискретной математике определение графа как отношения или двуместного предиката.
Graph(i,j)=true – существует стрелка из вершины i в вершину j. Отношение соседства из задачи по раскраске – пример именно такого определения графа.
Англия
Это пример неориентированного графа или симметричного отношения.
Франция
Италия i,j Graph(i,j)=Graph(j,i)
В программировании стандартным способом задания графа является двуместные массивы, обычно булевские. Иной взгляд на диаграммы даёт их понимание как транспортные схемы. Автоматом назовём соответствие вида
Automaton: XFX
Automaton(x,f)=x|, если ребро f ведёт из вершины х в вершину x|. Или, в терминологии теории автоматов, событие f переводит из состояния х в состояние x|.
Путём называется произвольная последовательность элементов из множества F. Функции Graph и Automaton очевидным образом продолжаются на множество всех путей F*. Другая интерпретация (трактовка) элементов множества F – преобразование состояний (процедура). Функция Automaton(x,f)= x| - аналог оператора аппликации – применения функции к аргументу.
Пусть задан некоторый автомат, а также предикаты Вход и Выход.
Вход: XBoolean
Выход: XBoolean
Состояния, на которых эти предикаты верны, называются входными и выходными.
Задача. Для данного автомата и предикатов Вход и Выход определить множество путей их каждого входного состояния некоторое выходное.
Это универсальная спецификация любой
задачи.
Пример: Сортировка массивов.
Множество состояний – множество всех состояний программы.
Вход: произвольное состояние, где Х – выделенная переменная, произвольный массив. Остальные переменные не определены.
Выход: любое состояние, в котором Х – перестановка начального состояния в упорядоченный массив.
Назовём задачу предыдущего вида (универсальный) конечной, если конечно множество состояний автомата (множество вершин графа). Полный перебор пути есть универсальный алгоритм решения любой конечной задачи.
Следствие: программисты не нужны!
Но следствие неверно, поскольку
-
существуют бесконечные задачи;
-
универсальный алгоритм даёт реально невыполнимые решения.