Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Алгоритмы и структуры данных.doc
Скачиваний:
80
Добавлен:
01.05.2014
Размер:
411.14 Кб
Скачать

Образовательный проект

Д.В. Груздев, В.А. Таланов

Алгоритмы и структуры данных

(лабораторные работы)

Нижний Новгород

2008

Содержание

1.Общие указания 5

2. Основные операции для работы с d-кучами 8

3. Лабораторные работы 10

3.1. Нахождение кратчайших путей в графе 10

Постановка задачи 10

Структура данных для представления графа 11

Алгоритм Дейкстры, реализованный на основе d-кучи 12

Алгоритм Дейкстры, использующий метки 13

Алгоритм Форда–Беллмана 14

Задания для лабораторной работы № 1 15

3.2. Нахождение минимального остова графа 16

Постановка задачи 16

Стратегии решения задачи 16

Алгоритм Борувки 17

Алгоритм Краскала 18

Алгоритм Прима 19

Round Robin алгоритм 20

Задания для лабораторной работы № 2 20

3.3. Создание и использование словаря 21

Постановка задачи 21

Решение задачи создания и использования словаря 21

Тривиальный алгоритм 22

Алгоритм с использованием АВЛ-дерева 22

Задания для лабораторной работы № 3 22

3.4. Поиск фрагмента в тексте 23

Постановка задачи 23

Наивный алгоритм поиска фрагмента в тексте 24

Алгоритм Кнута-Морриса-Пратта 24

Задания для лабораторной работы № 4 25

3.5. Сортировка 26

Постановка задачи 26

Сортировка с помощью d-кучи 26

Быстрая сортировка 26

Задания для лабораторной работы № 5 27

3.6. Построение выпуклой оболочки n точек на плоскости 28

Постановка задачи 28

Построение выпуклой оболочки с помощью сортировки 28

Задания для лабораторной работы № 6 29

3.7. Поиск пары пересекающихся отрезков 30

Постановка задачи 30

Наивный алгоритм поиска пересечения 31

Эффективный алгоритм поиска пересечения 31

Задания для лабораторной работы № 7 32

4. Приложение: генерация графов для экспериментов 33

Литература 34

  1. Общие указания

Предмет "Лабораторный практикум по АРА" предполагает выполнение ряда вариантов лабораторных работ.

Целью каждого варианта каждой лабораторной работы является реализация, сравнение и анализ двух алгоритмов, решающих одну и ту же задачу.

Заданный студенту вариант лабораторной работы считаются выполненными им после представления и утверждения самостоятельно им написанных двух программ и отчёта. (Самостоятельность означает, что после изучения соответствующего материала каждый символ в исходном коде своей программы и каждый символ в своём отчёте студент придумывает и пишет (или набирает) сам. При этом совершенно необходимо, чтобы студент понимал абсолютно всё, что содержится в его отчёте и исходном коде его программ.)

Студент на основе троекратного внимательнейшего изучения общих указаний и задания для соответствующих вариантов лабораторной работы, а также на основе внимательнейшего изучения всего кода своих программ или всего своего отчёта должен самостоятельно заблаговременно найти все неточности в программах или отчёте и также самостоятельно заблаговременно все неточности исправить. Причём так поступать необходимо каждый раз, когда обнаруживается хотя бы одна неточность.

Первая программа должна читать из файла входную информацию и записывать результаты работы каждого исследуемого алгоритма, а также время его работы в соответствующий данному алгоритму новый файл с именем, начинающимся с “output”. Таким образом, выходная информация для первого алгоритма должна быть записана в первый файл, а выходная информация для второго алгоритма должна быть записана во второй файл. Вторая программа предназначена для проведения экспериментов и должна соответствовать разделу 2 задания для соответствующих вариантов лабораторной работы. Для каждой программы в электронном виде должны быть представлены: все исходные файлы, имя основного из которых начинается с “prog”, выполняемый файл с именем, начинающимся с “prog”, и инструкция по работе программы, содержащаяся в файле, имя которого начинается с “instruction”. К первой программе также должен быть приложен файл с соответствующей входной информацией, имеющий начинающееся с “input” имя и размер не более ста байт.

