Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
cours
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
algorithmique
cours
Commits
832374fa
Verified
Commit
832374fa
authored
3 years ago
by
orestis.malaspin
Browse files
Options
Downloads
Patches
Plain Diff
added horizontal symmetry
parent
fbfce174
Branches
Branches containing commit
No related tags found
No related merge requests found
Pipeline
#16815
failed
3 years ago
Stage: test
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
slides/cours_19.md
+1
-291
1 addition, 291 deletions
slides/cours_19.md
slides/cours_20.md
+653
-0
653 additions, 0 deletions
slides/cours_20.md
with
654 additions
and
291 deletions
slides/cours_19.md
+
1
−
291
View file @
832374fa
...
@@ -38,7 +38,7 @@ patat:
...
@@ -38,7 +38,7 @@ patat:
25 | 60 | 35 | 10 | 5 | 20 | 65 | 45 | 70 | 40 | 50 | 55 | 30 | 15
25 | 60 | 35 | 10 | 5 | 20 | 65 | 45 | 70 | 40 | 50 | 55 | 30 | 15
```
```
## Un à un et le/la premier/ère qui poste la bonne réponse sur matrix
à
un point
## Un à un et le/la premier/ère qui poste la bonne réponse sur matrix
a
un point
# Suppression dans un arbre AVL
# Suppression dans un arbre AVL
...
@@ -385,293 +385,3 @@ Image 64 pixels, arbre 25 neouds.
...
@@ -385,293 +385,3 @@ Image 64 pixels, arbre 25 neouds.
:::
:::
# Structure de données
::: columns
:::: {.column width=50%}
## Pseudocode?
. . .
```
python
struct
node
info
node
sup_gauche
,
sup_droit
,
inf_gauche
,
inf_droit
```

::::
:::: {.column width=50%}
## En C?
. . .
```
C
struct _node {
int info;
struct _node *sup_left;
struct _node *sup_right;
struct _node *inf_left;
struct _node *inf_right;
};
```
*
Pourquoi le
`*`
est important?
. . .
*
Type récursif => taille inconnue à la compilation.
::::
:::
# Une fonctionnalité simple
\f
ootnotesize
## La fonction `est_feuille(noeud)`
*
Problème avec cette implémentation?
```
pyrhon
bool est_feuille(noeud)
retourne
est_vide(sup_gauche(noeud)) &&
est_vide(sup_droit(noeud)) &&
est_vide(inf_gauche(noeud)) &&
est_vide(inf_droit(noeud))
```
. . .
*
Inutile d'avoir 4 conditions (soit 4 enfants soit aucun!)
*
Facile d'en oublier un!
*
Comment changer la structure pour que ça soit moins terrible?
. . .
```
python
struct
node
info
node
enfant
[
4
]
```
# Structure de données
## En C?
. . .
```
C
typedef struct _node {
int info;
struct _node *child[4];
} node;
```
## Fonction `is_leaf(node *tree)`?
. . .
```
C
bool is_leaf(node *tree) {
return (NULL == tree->child[0]); // only first matters
}
```
# Problème à résoudre
*
Construire un arbre quaternaire à partir d'une image:
*
Créer l'arbre (allouer la mémoire pour tous les nœuds),
*
Le remplir avec les valeurs des pixels.
*
Compression de l'image:
*
Si les pixels sont les mêmes dans le quadrant on supprime le sous-arbre (sans perte)
*
Si les pixels dévident pas trop on supprime le quadrant (avec perte)
# Fonctions utiles (1/N)
## Comment créer un arbre de profondeur `prof` (3min)?
. . .
```
python
arbre
creer_arbre
(
prof
)
n
=
nouveau_noeud
()
# alloue la mémoire
si
prof
>
0
pour
i
=
0
à
3
n
.
enfant
[
i
]
=
creer_arbre
(
prof
-
1
)
retourne
n
```
## En `C` (3 min, matrix)?
. . .
```
C
node *qt_create(int depth) {
node *n = calloc(1, sizeof(*n));
if (depth > 0) {
for (int i = 0; i < 4; ++i) {
n->child[i] = qt_create(depth-1);
}
}
return n;
}
```
# Fonctions utiles (2/N)
## Comment remplir un arbre depuis une matrice?
```
SG=0 | SD=1
21 | 12 | 4 | 4
9 | 7 | 4 | 4
-----------------
1 | 1 | 0 | 31
1 | 1 | 3 | 27
IG=2 | ID=3
```
## Quel arbre cela représente?
. . .

