• Nie Znaleziono Wyników

3 Dijkstra z ograniczonymi wagami

N/A
N/A
Protected

Academic year: 2021

Share "3 Dijkstra z ograniczonymi wagami"

Copied!
4
0
0

Pełen tekst

(1)

Algorytmy i Struktury Danych, 6. ćwiczenia

2010-11-09

1 Plan zajęć

• d-kopce + zastosowanie w algorytmie Dijkstry,

• Dijkstra z ograniczonymi wagami,

• rozgłaszanie komunikatów,

• system różnych reprezentantów,

• kopce lewicowe.

2 d-kopce

d–kopiec do drzewo zupełne o stopniu d z porządkiem kopcowym (min w korze- niu). Należy pokazać, że poszczególne operacje wykonuje się w czasie:

• Min — O(1)

• DeleteMin — O(d · logd(n))

• DecreaseKey — O(logd(n))

Koszt implementacji algorytmu Dijkstry, przy użyciu d–kopców: O(nd · logd(n) + m · logd(n)).

Zanalizować jak należy dobrać d w zależności od m i n (jeśli za d weźmiemy max(2, dm/ne) to dostajemy O(log m/nm log n)).

3 Dijkstra z ograniczonymi wagami

Aby otrzymać czas O(N W + M ) potrzebujemy kolejki priorytetowej o następu- jących czasach wykonania poszczególnych operacji:

• ExtracMin — O(W )

• DecreaseKey — O(1)

Wystarczy zauważyć, że jeśli do jakiegoś wierzchołka istnieje droga, to jej długość jest ≤ N W . Czyli potrzebujemy tablicy N W elementowej (i–ty element tablicy zawiera listę nieodwiedzonych wierzchołków w odległości i od wierz- chołka początkowego).

1

(2)

4 Rozgłaszanie komunikatów

Dane drzewo T , należy obliczyć czas potrzebny na przesłanie komunikatów do wszystkich węzłów drzewa. Przesłanie komunikatu po jednej krawędzi zajmuje 1 jednostkę czasu.

Algorytm O(n log n):

• jeśli wierzchołek jest liściem to czas = 0,

• wpp. rekurencyjnie oblicz czas potrzebny na rozgłoszenie w poddrzewach,

• posortuj malejąco otrzymane czasy: t1, . . . , tk

• czas = max{i + ti: 1 ≤ i ≤ k}

Aby otrzymać algorytm O(n) trzeba sprytnie obliczać wartości atrybutu czas.

• Q = { liście T },

• while root 6∈ Q do – x = Q.extractM in()

– dodaj x.czas do kolejki parent(x),

– jeśli parent(x) ma już pełną listę poddrzew, to policz parent(x).czas i dodaj parent(x) do kolejki.

Kolejkę Q można zaimplementować w tablicy (i–ty element tablicy zawiera listę wierzchołków o wartości x.czas = i). Sumarycznie operacje extractM in zajmą czas O(n). Dodawanie do kolejki zajmuje czas O(1).

5 System różnych reprezentantów

Dana jest rodzina n niepustych podzbiorów zbioru {1, 2, . . . , n}, z których każdy to całkowitoliczbowy przedział postaci [i, j], i ≤ j. Zaprojektuj efektywny algo- rytm sprawdzania, czy zadana rodzina posiada system różnych reprezentantów, a jeśli tak, to podaje jeden z nich.

Możemy udowodnić, że następujący algorytm zachłanny rozwiązuje problem:

• dane: n przedziałów [li, ri],

• niech K oznacza kopiec zawierający przedziały uporządkowane rosnąco według prawych końców, początkowo kopiec jest pusty

• y = 1

• for i ∈ 1, . . . , n do:

– dodaj do kopca wszystkie przedziały postaci [i, rk],

