La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Cammini minimi da un sorgente Precondizioni: G = grafo orientato e pesato, w: E  R funzione peso, s  V G non ha cicli di peso negativo raggiungibili.

Presentazioni simili


Presentazione sul tema: "Cammini minimi da un sorgente Precondizioni: G = grafo orientato e pesato, w: E  R funzione peso, s  V G non ha cicli di peso negativo raggiungibili."— Transcript della presentazione:

1 Cammini minimi da un sorgente Precondizioni: G = grafo orientato e pesato, w: E  R funzione peso, s  V G non ha cicli di peso negativo raggiungibili da s Dopo qualunque sequenza di RELAX sugli archi di G, eseguita dopo la INITIALIZE_SINGLE_SOURCE (G, s), si ha: 1. G  è un albero di radice s. 2. Se  v  V, d[v] =  (s, v), allora G  è un albero di cammini minimi da s.

2 Se riusciamo ad individuare una strategia per effettuare le RELAX in modo da assicurare la condizione d[v] =  (s, v),  v  V abbiamo risolto il problema di costruire un albero di cammini minimi da s. Grazie alla proprietà 2 si può affermare che:

3 fare su tutti gli archi del grafo un numero di RELAX sufficiente ad assicurare la condizione. Due strategie:

4 fare su tutti gli archi del grafo un numero di RELAX sufficiente ad assicurare la condizione. Algoritmo di Bellman-Ford Due strategie:

5 fare su tutti gli archi del grafo un numero di RELAX sufficiente ad assicurare la condizione. Algoritmo di Bellman-Ford Due strategie: fare le RELAX in modo “guidato” su archi opportuni.

6 fare su tutti gli archi del grafo un numero di RELAX sufficiente ad assicurare la condizione. Algoritmo di Bellman-Ford Due strategie: fare le RELAX in modo “guidato” su archi opportuni. Algoritmo di Dijkstra

7 fare le RELAX in modo “guidato” su archi opportuni.

8 Algoritmo di Dijkstra fare le RELAX in modo “guidato” su archi opportuni. fare le RELAX sugli archi uscenti da un vertice via via scelto “bene” e che non sia già stato preso in esame prima.

9 Algoritmo di Dijkstra fare le RELAX in modo “guidato” su archi opportuni. fare le RELAX sugli archi uscenti da un vertice via via scelto “bene” e che non sia già stato preso in esame prima. 1^ approssimazione dell’algoritmo, dove S è l’insieme dei vertici già considerati:

10 Algoritmo di Dijkstra fare le RELAX in modo “guidato” su archi opportuni. fare le RELAX sugli archi uscenti da un vertice via via scelto “bene” e che non sia già stato preso in esame prima. 1^ approssimazione dell’algoritmo, dove S è l’insieme dei vertici già considerati: INITIALIZE_SINGLE_SOURCE (G, s) S   while S  V[G] do u  vertice scelto “bene” S  S  {u} for ogni v  ADJ[u] do if v  S then RELAX (u, v, w)

11 u  vertice scelto “bene” ???????? Scriviamo un algoritmo greedy che effettua la scelta migliore in ogni istante e dimostreremo che tale scelta si rivela buona anche a lungo termine.

12 u  vertice scelto “bene” ???????? Scriviamo un algoritmo greedy che effettua la scelta migliore in ogni istante e dimostreremo che tale scelta si rivela buona anche a lungo termine. Scelta migliore a breve: un vertice la cui stima della distanza pesata è minima tra tutte quelle dei vertici non ancora considerati.

13 u  vertice scelto “bene” ???????? Scriviamo un algoritmo greedy che effettua la scelta migliore in ogni istante e dimostreremo che tale scelta si rivela buona anche a lungo termine. Scelta migliore a breve: un vertice la cui stima della distanza pesata è minima tra tutte quelle dei vertici non ancora considerati. Riscriviamo l’algoritmo

14 INITIALIZE_SINGLE_SOURCE (G, s) S   while S  V[G] do u  vertice con d minima tra tutti i vertici non in S S  S  {u} for ogni v  ADJ[u] do if v  S then RELAX (u, v, w)