# Fonctions utiles (3/N)
*
On veut transformer une ligne/colonne en feuille.
*
Comment?
::: columns
:::: {.column width=40%}
## Soit `ligne=2`, `colonne=3`
```
SG=0 | SD=1
21 | 12 | 4 | 4
9 | 7 | 4 | 4
-----------------
1 | 1 | 0 | 31
1 | 1 | 3 | 27
IG=2 | ID=3
```
::::
:::: {.column width=70%}
## Trouver un algorithme

*
Quelle feuille?
*
Plus important: quel chemin?
. . .
*
`co -> G/D`
,
`li -> S/I`
,
*
`2 * (li / 2) + co / 2 -> 2 * 1 + 1 = 3`
*
`2 * ((li % 2) / 1) + (co % 2) / 1 -> 2 * 0 + 1 = 1`
*
Comment généraliser?
::::
:::
# Fonctions utiles (4/N)
::: columns
:::: {.column width=40%}
## Soit `ligne=2`, `colonne=3`
```
SG=0 | SD=1
21 | 12 | 4 | 4
9 | 7 | 4 | 4
-----------------
1 | 1 | 0 | 31
1 | 1 | 3 | 27
IG=2 | ID=3
```
::::
:::: {.column width=70%}
## Trouver un algorithme

*
Comment généraliser?
. . .
```
C
noeud position(li, co, arbre)
d = profondeur(arbre);
tant_que (d > 1)
index = 2 * ((li % 2^d) / 2^(d-1)) +
(col % 2^d) / 2^(d-1)
arbre = arbre.enfant[index]
d -= 1
retourn arbre
```
::::
:::
# Remplir l'arbre
## A partir d'une matrice (pseudo-code, 5min, matrix)?
. . .
```
C
arbre matrice_à_arbre(matrice, arbre)
arbre = creer_arbre(profondeur)
pour li de 0 à nb_lignes(matrice)
pour co de 0 à nb_colonnes(matrice)
noeud = position(li, co, arbre)
noeud.info = matrice[co][li]
retourne arbre
```
. . .
## A partir d'une matrice (C, 5min, matrix)?
```
C
node *matrice_to_qt(int nb_li, int nb_co, int matrix[nb_li][nb_co], int depth)
node *qt = qt_create(depth);
for (int li = 0; li < nd_li; ++li) {
for (int co = 0; co < nd_co; ++co) {
node *current = position(li, co, qt);
current->info = matrix[li][co];
}
}
return qt;
```
# Interface
## Quelles sont les fonctions à implémenter?
# Implémentation
This diff is collapsed.
Click to expand it.
slides/cours_20.md
0 → 100644
+
653
−
0
View file @
832374fa
---
title
:
"
Arbres
quaternaires
et
compression"
date
:
"
2022-03-30"
patat
:
eval
:
tai
:
command
:
fish
fragment
:
false
replace
:
true
ccc
:
command
:
fish
fragment
:
false
replace
:
true
images
:
backend
:
auto
---
# Le cours précédent
## Questions (réponse sur matrix)
. . .
*
Combien de points du suture?

# Le cours précédent
## Questions
*
Aucun c'est de la colle

# Le cours précédent
## Questions
*
Qu'est-ce qu'un arbre quaternaire?
. . .
*
Un arbre où chaque noeud a soit
**4 enfants**
soit
**aucun**
.
*
A quoi peut servir un arbre quaternaire?
. . .
*
Compression
# Les arbres quaternaires
## Définition
Arbre dont chaque nœud a 4 enfants ou aucun.

