From a2e0cbb2a39177891c6ba42be0171410094e17e7 Mon Sep 17 00:00:00 2001
From: Orestis <orestis.malaspinas@pm.me>
Date: Tue, 21 May 2024 07:44:45 +0200
Subject: [PATCH] added 2024

---
 slides/cours_25.md | 1425 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1425 insertions(+)
 create mode 100644 slides/cours_25.md

diff --git a/slides/cours_25.md b/slides/cours_25.md
new file mode 100644
index 0000000..da306e1
--- /dev/null
+++ b/slides/cours_25.md
@@ -0,0 +1,1425 @@
+---
+title: "Théorie des graphes"
+date: "2024-05-21"
+---
+
+# Les graphes
+
+\Huge
+
+Les graphes
+
+# Les graphes! Historique
+
+**Un mini-peu d'histoire...**
+
+## L. Euler et les 7 ponts de Koenigsberg:
+
+* Existe-t-il une promenade sympa, passant **une seule fois** par les 7 ponts et revenant au point de départ?
+
+![Les ponts c'est beau. Source: Wikipédia, <https://bit.ly/37h0yOG>](figs/Konigsberg_bridges.png){width=50%}
+
+. . .
+
+* Réponse: ben non!
+
+# Utilisation quotidienne
+
+## Réseau social
+
+![Source, Wikipedia: <https://bit.ly/3kG6cgo>](figs/Social_Network.svg){width=40%}
+
+* Chaque sommet est un individu.
+* Chaque trait une relation d'amitié.
+* Miam, Miam, Facebook.
+
+# Utilisation quotidienne
+
+## Moteurs de recherche
+
+![Source, Wikipedia: <https://bit.ly/3kG6cgo>](figs/PageRanks-Example.svg){width=40%}
+
+* Sommet est un site.
+* Liens sortants;
+* Liens entrants;
+* Notion d'importance d'un site: combien de liens entrants, pondérés par l'importance du site.
+* Miam, Miam, Google (PageRank).
+
+# Introduction
+
+## Définition, plus ou moins
+
+* Un graphe est un ensemble de sommets, reliés par des lignes ou des flèches.
+
+![Deux exemples de graphes.](figs/ex_graphes.png)
+
+* Des sommets (numérotés 1 à 6);
+* Connectés ou pas par des traits ou des flèches!
+
+# Généralités
+
+## Définitions
+
+* Un **graphe** $G(V, E)$ est constitué
+    * $V$: un ensemble de sommets;
+    * $E$: un ensemble d'arêtes.
+* Une **arête** relie une **paire** de sommets de $V$.
+
+## Remarques
+
+* Il y a **au plus** une arête $E$ par paire de sommets de $V$.
+* La **complexité** d'un algorithme dans un graphe se mesure en terme de $|E|$ et $|V|$, le nombre d'éléments de $E$ et $V$ respectivement.
+
+# Généralités
+
+## Notations
+
+* Une arête d'un graphe **non-orienté** est représentée par une paire **non-ordonnée** $(u,v)=(v,u)$, avec $u,v\in V$.
+* Les arêtes ne sont pas orientées dans un graphe non-orienté (elles sont bi-directionnelles, peuvent être parcourues dans n'importe quel ordre).
+
+## Exemple
+
+
+::: columns
+
+:::: column
+
+![Un graphe non-orienté.](figs/ex_graphe_non_oriente.svg)
+
+
+::::
+
+:::: column
+
+## Que valent $V$, $|V|$, $E$, et $|E|$?
+
+. . .
+
+\begin{align*}
+V&=\{1, 2, 3, 4\},\\
+|V|&=4,\\
+E&=\{(1,2),(2,3),(2,4),(4,1)\},\\
+|E|&=4.
+\end{align*}
+
+::::
+
+:::
+
+# Généralités
+
+## Notations
+
+* Une arête d'un graphe **orienté** est représentée par une paire **ordonnée** $(u,v)\neq(v,u)$, avec $u,v\in V$.
+* Les arêtes sont orientées dans un graphe orienté (étonnant non?).
+
+## Exemple
+
+
+::: columns
+
+:::: column
+
+![Un graphe orienté.](figs/ex_graphe_oriente.svg)
+
+
+::::
+
+:::: column
+
+## Que valent $V$, $|V|$, $E$, et $|E|$?
+
+. . .
+
+\begin{align*}
+V&=\{1, 2, 3, 4\},\\
+|V|&=4,\\
+E&=\{(1,2),(2,3),(2,4),(4,1),(4,2)\},\\
+|E|&=5.
+\end{align*}
+
+::::
+
+:::
+
+# Généralités
+
+## Définition
+
+* Le somme $v$ est **adjacent** au sommet $u$, si et seulement si $(u,v)\in E$;
+* Si un graphe non-orienté contient une arête $(u,v)$, $v$ est adjacent à $u$ et $u$ et adjacent à $v$.
+
+## Exemple
+
+::: columns
+
+:::: column
+
+![Sommet $a$  adjacent à $c$, $c$ adjacent à $a$.](figs/ex_adj_non_or.svg){width=80%}
+
+::::
+
+:::: column
+
+![Sommet $a$  adjacent à $c$.](figs/ex_adj_or.svg){width=80%}
+
+::::
+
+:::
+
+# Généralités
+
+## Définition
+
+* Un **graphe pondéré** ou **valué** est un graphe dont chaque arête a un
+  poids associé, habituellement donné par une fonction de pondération $w:E\rightarrow\mathbb{R}$.
+
+## Exemples
+
+![Graphe pondéré orienté (gauche) et non-orienté (droite).](figs/ex_graph_pond.pdf){width=80%}
+
+
+# Généralités
+
+## Définition
+
+* Dans un graphe $G(V,E)$, une **chaîne** reliant un sommet $u$ à un sommet $v$ est une suite d'arêtes entre les sommets, $w_0$, $w_1$, ..., $w_k$, telles que 
+$$
+(w_i, w_{i+1})\in E,\quad u=w_0,\quad v=w_k,\quad \mbox{pour }0\leq i< k,
+$$
+avec $k$ la longueur de la chaîne (le nombre d'arêtes du chemin).
+
+## Exemples
+
+![Illustration d'une chaîne, ou pas chaîne dans un graphe.](figs/ex_graphe_chaine.pdf){width=80%}
+
+# Généralités
+
+## Définition
+
+* Une **chaîne élémentaire** est une chaîne dont tous les sommets sont distincts, sauf les extrémités qui peuvent être égales
+
+## Exemples
+
+![Illustration d'une chaîne élémentaire.](figs/ex_graphe_chaine_elem.pdf){width=80%}
+
+# Généralités
+
+## Définition
+
+* Une **boucle** est une arête $(v,v)$ d'un sommet vers lui-même.
+
+## Exemples
+
+![Illustration d'une boucle.](figs/ex_graphe_boucle.pdf){width=40%}
+
+# Généralités
+
+## Définition
+
+* Un graphe non-orienté est dit **connexe**, s'il existe un chemin reliant n'importe quelle paire de sommets distincts.
+
+## Exemples
+
+\
+
+::: columns
+
+:::: column
+
+![Graphe connexe. Source, Wikipédia: <https://bit.ly/3yiUzUv>](figs/graphe_connexe.svg){width=80%}
+
+::::
+
+:::: column
+![Graphe non-connexe avec composantes connexes. Source, Wikipédia: <https://bit.ly/3KJB76d>](figs/composantes_connexes.svg){width=60%}
+
+::::
+
+:::
+
+# Généralités
+
+## Définition
+
+* Un graphe orienté est dit **fortement connexe**, s'il existe un chemin reliant n'importe quelle paire de sommets distincts.
+
+## Exemples
+
+\
+
+::: columns
+
+:::: column
+
+![Graphe fortement connexe.](figs/ex_graph_fort_connexe.pdf){width=60%}
+
+::::
+
+:::: column
+
+![Composantes fortement connexes. Source, Wikipédia: <https://bit.ly/3w5PL2l>](figs/composantes_fortement_connexes.svg){width=100%}
+
+::::
+
+:::
+
+# Généralités
+
+## Définition
+
+* Un **cycle** dans un graphe *non-orienté* est une chaîne de longueur $\geq 3$ telle que le 1er sommet de la chaîne est le même que le dernier, et dont les arêtes sont distinctes.
+* Pour un graphe *orienté* on parle de **circuit**.
+* Un graphe sans cycles est dit **acyclique**.
+
+## Exemples
+
+![Illustration de cycles, ou pas.](figs/ex_graphe_cycle.pdf){width=100%}
+
+# Question de la mort
+
+* Qu'est-ce qu'un graphe connexe acyclique?
+
+. . .
+
+* Un arbre!
+
+# Représentations
+
+* La complexité des algorithmes sur les graphes s'expriment en fonction du nombre de sommets $V$, et du nombre d'arêtes $E$:
+    * Si $|E|\sim |V|^2$, on dit que le graphe est **dense**.
+    * Si $|E|\sim |V|$, on dit que le graphe est **peu dense**.
+* Selon qu'on considère des graphes denses ou peu denses, différentes structure de données peuvent être envisagées.
+
+## Question
+
+* Comment peut-on représenter un graphe informatiquement? Des idées (réflexion de quelques minutes)?
+
+. . .
+
+* Matrice/liste d'adjacence.
+
+# Matrice d'adjacence
+
+* Soit le graphe $G(V,E)$, avec $V=\{1, 2, 3, ..., n\}$;
+* On peut représenter un graphe par une **matrice d'adjacence**, $A$, de dimension $n\times n$ définie par
+$$
+A_{ij}=\left\{ \begin{array}{ll}
+         1 & \mbox{si } i,j\in E,\\
+         0 & \mbox{sinon}.
+         \end{array} \right.
+$$
+
+
+::: columns
+
+:::: column
+
+## Exemple
+
+```{.mermaid format=pdf width=400 loc=figs/}
+graph LR;
+    1---2;
+    1---4;
+    2---5;
+    4---5;
+    5---3;
+```
+
+::::
+
+:::: column
+
+\footnotesize
+
+## Quelle matrice d'adjacence? 
+
+. . .
+
+```
+   || 1 | 2 | 3 | 4 | 5
+===||===|===|===|===|===
+ 1 || 0 | 1 | 0 | 1 | 0
+---||---|---|---|---|---
+ 2 || 1 | 0 | 0 | 0 | 1
+---||---|---|---|---|---
+ 3 || 0 | 0 | 0 | 0 | 1
+---||---|---|---|---|---
+ 4 || 1 | 0 | 0 | 0 | 1
+---||---|---|---|---|---
+ 5 || 0 | 1 | 1 | 1 | 0
+```
+
+::::
+
+:::
+
+# Matrice d'adjacence
+
+## Remarques
+
+* Zéro sur la diagonale.
+* La matrice d'un graphe non-orienté est symétrique
+
+$$
+A_{ij}=A_{ji}, \forall i,j\in[1,n]
+$$.
+
+::: columns
+
+:::: column
+
+```{.mermaid format=pdf width=400 loc=figs/}
+graph LR;
+    1---2;
+    1---4;
+    2---5;
+    4---5;
+    5---3;
+```
+
+::::
+
+:::: column
+
+\footnotesize
+
+```
+   || 1 | 2 | 3 | 4 | 5
+===||===|===|===|===|===
+ 1 || 0 | 1 | 0 | 1 | 0
+---||---|---|---|---|---
+ 2 || 1 | 0 | 0 | 0 | 1
+---||---|---|---|---|---
+ 3 || 0 | 0 | 0 | 0 | 1
+---||---|---|---|---|---
+ 4 || 1 | 0 | 0 | 0 | 1
+---||---|---|---|---|---
+ 5 || 0 | 1 | 1 | 1 | 0
+```
+
+::::
+
+:::
+
+# Matrice d'adjacence
+
+* Pour un graphe orienté (digraphe)
+
+::: columns
+
+:::: column
+
+## Exemple
+
+```{.mermaid format=pdf width=400 loc=figs/}
+graph LR;
+    2-->1;
+    1-->4;
+    2-->5;
+    5-->2;
+    4-->5;
+    5-->3;
+```
+
+::::
+
+:::: column
+
+\footnotesize
+
+## Quelle matrice d'adjacence? 
+
+. . .
+
+```
+   || 1 | 2 | 3 | 4 | 5
+===||===|===|===|===|===
+ 1 || 0 | 0 | 0 | 1 | 0
+---||---|---|---|---|---
+ 2 || 1 | 0 | 0 | 0 | 1
+---||---|---|---|---|---
+ 3 || 0 | 0 | 0 | 0 | 0
+---||---|---|---|---|---
+ 4 || 0 | 0 | 0 | 0 | 1
+---||---|---|---|---|---
+ 5 || 0 | 1 | 1 | 0 | 0
+```
+
+::::
+
+:::
+
+* La matrice d'adjacence n'est plus forcément symétrique
+$$
+A_{ij}\neq A_{ji}.
+$$
+
+# Stockage
+
+* Quel est l'espace nécessaire pour stocker une matrice d'adjacence pour un graphe orienté?
+
+. . .
+
+* $\mathcal{O}(|V|^2)$.
+* Quel est l'espace nécessaire pour stocker une matrice d'adjacence pour un graphe non-orienté?
+
+. . .
+
+* $\mathcal{O}(|V|-1)|V|/2$.
+
+# Considérations d'efficacité
+
+* Dans quel type de graphes la matrice d'adjacence est utile?
+
+. . .
+
+* Dans les graphes denses.
+* Pourquoi?
+
+. . .
+
+* Dans les graphes peu denses, la matrice d'adjacence est essentiellement composée de `0`.
+
+## Remarque
+
+* Dans la majorité des cas, les grands graphes sont peu denses.
+* Comment représenter un graphe autrement?
+
+# La liste d'adjacence (non-orienté)
+
+* Pour chaque sommet $v\in V$, stocker les sommets adjacents à $v$-
+* Quelle structure de données pour la liste d'adjacence?
+
+. . .
+
+* Tableau de liste chaînée, vecteur (tableau dynamique), etc.
+
+
+::: columns
+
+:::: column
+
+## Exemple
+
+![Un graphe non-orienté.](figs/ex_graph_adj.pdf){width=80%}
+
+::::
+
+:::: column
+
+
+## Quelle liste d'adjacence? 
+
+. . .
+
+![La liste d'adjacence.](figs/ex_graph_list_adj.pdf)
+
+
+::::
+
+:::
+
+# La liste d'adjacence (orienté)
+
+
+::: columns
+
+:::: column
+
+## Quelle liste d'adjacence pour...
+
+* Matrix (2min)
+
+```{.mermaid format=pdf width=400 loc=figs/}
+graph LR;
+    0-->1;
+    0-->2;
+    1-->2;
+    3-->0;
+    3-->1;
+    3-->2;
+```
+
+::::
+
+:::: column
+
+```
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+::::
+
+:::
+
+# Complexité
+
+## Stockage
+
+* Quelle espace est nécessaire pour stocker une liste d'adjacence (en fonction de $|E|$ et $|V|$)?
+
+. . .
+
+$$
+\mathcal{O}(|E|)
+$$
+
+* Pour les graphes *non-orientés*: $\mathcal{O}(2|E|)$.
+* Pour les graphes *orientés*: $\mathcal{O}(|E|)$.
+
+## Définition
+
+* Le **degré** d'un sommet $v$, est le nombre d'arêtes incidentes du sommet (pour les graphes orientés on a un degré entrant ou sortant).
+* Comment on retrouve le degré de chaque sommet avec la liste d'adjacence?
+
+. . .
+
+* C'est la longueur de la liste chaînée.
+
+
+# Parcours
+
+* Beaucoup d'applications nécessitent de parcourir des graphes:
+    * Trouver un chemin d'un sommet à un autre;
+    * Trouver si le graphe est connexe;
+* Il existe *deux* parcours principaux:
+    * en largeur (Breadth-First Search);
+    * en profondeur (Depth-First Search).
+* Ces parcours créent *un arbre* au fil de l'exploration (si le graphe est non-connexe cela crée une *forêt*, un ensemble d'arbres).
+
+# Illustration: parcours en largeur
+
+![Le parcours en largeur.](figs/parcours_larg.pdf){width=80%}
+
+# Exemple
+
+## Étape par étape (blanc non-visité)
+
+![Initialisation.](figs/parcours_larg_0.pdf){width=50%}
+
+## Étape par étape (gris visité)
+
+![On commence en `x`.](figs/parcours_larg_1.pdf){width=50%}
+
+# Exemple
+
+## Étape par étape
+
+![On commence en `x`.](figs/parcours_larg_1.pdf){width=50%}
+
+## Étape par étape (vert à visiter)
+
+![Vister `w`, `t`, `y`.](figs/parcours_larg_2.pdf){width=50%}
+
+# Exemple
+
+## Étape par étape
+
+![Vister `w`, `t`, `y`.](figs/parcours_larg_2.pdf){width=50%}
+
+## Étape par étape
+
+![`w`, `t`, `y` visités. `u`, `s` à visiter.](figs/parcours_larg_3.pdf){width=50%}
+
+# Exemple
+
+## Étape par étape
+
+![`w`, `t`, `y` visités. `u`, `s` à visiter.](figs/parcours_larg_3.pdf){width=50%}
+
+## Étape par étape
+
+![`u`, `s`, visités. `r` à visiter.](figs/parcours_larg_4.pdf){width=50%}
+
+# Exemple
+
+## Étape par étape
+
+![`u`, `s`, visités. `r` à visiter.](figs/parcours_larg_4.pdf){width=50%}
+
+## Étape par étape
+
+![`r` visité. `v` à visiter.](figs/parcours_larg_5.pdf){width=50%}
+
+# Exemple
+
+## Étape par étape
+
+![`r` visité. `v` à visiter.](figs/parcours_larg_5.pdf){width=50%}
+
+## Étape par étape
+
+![The end. Plus rien à visiter!](figs/parcours_larg_6.pdf){width=50%}
+
+# En faisant ce parcours...
+
+
+::: columns
+
+:::: column
+
+## Du parcours de l'arbre
+
+![](figs/parcours_larg_6.pdf){width=100%}
+
+::::
+
+:::: column
+
+## Quel arbre est créé par le parcours (2min)?
+
+. . .
+
+```{.mermaid format=pdf width=400 loc=figs/}
+graph LR;
+    0[x]-->1[w];
+    0-->2[t];
+    0-->3[y];
+    2-->9[u];
+    1-->4[s];
+    4-->5[r];
+    5-->6[v];
+```
+
+::::
+
+:::
+
+## Remarques
+
+* Le parcours dépend du point de départ dans le graphe.
+* L'arbre sera différent en fonction du noeud de départ, et de l'ordre de parcours des voisins d'un noeud.
+
+# Le parcours en largeur
+
+## L'algorithme, idée générale (3min, matrix)?
+
+. . .
+
+```C
+v = un sommet du graphe
+i = 1
+pour sommet dans graphe et sommet non-visité
+    visiter(v, sommet, i) // marquer sommet à distance i visité 
+    i += 1
+```
+
+## Remarque
+
+* `i` est la distance de plus cours chemin entre `v` et les sommets en cours de visite.
+
+
+# Le parcours en largeur
+
+## L'algorithme, pseudo-code (3min, matrix)?
+
+* Comment garder la trace de la distance?
+
+. . .
+
+* Utilisation d'une **file**
+
+. . .
+
+```C
+initialiser(graphe) // tous sommets sont non-visités
+file = visiter(sommet, vide) // sommet est un sommet du graphe au hasard
+tant que !est_vide(file)
+    v = défiler(file)
+    file = visiter(v, file)
+```
+
+## Que fait visiter?
+
+```
+file visiter(sommet, file)
+    sommet = visité
+    pour w = chaque arête de sommet
+        si w != visité
+            file = enfiler(file, w)
+    retourne file
+```
+
+# Exercice (5min)
+
+## Appliquer l'algorithme sur le graphe
+
+![](figs/parcours_larg_0.pdf){width=50%}
+
+* En partant de `v`, `s`, ou `u` (par colonne de classe).
+* Bien mettre à chaque étape l'état de la file.
+
+# Complexité du parcours en largeur
+
+## Étape 1
+
+* Extraire un sommet de la file;
+
+## Étape 2
+
+* Traîter tous les sommets adjacents.
+
+## Quelle est la complexité?
+
+. . .
+
+* Étape 1: $\mathcal{O}(|V|)$,
+* Étape 2: $\mathcal{O}(2|E|)$,
+* Total: $\mathcal{O}(|V| + |2|E|)$.
+
+# Exercice
+
+* Établir la liste d'adjacence et appliquer l'algorithme de parcours en largeur au graphe
+
+```{.mermaid format=pdf width=400 loc=figs/}
+graph LR;
+    1---2;
+    1---3;
+    1---4;
+    2---3;
+    2---6;
+    3---6;
+    3---4;
+    3---5;
+    4---5;
+```
+
+
+# Illustration: parcours en profondeur
+
+![Le parcours en profondeur. À quel parcours d'arbre cela ressemble-t-il?](figs/parcours_prof.pdf){width=80%}
+
+# Parcours en profondeur
+
+## Idée générale
+
+* Initialiser les sommets comme non-lus
+* Visiter un sommet
+* Pour chaque sommet visité, on visite un sommet adjacent s'il est pas encore visité récursivement.
+
+## Remarque
+
+* La récursivité est équivalent à l'utilisation d'une **pile**.
+
+# Parcours en profondeur
+
+## Pseudo-code (5min)
+
+. . .
+
+```C
+initialiser(graphe) // tous sommets sont non-visités
+pile = visiter(sommet, vide) // sommet est un sommet du graphe au hasard
+tant que !est_vide(pile)
+    v = dépiler(pile)
+    pile = visiter(v, pile)
+```
+
+## Que fait visiter?
+
+. . .
+
+```C
+pile visiter(sommet, pile)
+    sommet = visité
+    pour w = chaque arête de sommet
+        si w != visité
+            pile = empiler(pile, w)
+    retourne pile
+```
+
+
+# Exercice
+
+* Établir la liste d'adjacence et appliquer l'algorithme de parcours en profondeur au graphe
+
+```{.mermaid format=pdf width=400 loc=figs/}
+graph LR;
+    1---2;
+    1---3;
+    1---4;
+    2---3;
+    2---6;
+    3---6;
+    3---4;
+    3---5;
+    4---5;
+```
+
+# Interprétation des parcours
+
+* Un graphe vu comme espace d'états (sommet: état, arête: action);
+    * Labyrinthe;
+    * Arbre des coups d'un jeu.
+
+. . .
+
+* BFS (Breadth-First) ou DFS (Depth-First) parcourent l'espace des états à la recherche du meilleur mouvement.
+    * Les deux parcourent *tout* l'espace;
+    * Mais si l'arbre est grand, l'espace est gigantesque!
+
+. . .
+
+* Quand on a un temps limité
+    * BFS explore beaucoup de coups dans un futur proche;
+    * DFS explore peu de coups dans un futur lointain.
+
+# Contexte: les réseaux (informatique, transport, etc.)
+
+* Graphe orienté;
+* Source: sommet `s`;
+* Destination: sommet `t`;
+* Les arêtes ont des poids (coût d'utilisation, distance, etc.);
+* Le coût d'un chemin est la somme des poids des arêtes d'un chemin.
+
+## Problème à résoudre
+
+* Quel est le plus court chemin entre `s` et `t`.
+
+# Exemples d'application de plus court chemin
+
+## Devenir riches!
+
+* On part d'un tableau de taux de change entre devises.
+* Quelle est la meilleure façon de convertir l'or en dollar?
+
+![Taux de change.](figs/taux_change.pdf){width=80%}
+
+. . .
+
+* 1kg d'or => 327.25 dollars
+* 1kg d'or => 208.1 livres => 327 dollars
+* 1kg d'or => 455.2 francs => 304.39 euros => 327.28 dollars
+
+# Exemples d'application de plus court chemin
+
+## Formulation sous forme d'un graphe: Comment (3min)?
+
+![Taux de change.](figs/taux_change.pdf){width=80%}
+
+
+# Exemples d'application de plus court chemin
+
+## Formulation sous forme d'un graphe: Comment (3min)?
+
+![Graphes des taux de change.](figs/taux_change_graphe.pdf){width=60%}
+
+* Un sommet par devise;
+* Une arête orientée par transaction possible avec le poids égal au taux de change;
+* Trouver le chemin qui maximise le produit des poids.
+
+. . .
+
+## Problème
+
+* On aimerait plutôt avoir une somme...
+
+
+# Exemples d'application de plus court chemin
+
+## Conversion du problème en plus court chemin
+
+* Soit `taux(u, v)` le taux de change entre la devise `u` et `v`.
+* On pose `w(u,w)=-log(taux(u,v))`
+* Trouver le chemin poids minimal pour les poids `w`.
+
+![Graphe des taux de change avec logs.](figs/taux_change_graphe_log.pdf){width=60%}
+
+* Cette conversion se base sur l'idée que
+
+$$
+\log(u\cdot v)=\log(u)+\log(v).
+$$
+
+# Applications de plus courts chemins
+
+## Quelles applications voyez-vous?
+
+. . .
+
+* Déplacement d'un robot;
+* Planificaiton de trajet / trafic urbain;
+* Routage de télécommunications;
+* Réseau électrique optimal;
+* ...
+
+# Plus courts chemins à source unique
+
+* Soit un graphe, $G=(V, E)$, une fonction de pondération $w:E\rightarrow\mathbb{R}$, et un sommet $s\in V$
+  * Trouver pour tout sommet $v\in V$, le chemin de poids minimal reliant $s$ à $v$.
+* Algorithmes standards:
+  * Dijkstra (arêtes de poids positif seulement);
+  * Bellman-Ford (arêtes de poids positifs ou négatifs, mais sans cycles).
+* Comment résoudre le problèmes si tous les poids sont les mêmes?
+
+. . .
+
+* Un parcours en largeur!
+
+# Algorithme de Dijkstra
+
+## Comment chercher pour un plus court chemin?
+
+. . .
+
+```
+si distance(u,v) > distance(u,w) + distance(w,v)
+    on passe par w plutôt qu'aller directement
+```
+
+# Algorithme de Dijkstra (1 à 5)
+
+* $D$ est le tableau des distances au sommet $1$: $D[7]$ est la distance de 1 à 7.
+* Le chemin est pas forcément direct.
+* $S$ est le tableau des sommets visités.
+
+::: columns
+
+:::: column
+
+![Initialisation.](figs/dijkstra_0.png)
+
+::::
+
+:::: column
+
+. . .
+
+![1 visité, `D[2]=1`, `D[4]=3`.](figs/dijkstra_1.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra (1 à 5)
+
+::: columns
+
+:::: column
+
+![Plus court est 2.](figs/dijkstra_1.png)
+
+
+::::
+
+:::: column
+
+. . .
+
+![2 visité, `D[3]=2`, `D[7]=3`.](figs/dijkstra_2.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra (1 à 5)
+
+::: columns
+
+:::: column
+
+![Plus court est 3.](figs/dijkstra_2.png)
+
+
+::::
+
+:::: column
+
+. . .
+
+![3 visité, `D[7]=3` inchangé, `D[6]=6`.](figs/dijkstra_3.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra (1 à 5)
+
+
+::: columns
+
+:::: column
+
+![Plus court est 4 ou 7.](figs/dijkstra_3.png)
+
+
+::::
+
+:::: column
+
+. . .
+
+![4 visité, `D[7]=3` inchangé, `D[5]=9`.](figs/dijkstra_4.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra (1 à 5)
+
+::: columns
+
+:::: column
+
+![Plus court est `7`.](figs/dijkstra_4.png)
+
+
+::::
+
+:::: column
+
+. . .
+
+![7 visité, `D[5]=7`, `D[6]=6` inchangé.](figs/dijkstra_5.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra (1 à 5)
+
+::: columns
+
+:::: column
+
+![Plus court est 6.](figs/dijkstra_5.png)
+
+
+::::
+
+:::: column
+
+. . .
+
+![`6` visité, `D[5]=7` inchangé.](figs/dijkstra_6.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra (1 à 5)
+
+::: columns
+
+:::: column
+
+![Plus court est 5 et c'est la cible.](figs/dijkstra_6.png)
+
+::::
+
+:::: column
+
+. . .
+
+![The end, tous les sommets ont été visités.](figs/dijkstra_7.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra
+
+## Idée générale
+
+* On assigne à chaque noeud une distance $0$ pour $s$, $\infty$ pour les autres.
+* Tous les noeuds sont marqués non-visités.
+* Depuis du noeud courant, on suit chaque arête du noeud vers un sommet non visité et on calcule le poids du chemin à chaque voisin et on met à jour sa distance si elle est plus petite que la distance du noeud.
+* Quand tous les voisins du noeud courant ont été visités, le noeud est mis à visité (il ne sera plus jamais visité).
+* Continuer avec le noeud à la distance la plus faible.
+* L'algorithme est terminé losrque le noeud de destination est marqué comme visité, ou qu'on a plus de noeuds qu'on peut visiter et que leur distance est infinie.
+
+# Algorithme de Dijkstra
+
+## Pseudo-code (5min, matrix)
+
+\footnotesize
+
+. . .
+
+```C
+tab dijkstra(graph, s, t)
+    pour chaque v dans graphe
+        distance[v] = infini
+        q = ajouter(q, v)
+    distance[s] = 0
+    tant que non_vide(q)
+    // sélection de u t.q. la distance dans q est min
+        u = min(q, distance)
+        si u == t // on a atteint la cible
+            retourne distance
+        q = remove(q, u)
+        // voisin de u encore dans q
+        pour chaque v dans voisinage(u, q)
+        // on met à jour la distance du voisin en passant par u 
+            n_distance = distance[u] + w(u, v)
+            si n_distance < distance[v]
+                distance[v] = n_distance
+    retourne distance
+```
+
+# Algorithme de Dijkstra
+
+* Cet algorithme, nous donne le plus court chemin mais...
+* ne nous donne pas le chemin!
+
+## Comment modifier l'algorithme pour avoir le chemin?
+
+. . .
+
+* Pour chaque nouveau noeud à visiter, il suffit d'enregistrer d'où on est venu!
+* On a besoin d'un tableau `precedent`.
+
+## Modifier le pseudo-code ci-dessus pour ce faire (3min matrix)
+
+# Algorithme de Dijkstra
+
+\footnotesize
+
+```C
+tab, tab dijkstra(graph, s, t)
+    pour chaque v dans graphe
+        distance[v] = infini
+        precedent[v] = indéfini
+        q = ajouter(q, v)
+    distance[s] = 0
+    tant que non_vide(q)
+    // sélection de u t.q. la distance dans q est min
+        u = min(q, distance) 
+        si u == t
+            retourne distance
+        q = remove(q, u)
+        // voisin de u encore dans q
+        pour chaque v dans voisinage(u, q) 
+            n_distance = distance[u] + w(u, v)
+            si n_distance < distance[v]
+                distance[v] = n_distance
+                precedent[v] = u
+    retourne distance, precedent
+```
+
+# Algorithme de Dijkstra
+
+## Comment reconstruire un chemin ?
+
+. . .
+
+```C
+pile parcours(precedent, s, t)
+    sommets = vide
+    u = t
+    // on a atteint t ou on ne connait pas de chemin
+    si u != s && precedent[u] != indéfini 
+        tant que vrai 
+            sommets = empiler(sommets, u)
+            u = precedent[u]
+            si u == s // la source est atteinte
+                retourne sommets
+    retourne sommets
+```
+
+# Algorithme de Dijkstra amélioré
+
+## On peut améliorer l'algorithme
+
+* Avec une file de priorité!
+
+## Une file de priorité est
+
+* Une file dont chaque élément possède une priorité,
+* Elle existe en deux saveurs: `min` ou `max`:
+    * File `min`: les éléments les plus petits sont retirés en premier.
+    * File `max`: les éléments les plus grands sont retirés en premier.
+* On regarde l'implémentation de la `max`.
+
+## Comment on fait ça?
+
+. . .
+
+* On insère les éléments à haute priorité tout devant dans la file!
+
+# Les files de priorité
+
+## Trois fonction principales
+
+```C
+booléen est_vide(element) // triviale
+element enfiler(element, data, priorite)
+data defiler(element)
+rien changer_priorite(element, data, priorite)
+nombre priorite(element) // utilitaire
+```
+
+## Pseudo-implémentation: structure (1min)
+
+. . .
+
+```C
+struct element
+    data
+    priorite
+    element suivant
+```
+
+# Les files de priorité
+
+## Pseudo-implémentation: enfiler (2min)
+
+. . .
+
+```C
+element enfiler(element, data, priorite)
+    n_element = creer_element(data, priorite)
+    si est_vide(element)
+        retourne n_element
+    si priorite(n_element) > priorite(element)
+        n_element.suivant = element
+        retourne n_element
+    sinon
+        tmp = element
+        prec = element
+        tant que !est_vide(tmp) && priorite < priorite(tmp)
+            prec = tmp
+            tmp = tmp.suivant
+        prev.suivant = n_element
+        n_element.suivant = tmp
+        retourne element           
+```
+
+# Les files de priorité
+
+## Pseudo-implémentation: defiler (2min)
+
+. . .
+
+```C
+data, element defiler(element)
+    si est_vide(element)
+        retourne AARGL!
+    sinon
+        tmp = element.data
+        n_element = element.suivant
+        liberer(element)
+        retourne tmp, n_element
+```
+
+# Algorithme de Dijkstra avec file de priorité min
+
+```C
+distance, precedent dijkstra(graphe, s, t):
+    distance[source] = 0
+    fp = file_p_vide()
+    pour v dans sommets(graphe)
+        si v != s
+            distance[v] = infini
+            precedent[v] = indéfini
+        fp = enfiler(fp, v, distance[v])
+    tant que !est_vide(fp)
+        u, fp = defiler(fp)
+        pour v dans voisinage de u
+            n_distance = distance[u] + w(u, v)
+            si n_distance < distance[v]
+                distance[v] = n_distance
+                precedent[v] = u
+                fp = changer_priorite(fp, v, n_distance)
+    retourne distance, precedent
+```
+
+# Algorithme de Dijkstra avec file
+
+\footnotesize
+
+```C
+distance dijkstra(graphe, s, t)
+---------------------------------------------------------
+    pour v dans sommets(graphe)
+O(V)    si v != s
+            distance[v] = infini
+O(V)        fp = enfiler(fp, v, distance[v]) // notre impl est nulle
+------------------O(V * V)-------------------------------
+    tant que !est_vide(fp)
+O(1)    u, fp = defiler(fp)
+---------------------------------------------------------
+O(E)    pour v dans voisinage de u
+            n_distance = distance[u] + w(u, v)
+            si n_distance < distance[v]
+                distance[v] = n_distance
+O(V)            fp = changer_priorite(fp, v, n_distance)
+---------------------------------------------------------
+    retourne distance
+```
+
+* Total: $\mathcal{O}(|V|^2+|E|\cdot |V|)$:
+    * Graphe dense: $\mathcal{O}(|V|^3)$ 
+    * Graphe peu dense: $\mathcal{O}(|V|^2)$ 
+
+# Algorithme de Dijkstra avec file
+
+## On peut faire mieux
+
+* Avec une meilleure implémentation de la file de priorité:
+    * Tas binaire: $\mathcal{O}(|V|\log|V|+|E|\log|V|)$.
+    * Tas de Fibonnacci: $\mathcal{O}(|V|+|E|\log|V|)$
+* Graphe dense: $\mathcal{O}(|V|^2\log|V|)$.
+* Graphe peu dense: $\mathcal{O}(|V|\log|V|)$.
+
+# Algorithme de Dijkstra (exercice, 5min) 
+
+![L'exercice.](figs/dijkstra_exo.png){width=60%}
+
+* Donner la liste de priorité, puis...
+
+## A chaque étape donner:
+
+* Le tableau des distances à `a`;
+* Le tableau des prédécesseurs;
+* L'état de la file de priorité.
+
+# Algorithme de Dijkstra (corrigé) 
+
+![Le corrigé partie 1.](figs/dijkstra_ex_0.png)
+
+# Algorithme de Dijkstra (corrigé) 
+
+![Le corrigé partie 2.](figs/dijkstra_ex_1.png)
+
+# Algorithme de Dijkstra (corrigé) 
+
+![Le corrigé partie 3.](figs/dijkstra_ex_2.png)
+
+# Algorithme de Dijkstra (corrigé) 
+
+![Le corrigé partie 4.](figs/dijkstra_ex_3.png)
+
+# Algorithme de Dijkstra (corrigé) 
+
+![Le corrigé partie 5.](figs/dijkstra_ex_4.png)
+
+# Algorithme de Dijkstra (corrigé) 
+
+![Le corrigé partie 6.](figs/dijkstra_ex_5.png)
+
+# Limitation de l'algorithme de Dijkstra
+
+## Que se passe-t-il pour?
+
+![Exemple.](figs/exemple_neg.png){width=50%}
+
+## Quel est le problème?
+
+. . .
+
+* L'algorithme n'essaiera jamais le chemin `s->x->y->v` et prendra direct `s->v`.
+* Ce problème n'apparaît que s'il y a des poids négatifs.
+
-- 
GitLab