Skip to content

Commit

Permalink
ct0371-1: Add lesson notes
Browse files Browse the repository at this point in the history
  • Loading branch information
alek3y committed Apr 19, 2024
1 parent d37a74c commit e316b94
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 14 deletions.
58 changes: 45 additions & 13 deletions src/ct0371-1/02/03/01/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,50 @@
# Dijkstra

<!-- TODO:
- Menziona che è molto simile all'algoritmo di prim, che usa coda di minima priorità su d[u]
- Menziona che serve per cammini minimi a singola sorgente/multiple destinazioni
- Menziona che invertendo gli archi e usando la destinazione come sorgente si può usare per sorgente multipla e destinazione singola
- Menziona che funziona solo con pesi positivi -->

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.
30 changes: 30 additions & 0 deletions src/ct0371-1/02/03/02/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
16 changes: 15 additions & 1 deletion src/ct0371-1/02/03/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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}
$$

0 comments on commit e316b94

Please sign in to comment.