# Les arbres quaternaires
## Cas d'utilisation
Typiquement utilisés pour représenter des données bidimensionnelles.
Son équivalent tri-dimensionnel est l'octree (chaque nœud a 8 enfants ou aucun).
## Cas d'utilisation: images
*
Stockage: compression.
*
Transformations: symétries, rotations, etc.
## Cas d'utilisation: simulation
*
Indexation spatiale.
*
Détection de collisions.
*
Simulation de galaxies, Barnes-Hut.
# Exemple de compression
::: columns
:::: {.column width=30%}
## Comment représenter l'image

::::
:::: {.column width=70%}
## Sous la forme d'un arbre quaternaire?
. . .

**Économie?**
. . .
Image 64 pixels, arbre 25 neouds.
::::
:::
# Structure de données
::: columns
:::: {.column width=50%}
## Pseudocode?
. . .
```
python
struct
node
info
node
sup_gauche
,
sup_droit
,
inf_gauche
,
inf_droit
```

::::
:::: {.column width=50%}
## En C?
. . .
```
C
struct _node {
int info;
struct _node *sup_left;
struct _node *sup_right;
struct _node *inf_left;
struct _node *inf_right;
};
```
*
Pourquoi le
`*`
est important?
. . .
*
Type récursif => taille inconnue à la compilation.
::::
:::
# Une fonctionnalité simple
\f
ootnotesize
## La fonction `est_feuille(noeud)`
*
Problème avec cette implémentation?
```
pyrhon
bool est_feuille(noeud)
retourne
est_vide(sup_gauche(noeud)) &&
est_vide(sup_droit(noeud)) &&
est_vide(inf_gauche(noeud)) &&
est_vide(inf_droit(noeud))
```
. . .
*
Inutile d'avoir 4 conditions (soit 4 enfants soit aucun!)
*
Facile d'en oublier un!
*
Comment changer la structure pour que ça soit moins terrible?
. . .
```
python
struct
node
info
node
enfant
[
4
]
```
# Structure de données
## En C?
. . .
```
C
typedef struct _node {
int info;
struct _node *child[4];
} node;
```
## Fonction `is_leaf(node *tree)`?
. . .
```
C
bool is_leaf(node *tree) {
return (NULL == tree->child[0]); // only first matters
}
```
# Problème à résoudre
*
Construire un arbre quaternaire à partir d'une image:
*
Créer l'arbre (allouer la mémoire pour tous les nœuds),
*
Le remplir avec les valeurs des pixels.
*
Compression de l'image:
*
Si les pixels sont les mêmes dans le quadrant on supprime le sous-arbre (sans perte)
*
Si les pixels dévident pas trop on supprime le quadrant (avec perte)
# Fonctions utiles (1/N)
## Comment créer un arbre de profondeur `prof` (3min)?
. . .
```
python
arbre
creer_arbre
(
prof
)
n
=
nouveau_noeud
()
# alloue la mémoire
si
prof
>
0
pour
i
=
0
à
3
n
.
enfant
[
i
]
=
creer_arbre
(
prof
-
1
)
retourne
n
```
## En `C` (3 min, matrix)?
. . .
```
C
node *qt_create(int depth) {
node *n = calloc(1, sizeof(*n));
if (depth > 0) {
for (int i = 0; i < 4; ++i) {
n->child[i] = qt_create(depth-1);
}
}
return n;
}
```
# Le nombre de noeuds?
## Comment implémenter la fonction (pseudo-code, 5min, matrix)?
. . .
```
C
entier nombre_noeuds(arbre)
si est_feuille(arbre)
retourne 1
sinon
somme = 1
pour i de 0 à 3
somme += nombre_noeuds(arbre.enfant[i])
retourne somme
```
# Le nombre de noeuds?
## Comment implémenter la fonction en C (3min, matrix)?
. . .
```
C
inf size(node *qt) {
if (is_leaf(qt)) {
return 1;
} else {
int sum = 1;
for (int i = 0; i < 4; ++i) {
sum += size(qt->child[i]);
}
return sum;
}
}
```
# La profondeur en C?
## Implémentation (5min, matrix)
. . .
```
C
int max(int x, int y) {
return (x >= y ? x : y);
}
int max_depth(int depths[4]) {
int m = depths[0];
for (int i = 1; i < 4; ++i) {
m = max(m, depths[i]);
}
return m;
}
int depth(node *qt) {
int depths[] = {0, 0, 0, 0};
if (is_leaf(qt)) {
return 0;
} else {
depths[i] = 1 + depth(qt->child[i]);
return max_depth(depths);
}
}
```
# Fonctions utiles (2/N)
## Comment remplir un arbre depuis une matrice?
```
SG=0 | SD=1
21 | 12 | 4 | 4
9 | 7 | 4 | 4
-----------------
1 | 1 | 0 | 31
1 | 1 | 3 | 27
IG=2 | ID=3
```
## Quel arbre cela représente?
. . .

