Calcul de complexité. Programmation dynamique.

Transcription

Calcul de complexité. Programmation dynamique.
Année universitaire 2014/2015
Site : Luminy St-Charles St-Jérôme Cht-Gombert Aix-Montperrin Aubagne-SATIS
Sujet de : 1er semestre 2 ème semestre Session 2
Durée de l’épreuve : 2h
Examen de : L2
Nom du diplôme : Licence d’Informatique
Code du module : SIN3U1
Libellé du module : Algorithmique
Calculatrices autorisées : NON
Documents autorisés : OUI, polys et notes de Cours/TD/TP
Dans tout ce qui suit vous utiliserez les notations O(f (n)) et Θ(f (n)) pour décrire le comportement asymptotique d’un algorithme (sa complexité). Les ∗ donnent une indication sur la difficulté des questions.
Calcul de complexité.
Question 1∗ . Dans la fonction count()
définie ci-contre, combien de fois la boucle
while sera effectuée dans le pire des cas ?
Question 2∗ . Ecrivez l’équation récursive qui décrit le nombre d’opérations élémentaires T (n) effectuées par la fonction
count() dans pire des cas.
Question 3∗ . Déduisez-en la complexité
dans le pire des cas de la fonction count(),
en expliquant comment vous obtenez ce résultat.
int count (int *T, int n)
{
int j;
if (n == 0)
return 0;
j = 1;
while ((n-1-j >= 0) && (T[n-1-j] != T[n-1]))
j = 2*j;
if (n-1-j >= 0)
return count(T, n-1);
return (count(T, n-1)+1);
}
Programmation dynamique.
Dans un jeu de type jeu de l’oie (constitué d’une suite de cases contigues, la première est la case de départ et la
dernière la case d’arrivée), le joueur progresse de une ou deux cases, au choix. Sur chaque case où il s’arrête, le
joueur doit s’acquitter d’une pénalité (qui peut être nulle). Soient p0 , p1 , p2 , . . . , pn , pn+1 la suite des pénalités
associées aux cases du jeu, de la première à la dernière. Les pénalités p0 et pn+1 correspondent aux cases de
départ et d’arrivée, et sont nulles. On veut calculer la pénalité totale minimale dont devra s’acquitter un joueur
pour joindre la case de départ à la case d’arrivée.
Question 1∗ . Quelle est la pénalité totale minimale si les pénalités associées aux cases du jeu sont les
suivantes : p0 = 0, p1 = 10, p2 = 22, p3 = 10, p4 = 13, p5 = 23, p6 = 0 ?
Question 2∗ . On note Pmin (i) la pénalité totale minimale dont devra s’acquitter un joueur partant de la case
de départ pour atteindre la ième case (la pénalité de la case i est comprise). Avec la suite de pénalités de la
question 1 quelles seraient les valeurs de Pmin (i) pour i = 0, . . . , n + 1.
Question 3∗∗ . Définissez par une formule récursive la pénalité minimale Pmin (i).
Question 4∗∗ . Ecrivez une fonction en C qui permet de calculer la suite des valeurs de Pmin à partir de
la suite des pénalités des cases du jeu en utilisant la formule de la question précédente. Choisissez les bons
paramètres.
Question 5∗∗ . Ecrivez une fonction en C qui affiche un parcours dont la pénalité totale est minimale, à partir
des valeurs de Pmin .
Question 6∗∗ . Le problème de la recherche d’un parcours de pénalité totale minimale peut se formuler comme
la recherche d’un plus court chemin dans un graphe. Dessiner le graphe orienté correspondant à l’exemple de
la Question 1. Faire apparaître sur le dessin la longueur de chacun des arcs et mettre en évidence le sommet
source s et le sommet destination t. Executer l’algorithme de Dijkstra sur ce graphe et préciser pour chaque
sommet i la longueur P (i) du plus court chemin entre s et i.
Arbres binaires.
On considère la structure d’arbre binaire suivante :
typedef int TYPE_VALEUR;
typedef struct noeud * ARBRE;
typedef struct noeud{
TYPE_VALEUR val;
ARBRE fg,fd;
} NOEUD;
On souhaite écrire une fonction permettant de vérifier si un arbre binaire donné est un arbre binaire de recherche
ou non : elle prendra en entrée un arbre binaire a et retournera 1 si a est un arbre binaire de recherche et 0
sinon.
Question 1∗ . On considère le programme suivant :
int verificationABR(ARBRE a){
if (a == NULL)
return 1;
if (a->fg != NULL && a->val < a->fg->val)
return 0;
if (a->fd != NULL && a->val > a->fd->val)
return 0;
return (verificationABR(a->fg) && verificationABR(a->fd));
}
Montrez que ce programme est INCORRECT. Pour cela, trouvez un arbre pour lequel il donne une réponse
incorrecte.
Question 2∗∗ . En supposant que vous disposez des fonctions int val_min(ARBRE a) et int val_max(ARBRE
a) qui retournent respectivement les valeurs minimale et maximale d’un arbre binaire de recherche non vide,
écrivez une fonction C verificationABR qui soit correcte.
Question 3∗∗∗ . La fonction que vous avez écrite explore t-elle chaque noeud une seule fois ? Si la réponse est
non, écrivez une fonction de vérification qui ait cette propriété.