Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
coursAlgo
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
yassin.elhakoun
coursAlgo
Commits
b23c767c
Verified
Commit
b23c767c
authored
10 months ago
by
orestis.malaspin
Browse files
Options
Downloads
Patches
Plain Diff
added 2024
parent
6e4b959e
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
slides/cours_26.md
+0
-532
0 additions, 532 deletions
slides/cours_26.md
slides/cours_27.md
+777
-0
777 additions, 0 deletions
slides/cours_27.md
with
777 additions
and
532 deletions
slides/cours_26.md
+
0
−
532
View file @
b23c767c
...
@@ -1085,535 +1085,3 @@ $$
...
@@ -1085,535 +1085,3 @@ $$
*
Bien indiquer l'état de $D$ et $P$ à chaque étape!
*
Bien indiquer l'état de $D$ et $P$ à chaque étape!
*
Ne pas oublier de faire la matrice d'adjacence évidemment...
*
Ne pas oublier de faire la matrice d'adjacence évidemment...
# La suite
*
Sans transition.... la suite!
# Trouver un réseau électrique pour

# Solution: pas optimale

*
La longueur totale des câbles est super longue!
# Solution: optimale

# Formalisation: Les arbres couvrants
## Application: minimisation des coûts
*
Équipement d'un lotissement avec des lignes électriques/téléphoniques, des canalisations, ...
. . .
*
Pour réduire les coûts, on cherche à minimiser la longueur totale des câbles/tuyaux.
. . .
*
Les lignes/tuyaux forment un
*arbre couvrant*
.
. . .
*
La meilleure option est un
*arbre couvrant minimal*
.
# Formalisation: Les arbres couvrants
*
Qu'est-ce qu'un arbre couvrant? Des idées? De quel objet on part? Où va-t-on?
. . .
*
Un arbre couvrant d'un graphe non-orienté et connexe est:
*
un arbre inclus dans le graphe qui connecte tous les sommets du graphe.
. . .

# Arbres couvrants
*
Quels algorithmes que nous avons déjà vus permettent de construire des arbres couvrants?
. . .
*
Les parcours en largeur et en profondeur!
. . .

# Arbres couvrants minimaux
*
Un
*arbre couvrant minimal*
est un sous-graphe d'un graphe non-orienté pondéré $G(V,E)$, tel quel:
*
C'est un arbre (graphe acyclique);
*
Il couvre tous les sommets de $G$ et contient $|V|-1$ arêtes;
*
Le coût total associé aux arêtes de l'arbre est minimum parmi tous les arbres couvrants possibles.
. . .
*
Est-il unique?
. . .
*
Pas forcément.
# Arbres couvrants minimaux
*
Comment générer un arbre couvrant minimal?

# Algorithme de Prim
::: columns
:::: column
## Un exemple

::::
:::: column
## On part de `e` (au hasard)

::::
:::
# Algorithme de Prim
::: columns
:::: column
## On choisit comment?

. . .
*
L'arête la plus courte sortant d'un sommet déjà visité, et entrant dans un sommet non-visité.
::::
:::: column
. . .
## L'arête `e->d`

::::
:::
# Algorithme de Prim
::: columns
:::: column
## On choisit comment?

. . .
*
L'arête la plus courte sortant d'un sommet déjà visité, et entrant dans un sommet non-visité.
::::
:::: column
. . .
## L'arête `d->a`

::::
:::
# Algorithme de Prim
::: columns
:::: column
## On choisit comment?

. . .
*
L'arête la plus courte sortant d'un sommet déjà visité, et entrant dans un sommet non-visité.
::::
:::: column
. . .
## L'arête `d->c`

::::
:::
# Algorithme de Prim
::: columns
:::: column
## On choisit comment?

. . .
*
L'arête la plus courte sortant d'un sommet déjà visité, et entrant dans un sommet non-visité.
::::
:::: column
. . .
## L'arête `e->b`