# Fonctions utiles (3/N)
*
On veut transformer une ligne/colonne en feuille.
*
Comment?
::: columns
:::: {.column width=40%}
## Soit `ligne=2`, `colonne=3`
```
SG=0 | SD=1
21 | 12 | 4 | 4
9 | 7 | 4 | 4
-----------------
1 | 1 | 0 | 31
1 | 1 | 3 | 27
IG=2 | ID=3
```
::::
:::: {.column width=70%}
## Trouver un algorithme

*
Quelle feuille?
*
Plus important: quel chemin?
. . .
*
`co -> G/D`
,
`li -> S/I`
,
*
`2 * (li / 2) + co / 2 -> 2 * 1 + 1 = 3`
*
`2 * ((li % 2) / 1) + (co % 2) / 1 -> 2 * 0 + 1 = 1`
*
Comment généraliser?
::::
:::
# Fonctions utiles (4/N)
::: columns
:::: {.column width=40%}
## Soit `ligne=2`, `colonne=3`
```
SG=0 | SD=1
21 | 12 | 4 | 4
9 | 7 | 4 | 4
-----------------
1 | 1 | 0 | 31
1 | 1 | 3 | 27
IG=2 | ID=3
```
::::
:::: {.column width=70%}
## Trouver un algorithme (prendre plusieurs exemples, 15min, matrix)

