diff --git a/src/ct0371-1/02/03/01/README.md b/src/ct0371-1/02/03/01/README.md index ebaccb65..7e089ae4 100644 --- a/src/ct0371-1/02/03/01/README.md +++ b/src/ct0371-1/02/03/01/README.md @@ -1,18 +1,50 @@ # Dijkstra - - +L'algoritmo trova i **cammini minimi** da una **singola sorgente** $s$ a tutti i nodi di un grafo $G$ con **pesi positivi**, effettuando `relax` sui vicini dei nodi estratti con distanza minore, similarmente a [quello di Prim](../../02/03/README.md): ```c dijkstra(G, w, s) - d, 𝜋 = init_ss(G, s) - Q = G.V // Coda di minima priorità in base a d - while Q.heap_size > 0 - u = extract_min(Q) - for each v in neighbors(G, u) - relax(u, v, w, d, 𝜋) - return (d, 𝜋) + d, 𝜋 = init_ss(G, s) + Q = G.V + while Q.heap_size > 0 + u = extract_min(Q) + for each v in neighbors(G, u) + relax(u, v, w, d, 𝜋) + return (d, 𝜋) ``` + +La **complessità** dipende da `Q`, infatti se $G$ è **denso** conviene usare un **array** perchè $m \approx n^2$: +$$ +T(n, m) = \underbrace{O(n)}_{\texttt{init\_ss}} + n \cdot \hspace{-0.8em} \underbrace{O(n)}_{\texttt{extract\_min}} \hspace{-0.8em} + \underbrace{\sum\limits_{i = 1}^n \text{out-deg}(i)}_{m} \cdot \underbrace{O(1)}_{\texttt{relax}} = O(n^2) +$$ +altrimenti se $G$ è **sparso** conviene una **coda di minima priorità** perchè $m \approx n$: +$$ +T(n, m) = \underbrace{O(n)}_{\texttt{init\_ss}} + n \cdot \underbrace{O(\log n)}_{\texttt{extract\_min}} + \sum\limits_{i = 1}^n \text{out-deg}(i) \cdot \underbrace{O(\log n)}_{\texttt{relax}} = O(m\log n) +$$ + +## Correttezza + +L'algoritmo è **corretto**, perchè alla fine si ha che $\forall u \in V, d_u = \delta(s, u)$ e $G_\pi$ è un _albero di cammini minimi_. + +Si può dimostrare la prima affermazione **supponendo** _per assurdo_ che esista un $u \in V$ per cui $d_u \neq \delta(s, u)$ e che sia **il primo nodo** per cui capita. +In particolare, attraverso le seguenti osservazioni: +1. $u \neq s$, perchè $\delta(s, s) \neq -\infty$ perchè non ci sono pesi negativi, quindi $d_s = \delta(s, s) = 0$ +2. All'estrazione di $u$ l'insieme $V \setminus Q \neq \emptyset$, perchè conterrà almeno $s$ +3. Si può raggiungere $u$ da $s$, ovvero $\delta(s, u) \neq \infty$, perchè altrimenti $\delta(s, u) = \infty = d_u$ è contro l'ipotesi +4. Nello stato dell'algoritmo **dopo** l'estrazione di $s \in V \setminus Q$ e **prima** di $u \in Q$: + + Per il punto _3_ esiste un $p = (s, ..., u)$ **minimo**, e dato un $(x, y)$ in $p$ per cui $x \in V \setminus Q$ e $y \in Q$: + 1. $d_x = \delta(s, x)$ perchè $u$ è il primo per cui l'ipotesi assurda vale + 2. La `relax` su $(x, y)$ causa $d_y = \delta(s, x) + w(x, y) = \delta(s, y)$ per la [convergenza](../README.md#proprietà) + 3. Dato che si sta per estrarre $u$, allora $d_u \leq d_y$ perchè anche $y \in Q$ + 4. $\delta(s, y) \leq \delta(s, u)$ perchè $(s, ..., y)$ è sottocammino di $p$ e non ci sono pesi negativi + 5. $\delta(s, u) \leq d_u$ per il [limite inferiore](../README.md#proprietà) + + Di conseguenza, con le osservazioni _4.5_, _4.3_, _4.2_, _4.4_ rispettivamente: + $$ + \begin{split} + \delta(s, u) \leq d_u &\leq d_y \\ + &= \delta(s, y) \\ + &\leq \delta(s, u) + \end{split} + $$ + ovvero che $\delta(s, u) \leq d_u \leq \delta(s, u)$ che però è **assurdo**, perchè va contro l'ipotesi. diff --git a/src/ct0371-1/02/03/02/README.md b/src/ct0371-1/02/03/02/README.md index b8447699..734a4803 100644 --- a/src/ct0371-1/02/03/02/README.md +++ b/src/ct0371-1/02/03/02/README.md @@ -4,3 +4,33 @@ - Menziona che serve per cammini minimi a singola sorgente/multiple destinazioni - Menziona che funziona con pesi negativi ma senza cicli negativi --> + +L'algoritmo trova i **cammini minimi** da una **singola sorgente** $s$ a tutti i nodi di un grafo $G$ con possibili **pesi negativi**, sempre che sia **senza cicli negativi**, effettuando $n-1$ `relax` sugli archi: +```c +bellman_ford(G, w, s) + d, 𝜋 = init_ss(G, s) + for i = 1 to G.V.length - 1 + for each (u, v) in G.E + relax(u, v, w, d, 𝜋) + for each (u, v) in G.E + if d[v] > d[u] + w(u, v) + return (false, d, 𝜋) // Possiede cicli negativi se c'è ancora un cammino più corto + return (true, d, 𝜋) +``` + +La **complessità**, data da l'`init_ss` da $\Theta(n)$ e dalla `relax` da $\Theta(1)$ chiamata $(n-1) \cdot m$ volte, sarà: +$$ +T(n, m) = \Theta(n) + (n-1) \cdot \Theta(m) + \Theta(m) = \Theta(nm) +$$ + +## Correttezza + +L'algoritmo è **corretto**, perchè se restituisce `true` si avrà che $\forall u \in V, d_u = \delta(s, u)$ e $G_\pi$ è un _albero di cammini minimi_, altrimenti se restituisce `false` significa che un _ciclo negativo_ è **raggiungibile** da $s$. + +Della prima situazione si può dimostrare che: +- $\forall u \in V, d_u = \delta(s, u)$ \ + Se $\delta(s, u) = \infty$ allora alla fine, siccome $u$ non è raggiungibile, anche $d_u = \infty$ grazie alla `init_ss`. + Altrimenti, il cammino minimo [semplice](../../01/README.md) $p = (n_0 = s, ..., n_k = u)$, che avrà al più $n-1$ archi, verrà esplorato un nodo $n_i$ alla volta portando $d_{n_{i+1}}$ a $\delta(s, n_{i+1})$ con la `relax`, per la [convergenza](../README.md#proprietà). + +- $\forall (u, v) \in E, d_v \leq d_u + w(u, v)$, ovvero restituisce `true` \ + Per il punto precedente e la [disuguaglianza triangolare](../README.md#proprietà), la proprietà è verificata. diff --git a/src/ct0371-1/02/03/README.md b/src/ct0371-1/02/03/README.md index ef9818ff..0ee51a13 100644 --- a/src/ct0371-1/02/03/README.md +++ b/src/ct0371-1/02/03/README.md @@ -108,7 +108,7 @@ Sia sui grafi _orientati_ che _non orientati_ valgono le proprietà: - $v = s$, allora $\delta(s, s) \leq d_s = 0$ anche in presenza di _cicli negativi_, i.e. $\delta(s, s) = -\infty$ - Dopo `relax` su $(u, v)$, supponendo _per assurdo_ che causi per la **prima volta** $d_v < \delta(s, v)$: - Siccome la `relax` dev'essere **entrata nell'`if`** perchè le ipotesi siano vere: + Siccome la `relax` dev'essere **entrata nell'`if`** perchè le ipotesi siano vere, $$ d_u + w(u, v) = d_v \hspace{0.4em} < \hspace{0.4em} @@ -117,3 +117,17 @@ Sia sui grafi _orientati_ che _non orientati_ valgono le proprietà: per l'ipotesi e per la _disuguaglianza triangolare_, ovvero che $d_u < \delta(s, u)$ che è assurdo perchè $v$ **non sarebbe il primo** ad aver infranto la proprietà, ma lo sarebbe $u$. - **Proprietà della convergenza** + + Dato $p = (s, ..., u, v)$ minimo, se $d_u = \delta(s, u)$ allora dopo la prima `relax` su $(u, v)$: + $$ + d_v = \delta(s, v) + $$ + + Questo è dimostrabile con il _limite inferiore_, e perchè dopo la `relax` si ha che $d_v \leq d_u + w(u, v)$: + $$ + \begin{split} + \delta(s, v) \leq d_v &\leq d_u + w(u, v) \\ + &= \delta(s, u) + w(u, v) \\ + &= \delta(s, v) + \end{split} + $$