*
Game over!
::::
:::
# Algorithme de Prim
## Structures de données
*
Dans quoi allons nous stocker les sommets?
. . .
*
File de priorité min.
*
Autre chose?
. . .
*
Tableau des distances (comme pour Dijkstra).
*
Autre chose?
. . .
*
Tableau des parents (presque comme pour Dijkstra).
*
Autre chose?
. . .
*
Non.
# Algorithme de Prim
## Initialisation: Pseudo-code (2min)
. . .
```
C
file_priorité, distance, parent initialisation(graphe)
r = aléatoire(graphe)
distance[r] = 0
parent[r] = indéfini
fp = file_p_vide()
pour v dans sommets(graphe)
si v != r
distance[v] = infini
parent[v] = indéfini
fp = enfiler(fp, v, distance[v])
retourne fp, distance, parent
```
# Algorithme de Prim
## Algorithme: Pseudo-code (5min)
. . .
```
C
sommets, parent prim(file_priorité, distance, parent)
sommets = vide
tant que !est_vide(file_priorité)
u, fp = défiler(file_priorité)
sommets = insérer(sommets, u)
pour v dans voisinage de u et pas dans sommets
// ou dans file_priorité
si w(u, v) < distance[v]
parent[w] = u
distance[w] = w(u, v)
fp = changer_priorité(fp, w, w(u, v))
retourne sommets, parent
```
# Exemple d'algorithme de Prim
::: columns
:::: {.column width="40%"}
## Un exemple

::::
:::: column
```
FP | e | d | b | c | a |
----------------------------------
D | 0 | inf | inf | inf | inf |
| e | d | b | c | a |
----------------------------------
P | - | - | - | - | - |
```
## Devient?
. . .
```
FP | d | b | c | a |
----------------------------
D | 4 | 5 | 5 | inf |
| e | d | b | c | a |
----------------------------------
P | - | e | e | e | - |
```
::::
:::
# Exemple d'algorithme de Prim
::: columns
:::: {.column width="40%"}
## Un exemple