*
Comment généraliser?
. . .
```
C
noeud position(li, co, arbre)
d = profondeur(arbre);
tant_que (d > 1)
index = 2 * ((li % 2^d) / 2^(d-1)) +
(col % 2^d) / 2^(d-1)
arbre = arbre.enfant[index]
d -= 1
retourn arbre
```
. . .
*
Écrire le code
`C`
correspondant (5min, matrix)
::::
:::
# Remplir l'arbre
## A partir d'une matrice (pseudo-code, 5min, matrix)?
. . .
```
C
arbre matrice_à_arbre(matrice)
arbre = creer_arbre(profondeur)
pour li de 0 à nb_lignes(matrice)
pour co de 0 à nb_colonnes(matrice)
noeud = position(li, co, arbre)
noeud.info = matrice[co][li]
retourne arbre
```
. . .
## A partir d'une matrice (C, 5min, matrix)?
```
C
node *matrix_to_qt(int nb_li, int nb_co, int matrix[nb_li][nb_co], int depth)
node *qt = qt_create(depth);
for (int li = 0; li < nd_li; ++li) {
for (int co = 0; co < nd_co; ++co) {
node *current = position(li, co, qt);
current->info = matrix[li][co];
}
}
return qt;
```
# La profondeur?
## Comment implémenter la fonction profondeur?
*
Quelle signature?
. . .
```
C
entier profondeur(arbre)
```
*
Quel pseudo-code (3min, matrix)?
. . .
```
C
entier profondeur(arbre)
profondeurs = [0, 0, 0, 0];
si est_feuille(arbre)
retourne 0
sinon
pour i 0 à 3
profondeurs[i] = 1 + profondeur(arbre.enfant[i])
retourn max(p)
```
# La profondeur en C?
## Implémentation (5min, matrix)
. . .
```
C
int max(int x, int y) {
return (x >= y ? x : y);
}
int max_depth(int depths[4]) {
int m = depths[0];
for (int i = 1; i < 4; ++i) {
m = max(m, depths[i]);
}
return m;
}
int depth(node *qt) {
int depths[] = {0, 0, 0, 0};
if (is_leaf(qt)) {
return 0;
} else {
depths[i] = 1 + depth(qt->child[i]);
return max_depth(depths);
}
}
```
# Remplir la matrice
## A partir de l'arbre (pseudo-code, 3min, matrix)?
. . .
```
C
matrice arbre_à_matrice(arbre)
pour li de 0 à nb_lignes(matrice)
pour co de 0 à nb_colonnes(matrice)
noeud = position(li, co, arbre)
matrice[co][li] = noeud.info
retourne arbre
```
. . .
## A partir de l'arbre (C, 3min, matrix)?
```
C
void qt_to_matrix(node *qt, int nb_li, int nb_co, int matrix[nb_li][nb_co])
for (int li = 0; li < nd_li; ++li) {
for (int co = 0; co < nd_co; ++co) {
node *current = position(li, co, qt);
matrix[li][co] = current->info;
}
}
```
# Transformations avec un arbre quaternaire
## A faire
*
Symétrie axiale (horizontale/verticale).
*
Rotation quart de cercle (gauche/droite).
*
Compression.
# La symétrie verticale
## Que donne la symétrie verticale de
```
SG=0 | SD=1
21 | 12 | 4 | 4
9 | 7 | 4 | 4
-----------------
1 | 1 | 0 | 31
1 | 1 | 3 | 27
IG=2 | ID=3
```
. . .
```
SG=0 | SD=1
4 | 4 | 12 | 21
4 | 4 | 7 | 9
------------------
31 | 0 | 1 | 1
27 | 3 | 1 | 1
IG=2 | ID=3
```
# La symétrie d'axe vertical
## Comment faire sur une matrice (3min, matrix)?
. . .
```
C
matrice symétrie(matrice)
pour i de 0 à nb_colonnes(matrice) / 2
pour j de 0 à nb_lignes(matrice)
échanger(matrice[i][j], matrice[nb_colonnes(matrice)-1-i][j])
retourne matrice
```
# La symétrie d'axe vertical
## Comment faire sur un arbre?
*
Faire un dessin de l'arbre avant/après (5min, matrix)
```
SG=0 | SD=1 SG=0 | SD=1
21 | 12 | 4 | 4 4 | 4 | 12 | 21
9 | 7 | 4 | 4 4 | 4 | 7 | 9
----------------- => ----------------
1 | 1 | 0 | 31 31 | 0 | 1 | 1
1 | 1 | 3 | 27 27 | 3 | 1 | 1
IG=2 | ID=3 IG=2 | ID=3
```
*
Écrire le pseudo-code (3min, matrix)
. . .
```
C
arbre symétrie(arbre)
si !est_feuille(arbre)
échanger(arbre.enfant[0], arbre.enfant[1])
échanger(arbre.enfant[2], arbre.enfant[3])
pour i de 0 à 3
symétrie(arbre.enfant[i])
retourne arbre
```
*
Trivial de faire l'axe horizontal (exercice à la maison)
# Rotation d'un quart de cercle
## Comment faire sur un arbre?
*
Faire un dessin de l'arbre avant/après (5min, matrix)
```
SG=0 | SD=1 SG=0 | SD=1
21 | 12 | 4 | 4 4 | 4 | 31 | 27
9 | 7 | 4 | 4 4 | 4 | 0 | 3
----------------- => -----------------
1 | 1 | 0 | 31 12 | 7 | 1 | 1
1 | 1 | 3 | 27 21 | 9 | 1 | 1
IG=2 | ID=3 IG=2 | ID=3
```
*
Écrire le pseudo-code (3min, matrix)
. . .
```
C
arbre symétrie(arbre)
si !est_feuille(arbre)
échanger(arbre.enfant[0], arbre.enfant[1])
échanger(arbre.enfant[2], arbre.enfant[3])
pour i de 0 à 3
symétrie(arbre.enfant[i])
retourne arbre
```
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