15 INITIALIZE_SINGLE_SOURCE (G, s) S   while S  V[G] do u  vertice con d minima tra tutti i vertici non in S S  S  {u} for ogni v  ADJ[u] do if v  S then RELAX (u, v, w) Non sempre la scelta funziona!

16 A B D C E Ad esempio:

17 A B D C E Ad esempio: Se il vertice sorgente è A, dopo le opportune RELAX, vengono scelti, nell’ordine:

18 A B D C E Ad esempio: Se il vertice sorgente è A, dopo le opportune RELAX, vengono scelti, nell’ordine: A (d[A] = 0, d[B] = d[C] = d[D] = d[E] =  )

19 A B D C E Ad esempio: Se il vertice sorgente è A, dopo le opportune RELAX, vengono scelti, nell’ordine: A (d[A] = 0, d[B] = d[C] = d[D] = d[E] =  ) C (d[B] = 5, d[C] = 2, d[D] = 3, d[E] =  )

20 A B D C E Ad esempio: Se il vertice sorgente è A, dopo le opportune RELAX, vengono scelti, nell’ordine: A (d[A] = 0, d[B] = d[C] = d[D] = d[E] =  C (d[B] = 5, d[C] = 2, d[D] = 3, d[E] =  ) D (d[B] = 5, d[D] = 3, d[E] =  )

21 A B D C E Ad esempio: Se il vertice sorgente è A, dopo le opportune RELAX, vengono scelti, nell’ordine: A (d[A] = 0, d[B] = d[C] = d[D] = d[E] =  C (d[B] = 5, d[C] = 2, d[D] = 3, d[E] =  ) D (d[B] = 5, d[D] = 3, d[E] =  ) E (d[B] = 5, d[E] = 4)

22 A B D C E Ad esempio: Se il vertice sorgente è A, dopo le opportune RELAX, vengono scelti, nell’ordine: A (d[A] = 0, d[B] = d[C] = d[D] = d[E] =  C (d[B] = 5, d[C] = 2, d[D] = 3, d[E] =  ) D (d[B] = 5, d[D] = 3, d[E] =  ) E (d[B] = 5, d[E] = 4) B (d[B] = 5)

23 A B D C E Ad esempio: Ma  (A, E) = 2, mentre d[E] = 4 Se il vertice sorgente è A, dopo le opportune RELAX, vengono scelti, nell’ordine: A (d[A] = 0, d[B] = d[C] = d[D] = d[E] =  C (d[B] = 5, d[C] = 2, d[D] = 3, d[E] =  ) D (d[B] = 5, d[D] = 3, d[E] =  ) E (d[B] = 5, d[E] = 4) B (d[B] = 5)

24 A B D C E Ad esempio: Ma  (A, E) = 2, mentre d[E] = 4 Se il vertice sorgente è A, dopo le opportune RELAX, vengono scelti, nell’ordine: A (d[A] = 0, d[B] = d[C] = d[D] = d[E] =  C (d[B] = 5, d[C] = 2, d[D] = 3, d[E] =  ) D (d[B] = 5, d[D] = 3, d[E] =  ) E (d[B] = 5, d[E] = 4) B (d[B] = 5) La scelta funziona solo in assenza di archi di peso negativo

25 Riscriviamo l ‘algoritmo di Dijkstra aggiungendo come precondizione la richiesta che la funzione peso non assuma valori negativi.

26 Riscriviamo l ‘algoritmo di Dijkstra aggiungendo come precondizione la richiesta che la funzione peso non assuma valori negativi. {G = grafo orientato e pesato and s  V and w: E  R +  {0} funzione peso and G non ha cicli di peso negativo raggiungibili da s}

27 Riscriviamo l ‘algoritmo di Dijkstra aggiungendo come precondizione la richiesta che la funzione peso non assuma valori negativi. {G = grafo orientato e pesato and s  V and w: E  R +  {0} funzione peso}

28 Riscriviamo l ‘algoritmo di Dijkstra aggiungendo come precondizione la richiesta che la funzione peso non assuma valori negativi. INITIALIZE_SINGLE_SOURCE (G, s) S   while S  V[G] do u  vertice con d minima tra tutti i vertici non in S S  S  {u} for ogni v  ADJ[u] do if v  S then RELAX (u, v, w) {G = grafo orientato e pesato and s  V and w: E  R +  {0} funzione peso}

29 Coda con priorità {G = grafo orientato e pesato and s  V and w: E  R +  {0} funzione peso} INITIALIZE_SINGLE_SOURCE (G, s) S   while S  V[G] do u  vertice con d minima tra tutti i vertici non in S S  S  {u} for ogni v  ADJ[u] do if v  S then RELAX (u, v, w)

30 {G = grafo orientato e pesato and s  V and w: E  R +  {0} funzione peso} INITIALIZE_SINGLE_SOURCE (G, s) S   Q  V[G] while S  V[G] do (Q   ) u  extract_min (Q) S  S  {u} for ogni v  ADJ[u] do if v  S (v  Q) then RELAX (u, v, w)

31 INITIALIZE_SINGLE_SOURCE (G, s) S   Q  V[G] while S  V[G] do (Q   ) u  extract_min (Q) S  S  {u} for ogni v  ADJ[u] do if v  S (v  Q) then RELAX (u, v, w) Se è piu conveniente ricorda il nuovo cammino e aggiorna la stima della distanza INITIALIZE_SINGLE_SOURCE (G, s) for ogni v  V do d[v]    [v]  nil d[s]  0

32 Ricorda un altro algoritmo che conosciamo L’algoritmo di PRIM

33 Ricorda un altro algoritmo che conosciamo L’algoritmo di PRIM riscriviamolo

34 INITIALIZE_ KEY (G, s) A   Q  V[G] while Q   do u  extract_min (Q) A  A  {(  [u], u)} for ogni v  ADJ[u] do if v  Q then if key[v] > w(u,v) then key[v]  w(u,v)  [v]  u INITIALIZE_ KEY (G, s) for ogni v  V do key[v]    [v]  nil key[s]  0

35 INITIALIZE_ KEY (G, s) A   Q  V[G] while Q   do u  extract_min (Q) A  A  {u} for ogni v  ADJ[u] do if v  Q then if key[v] > w(u,v) then key[v]  w(u,v)  [v]  u INITIALIZE_ KEY (G, s) for ogni v  V do key[v]    [v]  nil key[s]  0 Se è più conveniente ricorda il nuovo arco e aggiorna la chiave

36 MST_Prim (G, s) INITIALIZE_ KEY (G, s) A   Q  V[G] while Q   do u  extract_min (Q) A  A  {(  [u], u)} for ogni v  ADJ[u] do if v  Q then if key[v] > w(u,v) then key[v]  w(u,v)  [v]  u Dijkstra (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) S   Q  V[G] while Q   do u  extract_min (Q) S  S  {u} for ogni v  ADJ[u] do if v  Q then RELAX (u, v, w)

37 Dijkstra (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) S   Q  V[G] while Q   do u  extract_min (Q) S  S  {u} for ogni v  ADJ[u] do if v  Q then RELAX (u, v, w) Complessità: - coda realizzata con un array lineare O(V 2 )

38 Dijkstra (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) S   Q  V[G] while Q   do u  extract_min (Q) S  S  {u} for ogni v  ADJ[u] do if v  Q then RELAX (u, v, w) Complessità: - coda realizzata con un array lineare O(V 2 ) - coda realizzata con heap binario O((V+E)logV) O(E logV)

39 Dijkstra (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) S   Q  V[G] while Q   do u  extract_min (Q) S  S  {u} for ogni v  ADJ[u] do RELAX (u, v, w) N.B. Poichè per tutti i vertici t  S: d[t] =  (s, t) e d[t] non verrà più modificata da nessuna RELAX, diventa inutile condizionare la RELAX (u,v,w) al fatto che v  Q. Tale semplificazione non è invece possibile nell’algoritmo di Prim.

40 Dobbiamo ancora dimostrare che l’algoritmo è corretto

41 Dijkstra (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) S   Q  V[G] while Q   do u  extract_min (Q) S  S  {u} for ogni v  ADJ[u] do RELAX (u, v, w) {G = grafo orientato e pesato and s  V and w: E  R +  {0} funzione peso}

42 Dijkstra (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) S   Q  V[G] {  t  S: d[t] =  (s, t) and S  Q = V[G] } while Q   do u  extract_min (Q) S  S  {u} for ogni v  ADJ[u] do RELAX (u, v, w) {  t  V[G] : d[t] =  (s, t)} {G = grafo orientato e pesato and s  V and w: E  R +  {0} funzione peso}

43 Dijkstra (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) S   Q  V[G] {  t  S: d[t] =  (s, t) and S  Q = V[G] } while Q   do u  extract_min (Q) S  S  {u} for ogni v  ADJ[u] do RELAX (u, v, w) {  t  V[G] : d[t] =  (s, t)} {G  è un albero di cammini minimi da s} {G = grafo orientato e pesato and s  V and w: E  R +  {0} funzione peso}

44 Algoritmo di Bellman-Ford for ogni arco (u, v)  E[G] do RELAX (u, v, w) INITIALIZE_SINGLE_SOURCE (G, s)

45 Algoritmo di Bellman-Ford for i = 1 to ? do for ogni arco (u, v)  E[G] do RELAX (u, v, w) INITIALIZE_SINGLE_SOURCE (G, s) Si tratta di trovare un numero da sostituire al ?.

46 Algoritmo di Bellman-Ford for i = 1 to ? do for ogni arco (u, v)  E[G] do RELAX (u, v, w) INITIALIZE_SINGLE_SOURCE (G, s) Si tratta di trovare un numero da sostituire al ?. Quante RELAX si dovranno fare per essere sicuri che le stime delle “distanze pesate” per ogni vertice siano diminuite abbastanza da raggiungere le distanze stesse?

47 Ricordiamo una proprietà delle RELAX Se s u v e` un cammino minimo da s a v, allora: {d[u] =  (s, u)} RELAX (u, v, w) {d[v] =  (s, v)}

48 Ricordiamo una proprietà delle RELAX Se s u v e` un cammino minimo da s a v, allora: {d[u] =  (s, u)} RELAX (u, v, w) {d[v] =  (s, v)} Possiamo dedurre che, se vi e` un vertice t la cui distanza pesata da s e` data da un cammino di lunghezza 1, d[t] sara`uguale a  (s, t) dopo la prima sequenza di RELAX su tutti gli archi del grafo.

49 Ricordiamo una proprietà delle RELAX Se s u v è un cammino minimo da s a v, allora: {d[u] =  (s, u)} RELAX (u, v, w) {d[v] =  (s, v)} Possiamo dedurre che, se vi e` un vertice t la cui distanza pesata da s e` data da un cammino di lunghezza 1, d[t] sarà uguale a  (s, t) dopo la prima sequenza di RELAX su tutti gli archi del grafo. Generalizzando: dopo n sequenze di RELAX su tutti gli archi del grafo i vertici t per cui esiste un cammino minimo da s di lunghezza minore o uguale ad n hanno d[t] =  (s, t).

50 Poichè, se nel grafo non ci sono cicli di peso negativo, i cammini minimi hanno al massimo lunghezza |V|-1, abbiamo trovato un valore per il ?

51 Bellman-Ford (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) for i = 1 to |V|-1 do for ogni arco (u, v)  E[G] do RELAX (u, v, w)

52 Bellman-Ford (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) for i = 1 to |V|-1 do for ogni arco (u, v)  E[G] do RELAX (u, v, w) Complessità: O(V. E)

53 Dimostriamo che l’algoritmo è corretto

54 {G = grafo orientato e pesato and s  V and w: E  R funzione peso and non ci sono cicli di peso negativo raggiungibili da s} Bellman-Ford (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) for i = 1 to |V|-1 do for ogni arco (u, v)  E[G] do RELAX (u, v, w) {  t  V[G] : d[t] =  (s, t)}

55 {G = grafo orientato e pesato and s  V and w: E  R funzione peso and non ci sono cicli di peso negativo raggiungibili da s} Bellman-Ford (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) for i = 1 to |V|-1 do for ogni arco (u, v)  E[G] do RELAX (u, v, w) {  t  V[G] : d[t] =  (s, t)} {G  è un albero di cammini minimi da s}

56 Possiamo modificare l’algoritmo in modo da eliminare nella precondizione la richiesta che non vi siano cicli di peso negativo raggiungibili dal sorgente.

57 Possiamo modificare l’algoritmo in modo da eliminare nella precondizione la richiesta che non vi siano cicli di peso negativo raggiungibili dal sorgente. In assenza di cicli di peso negativo raggiungibili dal sorgente, alla fine dell’algoritmo G  è un albero di cammini minimi da s, allora, per ogni vertice v raggiungibile da s, è vera la seguente uguaglianza: d[v] = d[  [v]] + w(  [v], v)

58 Possiamo modificare l’algoritmo in modo da eliminare nella precondizione la richiesta che non vi siano cicli di peso negativo raggiungibili dal sorgente. In assenza di cicli di peso negativo raggiungibili dal sorgente, alla fine dell’algoritmo G  è un albero di cammini minimi da s, allora, per ogni vertice v raggiungibile da s, è vera la seguente uguaglianza: d[v] = d[  [v]] + w(  [v], v) Tale uguaglianza sarà vera anche in presenza di cicli di peso negativo ?

59 Esempio: A B D C E    

60 Esempio: A B D C E     Supponiamo di eseguire le RELAX sugli archi nel seguente ordine:,,,,,

61 Dopo la prima sequenza di RELAX si ha:,,,,, A B D C E   A B D C E     1

62 A B D C E  ,,,,,

63 A B D C E A B D C E  ,,,,, 2

64 A B D C E A B D C E  ,,,,, A B D C E

65 A B D C E A B D C E  ,,,,, A B D C E A B D C E

66 A B D C E  [B] = D d[B] = -1 d[D] = -1 d[B] > d[D] + w(D,B) Bastano 4 cicli di RELAX perchè il grafo ha 5 vertici

67 A B D C E  [B] = D d[B] = -1 d[D] = -1 d[B] > d[D] + w(D,B) Bastano 4 cicli di RELAX perchè il grafo ha 5 vertici Non e` casuale ! Si ha sempre un arco del genere in presenza di cicli di peso negativo

68 Versione finale

69 {G = grafo orientato e pesato and s  V and w: E  R funzione peso} Bellman-Ford (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) for i = 1 to |V|-1 do for ogni arco (u, v)  E[G] do RELAX (u, v, w) for ogni arco (u, v)  E[G] do if d[v] > d[u] + w(u, v) then return “false” return “true”

70 {G = grafo orientato e pesato and s  V and w: E  R funzione peso} Bellman-Ford (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) for i = 1 to |V|-1 do for ogni arco (u, v)  E[G] do RELAX (u, v, w) for ogni arco (u, v)  E[G] do if d[v] > d[u] + w(u, v) then return “false” return “true” {true  non ci sono cicli di peso negativo raggiungibili da s}

71 {G = grafo orientato e pesato and s  V and w: E  R funzione peso} Bellman-Ford (G, w, s) INITIALIZE_SINGLE_SOURCE (G, s) for i = 1 to |V|-1 do for ogni arco (u, v)  E[G] do RELAX (u, v, w) for ogni arco (u, v)  E[G] do if d[v] > d[u] + w(u, v) then return “false” return “true” {true  non ci sono cicli di peso negativo raggiungibili da s} {true  G  è un albero di cammini minimi da s}


Scaricare ppt "Cammini minimi da un sorgente Precondizioni: G = grafo orientato e pesato, w: E  R funzione peso, s  V G non ha cicli di peso negativo raggiungibili."

Presentazioni simili


Annunci Google