– jeśli kopiec nie jest pusty, to niech [lr, rk] = ExtractM in(K) – jeśli y > rk to zakończ algorytm — BRAK ROZWIĄZANIA – w przeciwnym przypadku, przydziel jako reprezentanta [lr, rk] war-

tość max(lr, y) – y := max(lr, y) + 1

2

(3)

6 Kopiec lewicowy

Kopiec lewicowy to drzewo binarne, spełniające:

• warunek kopca: key(x) ≥ key(parent(x)),

• oraz dist(lef t(x)) ≤ dist(right(x)), gdzie dist(x) jest odległością do naj- bliższego potomka o mniej niż 2 synach (przyjmujemy, że dist(null) = −1).

Przydatna własność: Jeśli v jest korzeniem kopca lewicowego, to zawiera on co najmniej 2dist(a) węzłów. Czyli jeśli kopiec zawiera n węzłów, to dist(root) = O(log n).

Podstawową operacją jest złączanie dwóch kopców:

Merge(a, b)

1: if a=null then

2: return b;

3: else if b=null then

4: return a;

5: end if

6: if key(b) < key(a) then

7: swap(a, b)

8: end if

9: left(a)=merge(left(a), b)

10: if dist(right(a)) < dist(lef t(a)) then

11: swap(right(a), left(a))

12: end if

13: if lef t(a)=null then

14: dist(a)=0

15: else

16: dist(a)=1+dist(left(a))

17: end if

18: return a

Łatwo pokazać, że złożoność operacji merge wynosi O(dist(a) + dist(b)), czyli O(log n).

Operacje insert i extractM in można zaimplementować używając operacji merge.

Insert(r, x)

1: p=MakeTree(x)

2: r=Merge(r, p)

ExtracMin(r)

1: min=r.value

2: r=Merge(r.lef t, r.right)

3: return min

Operacje IncreaseKey/DecreaseKey możemy zaimplementować w następujący sposób (T – kopiec lewicowy, v – zmieniany węzeł, x – nowa wartość węzła x):

• usuwamy wskazany węzeł v z kopca T (musimy zadbać by wszystkie wa- runki kopca lewicowego były nadal zachowane)

• tworzymy jednoelementowy kopiec lewicowy T0 z wartością x,

3

(4)

• scalamy T i T0.

Usuwanie węzła z kopca możemy wykonać w następujący sposób:

RemoveNode(v)

1: zastąp v przez Merge(v.lef t, v.right)

2: p=v.parent

3: while p 6= nil do

4: if dist(p.lef t) > dist(p.right) then

5: swap(p.lef t, p.right)

6: end if

7: if dist(p) = dist(p.lef t) + 1 then

8: break

9: else

10: dist(p) = dist(p.lef t) + 1; p = p.parent

11: end if

12: end while

Analiza pojedynczego kroku pętli while:

• v należy do poddrzewa p.right:

– jeśli wykonano operację swap, to kopiec musi mieć co najmniej 2k węzłów (gdzie k to odległość pomiędzy v i p)

– wpp. algorytm kończy działanie,

• v należy do poddrzewa p.lef t, jednak zauważmy, że liczba kroków tego typu nie może przekroczyć O(log n)

4

Cytaty

Powiązane dokumenty

Trójkąt równoramienny na płaszczyźnie jest utworzony przez wektor [1, 0] oraz inny wektor o długości 1 w kierunku losowym (wierzchołek trójkąta ma rozkład jednostajny na

Gdy biopsja węzła wartowniczego jest wykonywana przed chemioterapią, wyższe są odsetki identyfikacji węzła (100% w porównaniu do 95%) i niższe są odsetki wyników

[r]

[r]

Doprowadzić wynik do postaci niezawierającej

Ponieważ dany szereg jest bezwzględnie zbieżny, możemy beztrosko zmieniać kolej- ność jego wyrazów, a nawet rozdzielać go na sumę

Dane drzewo T , należy obliczyć czas potrzebny na przesłanie komunikatów do wszystkich

[r]