Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсовая работа1.doc
Скачиваний:
3
Добавлен:
20.04.2019
Размер:
110.08 Кб
Скачать

МИНИСТЕРСТВО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ

ДОНСКОЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

Кафедра ПО ВТ и АС

УТВЕРЖДАЮ

Зав.каф. Р. А. Нейдорф

"______"________2011г.

ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

К курсовой работе _Программирование и основы алгоритмизации___________

(наименование учебной дисциплины)

на тему: «Создание программы алгорима Прима» _____________________________

________________________________________________________________________

________________________________________________________________________

______________________________________________________________

Автор работы _______________Селезнёв Денис_______________________________

Специальность__________________Мехатроника______________________________

Обозначение курсовой работы ___________________ Группа___УМ21___________

Руководитель проекта____________________ ______________________________

(подпись) (Ф.И.О.)

Работа защищена _______________________ ______________________________

(дата) (оценка)

Члены комиссии ________________________ ______________________________

(подпись) (Ф.И.О)

________________________ ______________________________

(подпись) (Ф.И.О)

________________________ ______________________________

(подпись) (Ф.И.О)

Ростов-на-Дону

2011

Оглавление

Теоретическая часть 3

Каркас неориентированного графа 3

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

Свойства минимальных остовов 6

Текст программы. 8

Блок схема 10

Диаграмма Насси-Шнейдермана. 14

Список литературы: 16

Теоретическая часть Каркас неориентированного графа

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

Задача об оптимальном каркасе.

Задача об оптимальном каркасе (стягивающем дереве) состоит в следующем. Дан обыкновенный граф G=(V,E) и весовая функция на множестве ребер u: V R. Вес множества X E определяется как сумма весов составляющих его ребер. Требуется в графе G найти каркас минимального веса. В этом разделе будем предполагать, что граф G связен, так что решением задачи всегда будет дерево. Для решения задачи об оптимальном каркасе известно несколько алгоритмов.

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

Этот алгоритм назван в честь американского математика Роберта Прима (Robert Prim), который открыл этот алгоритм в 1957 г. Впрочем, ещё в 1930 г. этот алгоритм был открыт чешским математиком Войтеком Ярником (Vojtěch Jarník). Кроме того, Эдгар Дейкстра (Edsger Dijkstra) в 1959 г. также изобрёл этот алгоритм, независимо от них.

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

При реализации важно быстро выбирать лёгкое ребро. Алгоритм получает на вход связный граф G и корень r минимального покрывающего дерева. В ходе алгоритма все вершины, ещё не попавшие в дерево, хранятся в очереди с приоритетами. Приоритет вершины v определяется значением key[u], которое равно минимальному весу рёбер, соединяющих v с вершинами дерева А. (Если таких рёбер нет, полагаем key[V] = ). Поле [v] для вершин дерева указывает на родителя, а для вершины v Q указывает на вершину дерева, в которую ведёт ребро веса key[v] (одно из таких рёбер, если их несколько). Мы не храним множество А вершин строимого дерева явно; его можно восстановить как

A = {(v, [v]):v V \{r} \Q}.

В конец работы алгоритма очередь Q пуста, и множество

A = {(v, [v]):v V \{r}}.

есть множество ребер покрывающего дерева.

MST-PRIM(G,W,r)

1 Q V[G]

2 for для каждой вершины u Q

3 do key[u]

4 key[r] 0

5 [r] NIL

6 while Q

7do u EXTRACT-MIN(Q)

8for для каждой вершины v Adj[u]

9 do if v Q и w(u,v)<key[v]

10 then [v] u

11 key(v) w(u,v)

После исполнения строк 1-5 и первого прохода цикла в строках 6 - 11 дерево состоит из единственной вершины r, все остальные вершины находятся в очереди, и значение key[v] для них равно длине ребра из r в v или , если такого ребра нет (в первом случае [v] = r). Таким образом, выполнен описанный выше инвариант (дерево есть часть некоторого остова, для вершин дерева поле указывает на родителя, а для остальных вершин на "ближайшую" вершину дерева - вес ребра до неё хранится в key[v].

Время работы алгоритма Прима зависит от того, как реализована очередь Q.

Тривиальная реализация: алгоритмы за и

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

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

Случай плотных графов: алгоритм за

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

Тогда, чтобы на текущем шаге произвести выбор минимального ребра, надо просто просмотреть эти минимальные рёбра у каждой не выбранной ещё вершины — асимптотика составит .

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

Таким образом, мы получили вариант алгоритма Прима с асимптотикой.