Compare commits
7 Commits
4322701efb
...
main
Author | SHA1 | Date | |
---|---|---|---|
33d3959fd1 | |||
1281027e97 | |||
66345b849b | |||
0c9007deb2 | |||
bed10d85fe | |||
4eb6e0aedb | |||
091b8f7b67 |
325
FOAD-bloc5.md
325
FOAD-bloc5.md
@@ -1,325 +0,0 @@
|
||||
# Recherche du plus grand carré blanc dans une "image"
|
||||
|
||||
## Objectif et déroulement
|
||||
|
||||
On considère le problème suivant : étant donné une image monochrome $n \times n$, déterminer le plus grand carré qui ne contient aucun point noir.
|
||||
|
||||
Le but du TP est d'établir plusieurs algorithmes permettant de trouver le plus grand carré blanc dans une image.
|
||||
|
||||
Déroulement du TP :
|
||||
|
||||
- Conception d'un algorithme récursif naïf : ```RechercheCarreBlanc_naif()```
|
||||
- Programmation dynamique - Utilisation de la mémoïsation : ```RechercheCarreBlanc_memoisation()```
|
||||
- Programmation dynamique - Optimisation par "Bottom_up" : ```RechercheCarreBlanc_BU()```
|
||||
|
||||
# Conception d'un algorithme récursif naïf : ```RechercheCarreBlanc_naif()```
|
||||
|
||||
## Une image c'est quoi ?
|
||||
|
||||
Une image, c'est un tableau de tuples qui représentent les couleurs des pixels. Dans le cadre de ce TP, nous nous limiterons à des images noir et blanc :
|
||||
|
||||

|
||||
|
||||
```python
|
||||
t=[
|
||||
[1,0,0,1,0,0,1,0,0,1],
|
||||
[0,0,0,0,0,0,1,0,0,0],
|
||||
...
|
||||
[0,0,0,0,1,0,0,0,1,0]
|
||||
]
|
||||
```
|
||||
|
||||
```t[5][1]==1``` car le pixel de la ligne ```5``` et de la colonne ```1``` est noir. (Attention les numéros des lignes/colonnes commencent à 0).
|
||||
|
||||
## Etude du problème
|
||||
|
||||
L'objectif est de trouver le carré blanc le plus grand possible à partir d'un pixel donné (coin inférieur droit).
|
||||
|
||||
- ```PlusGrandCarreBlanc_Rec(lig,col)``` : Retourne la taille du carré blanc à partir du coin inférieur droit (ligne,colonne).
|
||||
|
||||
Par ex :
|
||||
|
||||
- ```PlusGrandCarreBlanc_Rec(1,2) == 2```
|
||||
- ```PlusGrandCarreBlanc_Rec(6,4) == 2```
|
||||
|
||||

