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

Минимальное остовное дерево (МОД)

Алгоритм построения МОД ( Prim, Dijkstra ; O(n*n); "ближ.соседа" )

Алгоритм построения МОД сложности O(m*log n)

Вход : V - множество вершин заданного графа G=(V,E)

D [1..n,1..n] – матрица весов (или ф-ия D(.,.) )

Выход: Vt - множество вершин МОД, Et - множество ветвей МОД, Wt - общий вес МОД

Рабочие: Near[1..(n-1)] - массив вершин, Near[v] – вершина дерева T=(Vt,Et),

ближайшая к вершине v, еще не включенной в T

begin {алгоритм МОД }

{выбор произвольной вершины v0}

Vt := {v0}; Et := { } ; Wt := 0;

for v (V \ Vt) do Near[v] := v0; {инициализация Near[*] }

while Card(Vt) < n do

begin

{ф1:} v := вершина из (V \ Vt) с минимальным значением D[v,Near[v]] ; {см. далее}

Vt := Vt +{v}; Et := Et + { {v,Near[v]} } ; Wt := Wt + D [v,Near[v]]; {добавили v к дереву T}

{коррекция массива Near[*] после включения v в T : }

for x (V \ Vt) do

if D [x,Near[x]] > D [x,v] then Near[x] := v;

end{{while}

end {алгоритма МОД };

{Детализация фрагмента ф1:}

min := + ;

for x (V \ Vt) do if D [x,Near[x]] < min then begin min := D [x,Near[x]] ; v := x end;

{Можно наряду с Near[*] использовать рабочий массив расстояний Dist[x] = D [x,Near[x]] }

Жадный алгоритм построения МОД (Kruskal, O(m*log m))

Vs - множество множеств узлов поддеревьев остовного леса

Begin {алгоритм МОД }

Vs := { }; T:= { };

For v V do добавить {v} к Vs;

Построить очередь Q из всех ребер eE, упорядочив по возрастанию весов;

While Card(Vs) > 1 do

begin

Выбрать из Q ребро e={u,v} с минимальным весом;

Удалить e из Q;

If u и v принадлежат разным подмножествам W1 и W2 из Vs

then

begin Заменить W1 и W2 на W1 W2 в Vs;

T := T {e}

end

end{{while}

end {алгоритма МОД };

Сложность алгоритма O(m*log m) при соответствующей реализации набора непересекающихся подмножеств Vs.

Вход : V - множество вершин заданного графа G=(V,E)

E - множество ребер заданного графа G=(V,E)

D [1..n,1..n] - матрица весов (или ф-ия D(.,.) )

Выход: T - множество ребер МОД

Рабочие: C - множество связных компонент графа (V,T) - лес;

C = {S1,...,Sk}

Кратч[1..n] – массив ребер; Кратч[i] - ребро, кратчайшее из всех ребер, имеющих ровно один конец (вершину) в дереве (в связной компоненте) Si=(Vi,Ti);

Min[1..n] - вспомогательный массив для определения Кратч[i]}

Begin

T:={ }; C :={ {v1},...,{vn} };

While Card(C)<>1 do

Begin

for Si C do min[i]:=+;

for {u,v} E do

begin

пусть i и j такие, что (u Si) & (v Sj);

if i<>j then

begin

if d(u,v) < min[i] then

begin

min[i] := d(u,v);

Кратч[i] :={u,v}

end;

if d(u,v) < min[j] then

begin

min[j] := d(u,v);

Кратч[j] := u,v

end

end {if}

end {for};

{здесь Кратч[i] – кратч. из всех ребер, имеющих ровно один конец в дереве Si=(Vi,Ti)}

for Si C do T := T + { Кратч[i] } ;

Найти множество C связных компонент графа (V,T)

End {while}

End

{Примечание: если при нахождении связных компонент вычислен массив NumComp[*],

то i и j определяются так

i := NumComp[u]; j := NumComp[v]

}

Кратчайшие пути в графе

1. Алгоритм нахождения кратчайшего пути по расстояниям между вершинами

3. Алгоритм Дейкстры (Dijkstra E.W. - 1959) нахождения расстояний от источника до всех остальных вершин в графе с неотрицательными весами дуг

Дано:

  • s, t – фиксированные вершины; s, t V;

  • DL [ * ] – расстояния от вершины s до каждой вершины графа; DL[v]=d(s,v);

  • W[u, v] – матрица весов ребер, u, v V;

Результат: St – стек, содержащий кратчайший путь от s до t, т.е. последовательность вершин s=v0, v1, … , vk=t

Begin

Create(st); st t; v:=t;

While vs do

Begin

u:= вершина, для которой DL[v]=DL[u]+W[u,v];

St u; v:=u;

End {while}

End

2. Алгоритм Форда-Беллмана нахождения расстояний от источника до остальных вершин в графе , не содержащем контуров отрицательной длины

Дано:

  • Орграф G=<V,E> с выделенным источником sV; V = n ;

  • W[u, v] – матрица весов дуг, u, v V;

(граф не содержит контуров отрицательной длины)

Результат: Расстояния от источника s до всех вершин графа DL[v] = d(s,v), v V;

Begin

For v V do DL[v]:=W[s,v]; DL[s]:=0;

For k:=1 to n-2 do

For v V \ {s} do

For u V do DL[v] := min { DL[v], DL[u]+W[u,v] }

End

Индуктивное утверждение (“инвариант”) цикла For k:=1 to n-2 do:

P( [1..k) ) ( d(s,v) DL[v] d[ k | v ] ) - инвариант точки входа тела цикла,

P( [1..k] ) ( d(s,v) DL[v] d[k+1| v ] ) - инвариант точки выхода тела цикла, где d[ k | v ] – длина кратчайшего из путей из s в v, содержащих не более k дуг.

Дано:

  • Орграф G=<V,E> с выделенным источником sV;

  • W[u, v] – матрица весов дуг, u, v V; W[u, v]0

Результат: Расстояния от источника s до всех вершин графа DL[v]=d(s,v), v V;

Begin

For v V do DL[v]:=W[s,v]; DL[s]:=0;

T:= V \ {s}; { S={s} }

While T{ } do

Begin

u:= произвольная вершина xT, такая, что DL[x] = min { DL[p] : pT };

T:=T \ {u}; { S:=S+{u} }

For v T do DL[v] := min { DL[v], DL[u]+W[u,v] }

End {while}

End

Инвариант цикла while:

( V = T + S ) & ( T S = { } ) &

( vS : DL[v] = d(s,v) ) &

( vT : DL[v] = длина кратчайшего из тех путей из s в v, в которых все вершины, кроме v, принадлежат множеству S )

_____________________________________________________________________________

Модификация алгоритма Дейкстры (сложности O(m log n) )

  1. Множество T представляется бинарным деревом (пирамидой) Heap(T)

с приоритетами DL[v];

при этом Inv Heap(T): (uT: (u=отец (v)) (DL[u] DL[v]) ).

Тогда min(T) – в корне Heap(T), и исключение u из T есть удаление корня Heap(T) с восстановлением пирамидальности.

2) Используются списки смежности Adj[*].

Тогда обновление DL[v] после выбора вершины u реализуется следующим образом:

_____________________________________________________________________________

For v Adj[u] do

If DL[u]+W[u,v]<DL[v] then

Begin

DL[v] := DL[u]+W[u,v];

Восстановить пирамидальность Heap(T) вверх от узла v;

End

Соседние файлы в папке Алгоритмы на графах (на псевдокоде)