::::
:::: column
```
FP | d | b | c | a |
----------------------------
D | 4 | 5 | 5 | inf |
| e | d | b | c | a |
----------------------------------
P | - | e | e | e | - |
```
## Devient?
. . .
```
FP | a | c | b |
----------------------
D | 2 | 4 | 5 |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
::::
:::
# Exemple d'algorithme de Prim
::: columns
:::: {.column width="40%"}
## Un exemple

::::
:::: column
```
FP | a | c | b |
----------------------
D | 2 | 4 | 5 |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
## Devient?
. . .
```
FP | c | b |
----------------
D | 4 | 5 |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
::::
:::
# Exemple d'algorithme de Prim
::: columns
:::: {.column width="40%"}
## Un exemple

::::
:::: column
```
FP | c | b |
----------------
D | 4 | 5 |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
## Devient?
. . .
```
FP | b |
----------
D | 5 |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
::::
:::
# Exemple d'algorithme de Prim
::: columns
:::: {.column width="40%"}
## Un exemple

::::
:::: column
```
FP | b |
----------
D | 5 |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
## Devient?
. . .
```
FP |
----
D |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
::::
:::
# Exercice: algorithme de Prim
## Appliquer l'algorithme de Prim à (15min):

# Exercice: algorithme de Prim
## Solution

# Complexité de l'algorithme de Prim
\f
ootnotesize
```
C
file_priorité, distance, parent initialisation(graphe)
// choix r et initialisation
pour v dans sommets(graphe)
O(|V|) // initialisation distance et parent
fp = enfiler(fp, v, distance[v])
retourne fp, distance, parent
sommets, parent prim(file_priorité, distance, parent)
sommets = vide
tant que !est_vide(file_priorité)
O(|V|) u, fp = défiler(file_priorité)
sommets = insérer(sommets, u)
pour v dans voisinage de u et pas dans sommets
O(|E|) si w(u, v) < distance[v]
// màj dista + parent
O(|V|) fp = changer_priorité(fp, w, w(u, v))
retourne sommets, parent
```
*
$O(|V|)+O(|E|)+O(|V|^2)=O(|E|+|V|^2)$
*
Remarque: $O(|E|)$ n'est pas mutliplié par $O(|V|)$, car les arêtes parcourues qu'une fois en
**tout**
.
This diff is collapsed.
Click to expand it.
slides/cours_27.md
0 → 100644
+
777
−
0
View file @
b23c767c
---
title
:
"
Flots
dans
les
graphes"
date
:
"
2024-06-04"
---
# Rappel (1/2)
## Algorithme de Dijkstra: à quoi sert-il?
. . .
A trouver le plus court chemin entre deux sommets d'un graphe!
## Algorithme de Dijkstra: algorithme?
. . .
```
C
distance[source] = 0
distance[reste] = inf;
pour sommet dans liste_sommets:
fp = enfiler(fp, sommet, w(source, sommet)) // file min
tant !est_vide(fp):
sommet_courant, fp = défiler(fp);
pour sommet_voisin dans voisinage(sommet_courant):
n_dist = distance[sommet_courant] + w(sommet_courant, sommet_voisin)
si distance[sommet_voisin] > n_dist:
distance[sommet_voisin] = n_dist
precedence[sommet_voisin] = sommet_courant
fp = mettre_a_jour(fp, sommet_voisin, n_dist)
```
# Rappel (2/2)
## Algorithme de Floyd: à quoi sert-il?
. . .
A trouver le plus court chemin entre toutes les paires de sommets d'un graphe!
## Algorithme de Floyd: algorithme?
. . .
```
C
matrice, matrice floyd_warshall(distance, n, w)
pour k de 1 à n
pour i de 1 à n
pour j de 1 à n
n_distance = distance[i][k] + distance[k][j]
si n_distance < distance[i][j]
distance[i][j] = n_distance
précédence[i][j] = précédence[k][j]
retourne distance, précédence
```
# La suite
\H
uge Sans transition.... la suite!
# Trouver un réseau électrique pour

# Solution: pas optimale

*
La longueur totale des câbles est super longue!
# Solution: optimale

# Formalisation: Les arbres couvrants
## Application: minimisation des coûts
*
Équipement d'un lotissement avec des lignes électriques/téléphoniques, des canalisations, ...
. . .
*
Pour réduire les coûts, on cherche à minimiser la longueur totale des câbles/tuyaux.
. . .
*
Les lignes/tuyaux forment un
*arbre couvrant*
.
. . .
*
La meilleure option est un
*arbre couvrant minimal*
.
# Formalisation: Les arbres couvrants
*
Qu'est-ce qu'un arbre couvrant? Des idées? De quel objet on part? Où va-t-on?
. . .
*
Un arbre couvrant d'un graphe non-orienté et connexe est:
*
un arbre inclus dans le graphe qui connecte tous les sommets du graphe.
. . .

# Arbres couvrants
*
Quels algorithmes que nous avons déjà vus permettent de construire des arbres couvrants?
. . .
*
Les parcours en largeur et en profondeur!
. . .

# Arbres couvrants minimaux
*
Un
*arbre couvrant minimal*
est un sous-graphe d'un graphe non-orienté pondéré $G(V,E)$, tel quel:
*
C'est un arbre (graphe acyclique);
*
Il couvre tous les sommets de $G$ et contient $|V|-1$ arêtes;
*
Le coût total associé aux arêtes de l'arbre est minimum parmi tous les arbres couvrants possibles.
. . .
*
Est-il unique?
. . .
*
Pas forcément.
# Arbres couvrants minimaux
*
Comment générer un arbre couvrant minimal?

# Algorithme de Prim
::: columns
:::: column
## Un exemple

::::
:::: column
## On part de `e` (au hasard)

::::
:::
# Algorithme de Prim
::: columns
:::: column
## On choisit comment?

. . .
*
L'arête la plus courte sortant d'un sommet déjà visité, et entrant dans un sommet non-visité.
::::
:::: column
. . .
## L'arête `e->d`

::::
:::
# Algorithme de Prim
::: columns
:::: column
## On choisit comment?

. . .
*
L'arête la plus courte sortant d'un sommet déjà visité, et entrant dans un sommet non-visité.
::::
:::: column
. . .
## L'arête `d->a`

::::
:::
# Algorithme de Prim
::: columns
:::: column
## On choisit comment?

. . .
*
L'arête la plus courte sortant d'un sommet déjà visité, et entrant dans un sommet non-visité.
::::
:::: column
. . .
## L'arête `d->c`

::::
:::
# Algorithme de Prim
::: columns
:::: column
## On choisit comment?

. . .
*
L'arête la plus courte sortant d'un sommet déjà visité, et entrant dans un sommet non-visité.
::::
:::: column
. . .
## L'arête `e->b`

*
Game over!
::::
:::
# Algorithme de Prim
## Structures de données
*
Dans quoi allons nous stocker les sommets?
. . .
*
File de priorité min.
*
Autre chose?
. . .
*
Tableau des distances (comme pour Dijkstra).
*
Autre chose?
. . .
*
Tableau des parents (presque comme pour Dijkstra).
*
Autre chose?
. . .
*
Non.
# Algorithme de Prim
## Initialisation: Pseudo-code (2min)
. . .
```
C
file_priorité, distance, parent initialisation(graphe)
r = aléatoire(graphe)
distance[r] = 0
parent[r] = indéfini
fp = file_p_vide()
pour v dans sommets(graphe)
si v != r
distance[v] = infini
parent[v] = indéfini
fp = enfiler(fp, v, distance[v])
retourne fp, distance, parent
```
# Algorithme de Prim
## Algorithme: Pseudo-code (5min)
. . .
```
C
sommets, parent prim(file_priorité, distance, parent)
sommets = vide
tant que !est_vide(file_priorité)
u, fp = défiler(file_priorité)
sommets = insérer(sommets, u)
pour v dans voisinage de u et pas dans sommets
// ou dans file_priorité
si w(u, v) < distance[v]
parent[w] = u
distance[w] = w(u, v)
fp = changer_priorité(fp, w, w(u, v))
retourne sommets, parent
```
# Exemple d'algorithme de Prim
::: columns
:::: {.column width="40%"}
## Un exemple

::::
:::: column
```
FP | e | d | b | c | a |
----------------------------------
D | 0 | inf | inf | inf | inf |
| e | d | b | c | a |
----------------------------------
P | - | - | - | - | - |
```
## Devient?
. . .
```
FP | d | b | c | a |
----------------------------
D | 4 | 5 | 5 | inf |
| e | d | b | c | a |
----------------------------------
P | - | e | e | e | - |
```
::::
:::
# Exemple d'algorithme de Prim
::: columns
:::: {.column width="40%"}
## Un exemple

::::
:::: column
```
FP | d | b | c | a |
----------------------------
D | 4 | 5 | 5 | inf |
| e | d | b | c | a |
----------------------------------
P | - | e | e | e | - |
```
## Devient?
. . .
```
FP | a | c | b |
----------------------
D | 2 | 4 | 5 |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
::::
:::
# Exemple d'algorithme de Prim
::: columns
:::: {.column width="40%"}
## Un exemple