Отчёт должен быть представлен как в электронном (в файле с начинающемся с “отчёт” именем), так и в печатном виде и содержать следующие разделы:

  • описание алгоритмов,

  • обоснование теоретических оценок временной сложности алгоритмов,

  • описание реализующих алгоритмы программ,

  • проведенные эксперименты,

  • сравнение алгоритмов,

  • выводы.

В разделе "Описание алгоритмов" следует поставить задачу и описать все исследуемые решающие её алгоритмы.

В разделе "Обоснование теоретических оценок временной сложности алгоритмов " следует сформулировать утверждения, представляющие оценки временной сложности всех исследуемых алгоритмов и подробнейшим образом их доказать.

В разделе "Проведенные эксперименты" следует отобразить результаты всех экспериментов, указанных в разделе 3 задания для соответствующих вариантов лабораторной работы, с помощью графиков. В каждом эксперименте варьируется один параметр, обозначим его через K, в некоторых пределах K0<K<K1, при этом для каждого K фиксируется время t(K) работы алгоритма. На рисунке, соответствующем этому эксперименту, должны быть приведены графики функций t(k) для всех исследуемых алгоритмов. Графики должны быть нарисованы так, чтобы им непосредственно предшествовали параметры эксперимента, были указаны названия осей и их единицы деления (в частности, единица деления вертикальной оси должна соответствовать 1 секунде), было написано, какой график какому алгоритму соответствует.

В разделе "Сравнение алгоритмов" следует сделать на основе практических данных, для получения которых приветствуется проведение дополнительных экспериментов, заключение о предпочтительности использования того или иного алгоритма в конкретных рассмотренных случаях и выяснить, соответствует ли сделанное заключение теоретическим оценкам временной сложности алгоритмов.

В разделе "Выводы" следует сделать на основе практических данных, для получения которых приветствуется проведение дополнительных экспериментов, заключение о предпочтительности использования того или иного в максимально более общих случаях и выяснить, соответствует ли сделанное заключение теоретическим оценкам временной сложности алгоритмов.

Соответствующие самостоятельно написанные студентом две программы и отчёт считаются представленными, если данный студент представил в печатном виде отчёт и в электронном виде каталог (с именем “(Фамилия)_(ИО)_(N)_(a)”, где “(фамилия)” означает фамилию данного студента, “(ИО)” есть инициалы имени и отчества данного студента, “(N)” есть номер соответствующей лабораторной работы и “(a)” есть номер соответствующего ее варианта), содержащий:

файл “отчёт*.*” с отчётом,

подкаталог “prog1_source” со всеми исходными файлами для первой программы,

подкаталог “prog1_exe” с выполняемым файлом для первой программы, с файлом инструкции “instruction*.*” и с файлом примера “input*.*”,

подкаталог “prog2_source” со всеми исходными файлами для второй программы,

подкаталог “prog2_exe” с выполняемым файлом для второй программы и с файлом инструкции “instruction*.*” и с файлом примера “input*.*”.

Соответствующие две программы и отчёт утверждаются после их представления и приведения к надлежащему виду.

Задание по предмету "Лабораторный практикум по АРА" состоит из 2-х частей.

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

Все соответствующие программы студентом должны быть представлены на занятии 7-ой недели (13.10.2007 – 19.10.2007) (1-ый этап).

Соответствующий отчёт студентом должен быть представлен на занятии 10-ой недели (3.11.2007 – 9.11.2007) (2-ой этап).

2-ая часть (обязательная) заключается в создании совместных отчётов всей подгруппы (по одному на каждую лабораторную работу), который должен быть представлен на занятии 14-ой недели (1.12.2007 – 7.12.2007) (3-ий этап).

Студенты, выполнившие 1-ую и 2-ую части задания по данному предмету с соблюдением сроков для всех пяти этапов, получают положительную оценку на зачёте.

2. Основные операции для работы с d-кучами

Всюду далее, говоря о d-кучах, будем предполагать, что d является натуральным числом, не меньшим 2.

Реализация основных операций для работы с d-кучами

Рассмотрим d-кучу, реализованную на массиве key[1..n] ключей и массиве имен name[1..n] ее элементов. Функция minchild(i, key, n, d) позволяет для i-го узла n-элементной d-кучи с массивом ключей key находить его непосредственного потомка с минимальным ключом. Если у i-го узла нет потомков, то minchild(i, key, n, d) = i. Данная функция использует функции first_child(n, d, i), last_child(n, d, i), father(n, d, i), выдающие номера первого потомка, последнего потомка и родителя узла i n-элементной d-кучи соответственно. Значение father(n, d, 1) = 1, и если у i-го узла нет потомков, то first_child(n, d, i) = 0, last_child(n, d, i) = 0.

function minchild (i; var key; n, d);

begin

kf:= first_child(n, d, i);

if kf = 0 then minchild:= i else

begin

kl:= last_child(n, d, i); min_key:= key[kf]; minchild:= kf;

for j := kf +1 to kl do

if key[j]< min_key then begin

min_key:= key[j]; minchild:= j;

end;

end;

end;

function first_child(n, d, i);

begin

k:= (i-1)d + 2; if k>n then first_child:= 0 else first_child:= k;

end;

function last_child(n,d,i);

begin

k:= first_child(n,d,i);

if k= 0 then last_child:= 0 else last_child:= min{k+d-1,n};

end;

function father(n,d,i);

begin

father:= (i – 2)div d +1;

end;

procedure ПОГРУЖЕНИЕ( i; var name; var key; n,d);

begin

key0:= key[i]; name0:= name[i]; c:= minchild( i, key,n,d);

while (c ≠ i) & (key0 > key[c]) do begin

key[i]:= key[c]; name[i]:= name[c];

{+}

i:= c; c:= minchild ( i, key, n,d);

end;

key[i]:= key0; name[i]:= name0;

{+}

end;

procedure ВСПЛЫТИЕ(i; var name; var key; n,d);

begin

key0:= key[i]; name0:= name[i]; p:= father(n,d,i);

while (i ≠ 1) and (key[p] > key0) do begin

key[i]:= key[p]; name[i]:= name[p];

{+}

i:= p; p:= father(n,d,i);

end;

key[i]:= key0; name[i]:= name0;

{+}

end;

procedure ИЗЪЯТИЕ_МИНИМУМА (var name1; var key1;

var name; var key; var n; d);

begin

name1:= name[1]; key1:= key[1];

name[1]:= name[n]; key[1]:= key[n];

name[n]:= name1; key[n]:= key1;

n:= n-1;

if n>1 then ПОГРУЖЕНИЕ( 1, name,key,n,d);

end;

procedure ОБРАЗОВАTЬ_ОЧЕРЕДЬ(var name; var key; n,d);

begin

for i:= n downto 1 do ПОГРУЖЕНИЕ (i);

end;

Временная сложность операций с n–элементными d-кучами

ПОГРУЖЕНИЕ

O (d logn)

ВСПЛЫТИЕ

O (logn)

ИЗЪЯТИЕ_МИНИМУМА

O (d logd n)

ОБРАЗОВАTЬ_ОЧЕРЕДЬ

O (n)

3. Лабораторные работы

3.1. Нахождение кратчайших путей в графе Постановка задачи

Пусть G = (V, E, W)  ориентированный граф без петель со взвешенными ребрами, где множество вершин V={1, … , n}, множество ребер E  VV, |E| = m, и весовая функция W(u,v) каждому ребру (u, v)E ставит в соответствие его вес  неотрицательное число. Требуется найти кратчайшие пути от заданной вершины sV до всех остальных вершин.

Если исходный граф не является ориентированным, то для использования описанных ниже алгоритмов следует превратить его в ориентированный, заменив каждое его ребро {u,v} на два ребра (u,v) и (v,u) того же веса.

Решением задачи будем считать два массива:

  • массив dist[1..n], (dist[i] – кратчайшее расстояние от вершины s до вершины i).

  • массив up[1..n], (up[i] – предпоследняя вершина в построенном кратчайшем пути из вершины s в вершину i).

В описываемых ниже алгоритмах “+” может быть заменено на любое число, превосходящее длину любого кратчайшего пути из вершины s в любую другую вершину графа G.