Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
algorithms.doc
Скачиваний:
29
Добавлен:
06.12.2018
Размер:
9.73 Mб
Скачать
        1. Реберный список с двойными связями (рсдс) (для плоской укладки планарных графов)

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

typedef struct SEdge_

{

int vertex0, vertex1;

int edge0,edge1;

int face0,face1;

}SEdge;

здесь vertex0, vertex1 – номера первой и второй вершины ребра. Порядок вершин задает ориентацию. edge0 – номер первого ребра (в массиве элементов Sedge), выходящего из вершины vertex0, взятого против часовой стрелки (при обходе ребер из вершины vertex0), edge1 – первое ребро, выходящее из вершины vertex1, взятое против часовой стрелки (при обходе ребер из вершины vertex1). face0 – номер грани, находящейся слева от направленного отрезка (vertex0, vertex1), face1 – номер грани, находящейся справа от направленного отрезка (vertex0, vertex1).

Вместо структуры можно использовать массив из шести целых чисел.

На следующем рисунке показан пример графа. Стрелками на ребрах указан порядок вершин в узлах РСДС, соответствующих ребрам. Стрелками между ребрами указаны ссылки на ребра из соответствующих узлов РСДС.

Для данного графа РСДС будет представлен следующим массивом улов:

{

{1,2, 5,2, 1,4},

{2,4, 1,7, 1,4},

{1,3, 1,4, 4,2},

{3,4, 6,5, 3,2},

{1,4, 3,2, 2,1},

{5,3, 7,3, 3,4},

{4,5, 4,6, 3,4}

}

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

  1. Лекция 8

  1. Структуры данных. Графы.

Д.Кнут. Искусство программирования для ЭВМ. тт 1-3. Москва. Мир. 1996-1998

Т.Кормен, Ч.Лейзерсон, Р.Ривест. Алгоритмы. Построение и анализ. Москва. МЦНМО. 1999.

      1. Поиск кратчайшего пути в графе

Пусть дан некоторый конечный граф G=(V,E), состоящий из N вершин, и две его вершины a, bV. Пусть для каждого ребра графа e задано положительное вещественное число l(e), которое будем называть длиной ребра. Требуется найти путь между вершинами графа a и b минимальной длины, т.е. требуется найти последовательность {x1,…,xn}, где xiV, x1=a, xn=b, (xi, xi+1)E с минимально возможной l(xi,xi+1).

Стандартным решением данной задачи является алгоритм Дейкстры.

Основная идея алгоритма заключается в следующем.

Пусть множество Qn представляет собой множество n ближайших вершин к вершине a вместе с длинами пути от a до этих вершин. Т.е. в каждом элементе множества qiQn содержится номер соответствующей вершины xi и длина пути от a до этой вершины li: qi=(xi,li). Можно предполагать, что последовательность {li} является неубывающей.

Утверждается, что ближайшая вершина графа к a из вершин, не внесенных в Qn , задается следующим соотношением:

argmin(v,wV, w Qn , v Qn , (w, v) E: lw+|(w,v)| ) (*)

здесь и далее под w Qn , v Qn имеется в виду, что w встречается среди вершин, внесенных в Qn, а v – нет; длина ребра (w, v) обозначается |(w,v)|. Т.о. элемент qn+1 складывается из вершины v, на которой достигается указанный минимум и соответствующей длины ln+1 = lw+|(w,v)|.

Доказательство. Допустим, найдена вершина s Qn с минимальной длиной до a. Пусть кратчайший путь от a до s проходит по последовательности вершин графа {a,x2,…,xn,s}. Длина пути {a,x2,…,xn} меньше длины пути до s, поэтому xn Qn, но тогда длина пути {a,x2,…,xn,s} должна совпадать с длиной кратчайшего пути от a до найденного выше w.

При поиске значения (*), формально, требуется перебрать все вершины w Qn и для каждой из них требуется перебрать все смежные вершины. Будем далее предполагать, что в графе отсутствуют кратные ребра и петли, тогда процедура (*) требует выполнения O(N2) операций, из чего следует, что суммарное время работы алгоритма есть O(N3).

На самом деле, для выполнения процедуры (*) можно обойтись O(N) операциями. Для этого заметим, что за один поиск значения (*) к множеству Qn добавляется всего одна точка и, поэтому, на следующем шаге значения lx изменятся только у вершин, смежных этой новой точке. Т.о. для пересчета в (*) всех значений lx требуется пересчитать lx только для точек, смежных одной точке, полученной при предыдущем выполнении (*). В силу введенных предположений, это можно сделать за O(N) операций. Искать же минимум lx можно по всем вершинам графа, не принадлежащим Qn, что тоже требует O(N) операций. Т.о. процедуру (*) можно реализовать за O(N) операций.

Для реализации алгоритма Дейкстры следует добавить в каждую вершину w графа вещественное число lw, характеризующее длину кратчайшего пути от вершины a до вершины w и логическую переменную sw, указывающую – посчитана ли на данный момент эта кратчайшая длина пути.

Для упрощения дальнейшей жизни (т.е. для поиска, собственно, кратчайшего пути при определенных значения lw) можно в каждом элементе также хранить ссылку на вершину, из которой мы в данную вершину пришли. Для текущей вершины w будем эту ссылку называть backw. Т.о. элементы Qi представляются в виде q=(w, lw, sw, backw).

Будем предполагать, что конкретная техника нам позволяет инициализировать все lw значением = плюс бесконечность (+INF), что мы и сделаем. Инициализируем все sw значением = FALSE.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]