|
||||
|
||||
>
|
||||
> 01. Pour l'image suivante, donner le résultat de :
|
||||
>
|
||||
> - ```PlusGrandCarreBlanc_Rec(2,1) == ...```
|
||||
> - ```PlusGrandCarreBlanc_Rec(1,2) == ...```
|
||||
> - ```PlusGrandCarreBlanc_Rec(1,1) == ...```
|
||||
>
|
||||
>
|
||||
>
|
||||
> 02. Quelle relation existe-il entre ```PlusGrandCarreBlanc_Rec(2,2)``` et les 3 valeurs précédentes ?
|
||||
>
|
||||
> 03. Généraliser ce résultat pour un pixel quelconque :
|
||||
>
|
||||
> ```PlusGrandCarreBlanc_Rec(lig,col) = min( ......... , ......... , ......... ) + .........```
|
||||
>
|
||||
> 4. Proposer un algorithme récursif pour ```PlusGrandCarreBlanc_Rec(i,j)``` :
|
||||
>
|
||||
> ```python
|
||||
> def PlusGrandCarreBlanc_Rec(t,lig,col): # t est le tableau représentant l'image noir et blanc
|
||||
>
|
||||
> if t(lig, col) == 1: # Si le pixel est noir
|
||||
> return ... # On retourne ...
|
||||
>
|
||||
> # Sinon :
|
||||
> elif ...... : # Si le pixel est sur la 1ère ligne ou 1ère colonne
|
||||
> return ... # On retourne ...
|
||||
>
|
||||
> else : # Sinon :
|
||||
> return ... # On retourne 1 + min(PlusGrandCarre des pixels adjacents)
|
||||
> # Adjacents => à gauche, en haut, en diagonale haut-gauche
|
||||
> ```
|
||||
>
|
||||
> 05. Tester votre algorithme sur le tableau suivant :
|
||||
>
|
||||
> ```python
|
||||
> t=[ [0,0,0,1,0],
|
||||
> [0,0,0,0,1],
|
||||
> [1,0,0,0,0],
|
||||
> [0,0,1,1,0],
|
||||
> [0,1,0,0,1] ]
|
||||
> ```
|
||||
>
|
||||
> ```python
|
||||
> >>> print(PlusGrandCarreBlanc_Rec(t,2,2))
|
||||
> 2
|
||||
> ```
|
||||
>
|
||||
> **Remarque :** D'autres tableaux sont présent dans le fichier ```TP.py```
|
||||
>
|
||||
> **Remarque :** Lors de l'évaluation du minimum par ```min()```, l'interpréteur DOIT calculer les 3 valeurs à comparer. Or, nous pouvons lui éviter dans certains cas ce travail (et économiser un nombre d'appels récursifs). En effet, si la première valeur calculée est nulle alors le ```min(... , ... , ...)``` retournera FORCEMENT 0 et la fonction retournera 1. De même pour la seconde et la troisième.
|
||||
>
|
||||
> 6. Modifier ```PlusGrandCarreBlanc_Rec(lig,col)``` en tenant compte de la remarque précédente.
|
||||
>
|
||||
> ```python
|
||||
> def PlusGrandCarreBlanc_Rec(t,lig,col):
|
||||
> ...
|
||||
> else :
|
||||
> g = ... # Valeur du pixel de gauche
|
||||
> if g==0:
|
||||
> return 1
|
||||
> h = ... # Valeur du pixel du haut
|
||||
> if h==0:
|
||||
> return 1
|
||||
> ... # ...
|
||||
> return ... # On retourne 1 + min(g,h,...)
|
||||
> ```
|
||||
>
|
||||
> 7. Ecrire un algorithme simple pour afficher ```t``` à l'aide de ```matplotlib``` et vérifier le bon fonctionnement de votre algorithme.
|
||||
>
|
||||
> > **Aide**
|
||||
> >
|
||||
> > ```python
|
||||
> > import matplotlib.pyplot as plt
|
||||
> > ...
|
||||
> > plt.imshow(t,cmap='binary')
|
||||
> > plt.show()
|
||||
> > ```
|
||||
>
|
||||
> 8. Ecrire un algorithme qui parcourt toute l'image et qui retourne la ligne et la colonne du carré le plus grand ainsi que sa taille.
|
||||
>
|
||||
> - ```RechercheCarreBlanc_naif(t)``` : Retourne la ligne et la colonne du coin inférieur droit du carré blanc le plus grand ainsi que sa taille.
|
||||
>
|
||||
> ```python
|
||||
> def RechercheCarreBlanc_naif(t):
|
||||
> ...
|
||||
> for lig in range(...):
|
||||
> for col in range(...):
|
||||
> ...
|
||||
> return l,c,tmax
|
||||
> ```
|
||||
>
|
||||
> 9. Bonus : Faire en sorte d'afficher ce carré lors de l'affichage de l'image.
|
||||
>
|
||||
> 10. Ajouter un compteur (variable global) ```compteur_naif``` permetttant de compter le nombre d'appels récursifs
|
||||
>
|
||||
> 11. Ecrire une fonction permettant de générer un tableau de $n\times n$ content un ratio de points noir de ```ratio_noir```%
|
||||
>
|
||||
> ```python
|
||||
> def genere_tab_alea(n, ratio_noir):
|
||||
> ...
|
||||
> return t
|
||||
> ```
|
||||
|
||||
# Programmation dynamique - Utilisation de la mémoïsation : ```RechercheCarreBlanc_memoisation()```
|
||||
|
||||
Remplacons nous dans le cadre d'un cas simple, on cherche ```PlusGrandCarreBlanc_Rec(2,2)```.
|
||||
|
||||

|
||||
|
||||
> 1. Pendant l'appel de ```PlusGrandCarreBlanc_Rec(2,2)```, quelles sont les 3 appels récursifs qui vont être exécutés ?
|
||||
>
|
||||
> - Appel n°1 : ```PlusGrandCarreBlanc_Rec( ... , ... )```
|
||||
> - Appel n°2 : ```PlusGrandCarreBlanc_Rec( ... , ... )```
|
||||
> - Appel n°3 : ```PlusGrandCarreBlanc_Rec( ... , ... )```
|
||||
>
|
||||
> 2. Compléter le tableau suivant qui liste, pour les appels n°1, n°2 et n°3, les appels récursifs exécutés.
|
||||
>
|
||||
> Appel n°1 : ```PGCB_Rec( ... , ... )``` | Appel n°2 : ```PGCB_Rec( ... , ... )``` | Appel n°3 : ```PGCB_Rec( ... , ... )```
|
||||
> ---------|----------|---------
|
||||
> ```PGCB_Rec( ... , ... )``` | ```PGrCB_Rec( ... , ... )``` | ```PGCB_Rec( ... , ... )```
|
||||
> ```PGCB_Rec( ... , ... )``` | ```PGrCB_Rec( ... , ... )``` | ```PGCB_Rec( ... , ... )```
|
||||
> ```PGCB_Rec( ... , ... )``` | ```PGrCB_Rec( ... , ... )``` | ```PGCB_Rec( ... , ... )```
|
||||
>
|
||||
> 3. Quels appels sont redondants ? Proposez une solution pour éviter cela.
|
||||
>
|
||||
|
||||
## Mise en place du tableau de mémoïsation
|
||||
|
||||
Pour économiser des appels récursifs, vous allez stocker **au fur et à mesure** les résultats de ces appels dans un tableau de même taille que l'image.
|
||||
|
||||
Ce tableau sera initialisé entièrement à ```-1```, ce qui signifie qu'aucun résultat n'a déjà été calculé pour ce pixel. Dans le cas contraire, il faudra stocker le résultat dans ce ```t_memo```
|
||||
|
||||
- ```t_memo``` : Tableau de même dimension que ```t``` qui stocke les valeurs de ```PlusGrandCarreBlanc_memo()``` au fur et à mesure des appels récursifs. Ce tableau est une variable globale.
|
||||
|
||||
> 4. Initialiser la variable globale ```t_memo```.
|
||||
>
|
||||
> **Aide :** En une ligne ... ```t_memo = [[-1 for i in ... ] for j ... ]```
|
||||
>
|
||||
> **Remarque :** On peut être malin et faire une copie de ```t``` en remplaceant les ```1``` (pixel noir) par des ```0``` (résultat connu) et les ```0``` (pixels blancs) par des ```-1``` (résultat inconnu)
|
||||
|
||||
## Évolution de ```PlusGrandCarreBlanc_Rec()``` en ```PlusGrandCarreBlanc_memo()```
|
||||
|
||||
> 5. En vous aidant de ```PlusGrandCarreBlanc_Rec()```, écrire la fonction ```PlusGrandCarreBlanc_memo()``` en stockant et utilisant les résultats précédamment calculés dans le tableau ```t_memo```
|
||||
|
||||
```python
|
||||
def PlusGrandCarreBlanc_memo(t, lig, col):
|
||||
if t_memo[lig][col] != -1: # Utilisation d'une valeur présente dans t_memo
|
||||
return ...
|
||||
if t[lig][col] == 1:
|
||||
...
|
||||
return ...
|
||||
```
|
||||
|
||||
> 6. Effectuer les tests sur différents pixels d'une image et sur différentes images. Vous pouvez aussi utiliser la fonction ```genere_tab_alea(n, ratio_noir)``` pour valider votre algorithme.
|
||||
|
||||
## Pour aller plus vite ... ```RechercheCarreBlanc_memo()``` ?
|
||||
|
||||
```PlusGrandCarreBlanc_memo()``` est une fonction équivalente à ```PlusGrandCarreBlanc_Rec()``` mais normalement plus rapide.
|
||||
|
||||
Il reste donc à parcourir une image pour trouver les coordonnées du coin inférieur droit du plus grand carré blanc dans l'image.
|
||||
|
||||
> 7. Ecrire la fonction ```RechercheCarreBlanc_memo()``` qui retourne les coordonnées du coin inférieur droit du plus grand carré blanc ainsi que sa taille.
|
||||
>
|
||||
> ```python
|
||||
> def RechercheCarreBlanc_memo(t):
|
||||
> l, c, tmax = 0, 0, 0
|
||||
> ...
|
||||
> return l, c, tmax
|
||||
> ```
|
||||
|
||||
## Complexité
|
||||
|
||||
> 8. A l'aide du module ```time```, mesurer la différence de performance de l'algorithme naïf et de celui qui utilisa le mémoïsation sur des images de tailles et de "ratio de noir" différents.
|
||||
>
|
||||
> $~$ | ```n=10``` / ```ratio=50``` | ```n=30``` / ```ratio=50``` | ```n=50``` / ```ratio=40``` | ```n=70``` / ```ratio=35```
|
||||
> ---------|----------|---------|----------|----------
|
||||
> ```RechercheCarreBlanc_Rec``` | $~$ | $~$| $~$| $~$
|
||||
> ```RechercheCarreBlanc_memo``` | $~$ | $~$| $~$| $~$
|
||||
>
|
||||
> 9. De la même manière que pour l'algorithme naïf, implanter un ```compteur_memo``` qui permettra de compter le nombre d'appels récursifs. Effectuer les tests avec les mêmes paramètres que dans la question précédente.
|
||||
>
|
||||
> $~$ | ```n=10``` / ```ratio=50``` | ```n=30``` / ```ratio=50``` | ```n=50``` / ```ratio=40``` | ```n=70``` / ```ratio=35```
|
||||
> ---------|----------|---------|----------|----------
|
||||
> ```RechercheCarreBlanc_Rec``` | $~$ | $~$| $~$| $~$
|
||||
> ```RechercheCarreBlanc_memo``` | $~$ | $~$| $~$| $~$
|
||||
>
|
||||
> Uniquement avec ```RechercheCarreBlanc_memo```, mesurer le temps d'exécution de l'algorithme avec ```n=500``` / ```ratio=50``` puis avec ```n=1000``` / ```ratio=50```.
|
||||
>
|
||||
> 10. Par combien a été multiplié le temps d'exécution lorsque ```n``` a doublé ? Conjecturer sur la complexité de cet algorithme.
|
||||
>
|
||||
> 11. Le gain de performance est-il subtanciel ?
|
||||
>
|
||||
|
||||

|
||||
|
||||
# Programmation dynamique - Optimisation "Bottom Up" : ```RechercheCarreBlanc_BU()```
|
||||
|
||||
L'optimisation "BOTTOM UP", consiste à traiter les problèmes du plus évident (les "plus petits") au moins évident (les "plus gros") en stockant les résultats au fur et à mesure dans un tableau.
|
||||
|
||||
Il faut toutefois identifier un ordre dans lequel résoudre les sous-problèmes. Dans notre cas l'ordre est :
|
||||
|
||||
- Traiter les problèmes de taille "0" : Les cases noires
|
||||
- Traiter les problèmes de taille "1" : Les cases sur la première ligne et première colonne
|
||||
- Traiter les problèmes de taille "2" : ...
|
||||
|
||||
Le tableau de "résultats", qui stocke au fur et à mesure les résultats de ````PlusGrandCarreBlanc(lig,col)````, se nommera ```res```.
|
||||
|
||||
> 1. Compléter, à la main, le tableau ```res``` pour les problèmes de taille "0".
|
||||
>
|
||||
> - Si le ```pixel(lig,col)``` est noir alors ```res[lig][col] = 0```
|
||||
>
|
||||
|
||||

|
||||
|
||||
> 2. Compléter, à la main, le précédent tableau ```res``` pour les problèmes de taille "1".
|
||||
>
|
||||
> - Si le ```pixel(lig,col)``` est sur la première ligne et/ou colonne alors ```res[lig][col] = 1```
|
||||
>
|
||||
|
||||

|
||||
|
||||
> 3. En l'état actuel, peut-on, à l'aide de ```res```, calculer ```PlusGrandCarreBlanc(1,1)``` directement (sans calcul intermédiaire) ? et ```PlusGrandCarreBlanc(2,2)``` ?
|
||||
>
|
||||
> 4. Comment faut-il parcourir le tableau pour être sûr qu'à chaque appel, l'algorithme dispose des résultats des problèmes de taille inférieur.
|
||||
>
|
||||
> 5. Ecrire un algorithme ```PlusGrandCarreBlanc_BU()``` qui :
|
||||
>
|
||||
> - Initialise le tableau ```res``` à -1
|
||||
> - Complète ```res``` avec les résultats de taille "0" (les cases noires)
|
||||
> - Complète ```res``` avec les résultats de taille "1" (1ère ligne/colonne)
|
||||
> - Parcours l'image et calcule les résultats de taille supérieur
|
||||
> - Et retourne ```res```
|
||||
|
||||
**Aide :**
|
||||
|
||||
- Remplir un tableau ```res```, qui a la même taille que l'image, et qui est initialisé -1 dans toutes les cases.
|
||||
- A l'aide de 2 boucles imbriquées sur les lignes et colonnes :
|
||||
- Si le ```t[lig][col]``` est noir, affectez ```0``` à ```res[lig][col]```
|
||||
- Sinon si ```lig==0``` ou ```col==0```, affectez 1 à ```res[lig][col]```
|
||||
- Sinon affectez ```min(res[lig][col-1] , res[lig-1][col-1] , res[lig-1][col] ) + 1``` à ```res[lig][col]```
|
||||
- Retourner ```res```
|
||||
|
||||
```python
|
||||
def PlusGrandCarreBlanc_BU(t):
|
||||
nb_lig, nb_col = ...
|
||||
res = [[-1 for i in ...] for j in ...]
|
||||
for lig in range(nb_lig):
|
||||
for col in range(nb_col):
|
||||
...
|
||||
return res
|
||||
```
|
||||
|
||||
## .... et trouver le carré blanc le plus grand (presque à la vitesse de la lumière) : ```RechercheCarreBlanc_BU()```
|
||||
|
||||
> 6. Ecrire ```RechercheCarreBlanc_BU()``` qui retourne les coordonnées du coin inférieur droit du plus grand carré blanc ainsi que sa taille à l'aide de l'algorithme précédent.
|
||||
>
|
||||
> ```
|
||||
> def RechercheCarreBlanc_BU(t):
|
||||
> l, c, tmax = 0, 0, 0
|
||||
> ...
|
||||
> return l, c, tmax
|
||||
> ```
|
||||
|
||||
## Comparaison des algorithmes
|
||||
|
||||
> 7. Comparer le temps d'éxecution des ces algorithmes.
|
||||
>
|
||||
> $~$ | ```n=100``` / ```ratio=30``` | ```n=300``` / ```ratio=20``` | ```n=1000``` / ```ratio=20``` | ```n=3000``` / ```ratio=40```
|
||||
> ---------|----------|---------|----------|----------
|
||||
> ```RechercheCarreBlanc_memo``` | $~$ | $~$| $~$| $~$
|
||||
> ```RechercheCarreBlanc_BU``` | $~$ | $~$| $~$| $~$
|
||||
|
||||
## Conclusion
|
||||
|
||||
Programmation dynamique = Gain en performance
|
||||
|
||||
L'étude théorique d'un problème permet une optimisation précise de l'algorithme qui le résoudra.
|
||||
|
||||

|
Binary file not shown.
11
README.md
11
README.md
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title : TP - Recherche du plus grand carré blanc
|
||||
author : TOTARA Cédric et BERTRAND Benjamin
|
||||
author : TODARO Cédric et BERTRAND Benjamin
|
||||
date : 24 juin 2021
|
||||
---
|
||||
|
||||
@@ -8,9 +8,11 @@ date : 24 juin 2021
|
||||
|
||||
## Déroulement
|
||||
|
||||
Toute la séquence est supporter par [ce support](./support/support.pdf)
|
||||
|
||||
### Approche déconnecté
|
||||
|
||||
On distribue des images en noir et blanc et on demande aux élèves de trouver les plus grand carré blanc à l'intérieur en précisant la taille et le coin inférieur droit. Ce premier travail est à faire seul.
|
||||
On distribue [des images en noir et blanc](./support/fig/grids.pdf) et on demande aux élèves de trouver les plus grand carré blanc à l'intérieur en précisant la taille et le coin inférieur droit. Ce premier travail est à faire seul.
|
||||
|
||||
Ils doivent ensuite,en groupe, déterminer au crayon une stratégie/algorithme pour trouver les solutions à ce problème et préparer une façon d'exposer leur méthode à leur camarades. Ils sont invité à faire des schémas, écrire l'algorithme ou encore présenter des relations.
|
||||
|
||||
@@ -47,3 +49,8 @@ En fonction de là où en est la progression, on pourra demander aux élèves de
|
||||
Le cours sur l'algorithme utilisant la programmation dynamique a été distribué aux élèves à la suite de temps réservé à la programmation de leur méthode. Ils devront l'implémenter à leur tour.
|
||||
|
||||
Les élèves qui auraient déjà réussi à l'implémenter, ont un problème supplémentaire de programmation dynamique `trouver le plus grand rectangle d'un histogramme`. La méthode est expliquée, ils doivent l'implémenter.
|
||||
|
||||
|
||||
### Approche différente possible
|
||||
|
||||
Voir [une approche différente du thème](./FOAD-bloc5.pdf). Cette approche est plus directive pour travailler la programmation dynamique.
|
@@ -23,6 +23,26 @@ def trim_axs(axs, N):
|
||||
return axs[:N]
|
||||
|
||||
|
||||
def draw_image(grid, ax):
|
||||
hight = len(grid)
|
||||
lenght = len(grid[0])
|
||||
ax.tick_params(left=False, bottom=False, labelleft=False, labelbottom=False)
|
||||
ax.imshow(grid, cmap="binary")
|
||||
ax.hlines(
|
||||
y=np.arange(0, hight) + 0.5,
|
||||
xmin=np.full(lenght, 0) - 0.5,
|
||||
xmax=np.full(lenght, hight) - 0.5,
|
||||
color="gray",
|
||||
)
|
||||
ax.vlines(
|
||||
x=np.arange(0, lenght) + 0.5,
|
||||
ymin=np.full(lenght, 0) - 0.5,
|
||||
ymax=np.full(lenght, hight) - 0.5,
|
||||
color="gray",
|
||||
)
|
||||
return ax
|
||||
|
||||
|
||||
def grid_to_image(grids, filename):
|
||||
""" """
|
||||
plt.clf()
|
||||
@@ -31,23 +51,7 @@ def grid_to_image(grids, filename):
|
||||
axs = plt.figure(constrained_layout=True).subplots(n_rows, n_cols)
|
||||
axs = trim_axs(axs, len(grids))
|
||||
for ax, grid in zip(axs, grids):
|
||||
# for i, grid in enumerate(grids):
|
||||
hight = len(grid)
|
||||
lenght = len(grid[0])
|
||||
ax.tick_params(left=False, bottom=False, labelleft=False, labelbottom=False)
|
||||
ax.imshow(grid, cmap="binary")
|
||||
ax.hlines(
|
||||
y=np.arange(0, hight) + 0.5,
|
||||
xmin=np.full(lenght, 0) - 0.5,
|
||||
xmax=np.full(lenght, hight) - 0.5,
|
||||
color="gray",
|
||||
)
|
||||
ax.vlines(
|
||||
x=np.arange(0, lenght) + 0.5,
|
||||
ymin=np.full(lenght, 0) - 0.5,
|
||||
ymax=np.full(lenght, hight) - 0.5,
|
||||
color="gray",
|
||||
)
|
||||
draw_image(grid, ax)
|
||||
|
||||
plt.savefig(filename)
|
||||
|
BIN
support/fig/sauvegarde.png
Normal file
BIN
support/fig/sauvegarde.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
@@ -71,10 +71,28 @@
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Programmation de l'algorithme\\ programmation dynamique}
|
||||
\begin{frame}{Programmation dynamique de l'algorithme}
|
||||
\begin{block}{Récurrence}
|
||||
|
||||
|
||||
\begin{minipage}{0.45\linewidth}
|
||||
\includegraphics[scale=0.5]{./fig/recurence}
|
||||
\end{minipage}
|
||||
\hfill
|
||||
\begin{minipage}{0.45\linewidth}
|
||||
On note \texttt{gc(i, j)} la taille du plus grand carré possible qui a le coin inférieur droit en position $(i,j)$.
|
||||
\end{minipage}
|
||||
\[
|
||||
\scriptstyle
|
||||
gc(i, j) = \left\{
|
||||
\begin{array}{ll}
|
||||
0 & \mbox{Si noir}\\
|
||||
\min(gc(i-1, j), gc(i, j-1), gc(i-1, j-1)) +1 & \mbox{Si blanc}
|
||||
\end{array}
|
||||
\]
|
||||
\end{block}
|
||||
\begin{block}{Stockage des valeurs}
|
||||
\begin{center}
|
||||
\includegraphics[scale=0.4]{./fig/sauvegarde}
|
||||
\end{center}
|
||||
\end{block}
|
||||
\end{frame}
|
||||
|
||||
|
Reference in New Issue
Block a user