::::
:::: column
```
FP | a | c | b |
----------------------
D | 2 | 4 | 5 |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
## Devient?
. . .
```
FP | c | b |
----------------
D | 4 | 5 |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
::::
:::
# Exemple d'algorithme de Prim
::: columns
:::: {.column width="40%"}
## Un exemple

::::
:::: column
```
FP | c | b |
----------------
D | 4 | 5 |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
## Devient?
. . .
```
FP | b |
----------
D | 5 |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
::::
:::
# Exemple d'algorithme de Prim
::: columns
:::: {.column width="40%"}
## Un exemple

::::
:::: column
```
FP | b |
----------
D | 5 |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
## Devient?
. . .
```
FP |
----
D |
| e | d | b | c | a |
----------------------------------
P | - | e | e | d | d |
```
::::
:::
# Exercice: algorithme de Prim
## Appliquer l'algorithme de Prim à (15min):

# Exercice: algorithme de Prim
## Solution

# Complexité de l'algorithme de Prim
\f
ootnotesize
```
C
file_priorité, distance, parent initialisation(graphe)
// choix r et initialisation
pour v dans sommets(graphe)
O(|V|) // initialisation distance et parent
fp = enfiler(fp, v, distance[v])
retourne fp, distance, parent
sommets, parent prim(file_priorité, distance, parent)
sommets = vide
tant que !est_vide(file_priorité)
O(|V|) u, fp = défiler(file_priorité)
sommets = insérer(sommets, u)
pour v dans voisinage de u et pas dans sommets
O(|E|) si w(u, v) < distance[v]
// màj dista + parent
O(|V|) fp = changer_priorité(fp, w, w(u, v))
retourne sommets, parent
```
*
$O(|V|)+O(|E|)+O(|V|^2)=O(|E|+|V|^2)$
*
Remarque: $O(|E|)$ n'est pas mutliplié par $O(|V|)$, car les arêtes parcourues qu'une fois en
**tout**
.
# Algorithme de Kruskal
*
On ajoute les arêtes de poids minimal:
*
si cela ne crée pas de cycle;
*
on s'arrête quand on a couvert tout le graphe.
. . .
*
Comment on fait ça?
. . .
*
Faisons un exemple pour voir.
# Algorithme de Kruskal: exemple
::: columns
:::: column
## Un exemple

::::
:::: column
## On part de `(a, d)` (poids le plus faible)

::::
:::
# Algorithme de Kruskal: exemple
::: columns
:::: column
## On continue avec `(c, d)`

::::
:::: column
## Résultat

::::
:::
# Algorithme de Kruskal: exemple
::: columns
:::: column
## On continue avec `(d, e)`

::::
:::: column
## Résultat

::::
:::
# Algorithme de Kruskal: exemple
::: columns
:::: column
## On continue avec `(b, e)`

::::
:::: column
## Résultat

::::
:::
# Algorithme de Kruskal: exemple
::: columns
:::: column
## Mais pourquoi pas `(c, e)`?

::::
:::: column
## Résultat: un cycle

::::
:::
*
Comment faire pour empêcher l'ajout de
`(c, e)`
ou
`(a, c)`
?
. . .
*
Si les deux sommets sont déjà couverts nous sommes sauvés (presque)!
# Algorithme de Kruskal
## L'initialisation
*
Créer un ensemble de sommets pour chaque de sommet du graphe ($V_1$, $V_2$, ...):
*
$V_1=
\{
v_1
\}
$, $V_2=
\{
v_2
\}
$, ...
*
S'il y a $n$ sommets, il y a $n$ $V_i$.
*
Initialiser l'ensemble $A$ des arêtes "sûres" constituant l'arbre couvrant minimal, $A=
\e
mptyset$.
*
Initialiser l'ensemble des sommets couverts $F=
\e
mptyset$
*
Trier les arêtes par poids croissant dans l'ensemble $E$.
## Mise à jour
*
Tant qu'il reste plus d'un $V_i$:
*
Pour $(u,v)
\i
n A$ à poids minimal:
*
Retirer $(u,v)$ de $A$,
*
Si $u
\i
n V_i$ et $v
\i
n V_j$ avec $V_i
\c
ap V_j=
\e
mptyset$:
*
Ajouter $(u,v)$ à $A$;
*
Fusionner $U$ et $V$ dans $F$.
<!-- # Algorithme de Kruskal: exemple -->
<!---->
<!-- ::: columns -->
<!---->
<!-- :::: column -->
<!---->
<!--  -->
<!---->
<!-- :::: -->
<!---->
<!-- :::: column -->
<!---->
<!-- :::: -->
<!---->
<!-- ::: -->
<!---->
<!-- # Algorithme de Kruskal: solution -->
<!---->
<!--  -->
<!---->
<!-- # Algorithme de Kruskal: exercice -->
<!---->
<!-- ::: columns -->
<!---->
<!-- :::: column -->
<!---->
<!--  -->
<!---->
<!-- :::: -->
<!---->
<!-- :::: column -->
<!---->
<!-- :::: -->
<!---->
<!-- ::: -->
<!---->
<!-- # Algorithme de Kruskal: solution -->
<!---->
<!--  -->
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment