• Aucun résultat trouvé

TD en info 31, L2

N/A
N/A
Protected

Academic year: 2022

Partager "TD en info 31, L2"

Copied!
7
0
0

Texte intégral

(1)

TD en info 31, L2

Récursion, problème de Hanoï

Récursion. Problème des pesées. On a 3^n pièces dont une est plus légère que les autres. La trouver en un minimum de pesées avec une balance (qui a trois sorties : poids du premier plateau plus grand, égal ou plus petit que le poids du second plateau)

Triangle de Sirpinski. Soit A B C les sommets du triangle. Calculer A' B' C' en fonction de A B C.

Voir que A'= milieu( B, C). Le triangle initial n'a pas à être équilatéral.

Von Koch. Les points extrémités sont A et B ; exprimer les trois points intermédiaires en fonction de A et B. Vonkoch( A, B, n)= si 0=n alors tracer(A, B) sinon soit C,D,E=... dans (Vonkoch(A, C, n-1) ; Vonkoch(C, D, n-1) ; Vonkoch( D, b, n-1) )

Dragon. Les points extrémités sont A et B ; exprimer le point intermédiaire en fonction de A et B.

drag( A, B, n) = si 0=n alors tracer'A, B) sinon soit C=... dans (drag (A, C, n-1) ; drag(B, C, n-1)).

Ackermann. La fonction d'Ackermann (à programmer en TP) est définie par A(m,n)=n+1 si 0=m

A(m,n)=A(m-1,1) si m>0 et n=0

A(m,n)=A(m-1, A(m, n-1)) si m>0 et n>0

A(4,2) is an integer of 19729 decimal digit. Voir que, en théorie, le calcul termine. En pratique, la pile est saturée.

(2)

Interpolation linéaire. Ecrire la procédure d'interpolation : la droite passe par deux points donnés (x1, y1) et (x2, y2). Quel est le y pour x donné? C'est nécessaire pour tracer Mandelbrot ou Julia dans un cadre donné.

Mandelbrot. Préparer le TP. Cet ensemble est dans le disque C de centre (0,0) et de rayon 2. Soit f_c(z)=z^2+c. L'orbite orb( f ) est l'ensemble des points 0, f(0), f(f(0)), etc. L'ensemble de Mandelbrot est l'ensemble des c complexes tels que l'orbite orb( f_c ) reste dans le disque C. Pour tous les points c de l'image, on calcule les premiers points de l'orbite de f_c, en s'arrêtant au plus à la 50 ième itération (si l'orbite ne sort pas avant du disque C). La couleur affichée pour le point c dépend du nombre d'itérations nécessaires pour sortir de C, par exemple blanc pour 0, noir pour 50.

Julia. Préparer le TP. Cet ensemble Julia(c)= J_c dépend d'un complexe c. Si c est dans Mandelbrot, alors le Julia correspondant est connexe. C'est l'ensemble des points z tels que l'orbite de z par f_c reste dans le disque de centre (0, 0) et de rayon 2. Utiliser pour le dessiner la même méthode que pour Mandelbrot. Sur wikipedia, en TP, vous trouverez de jolies valeurs pour c.

Puissance rapide. Proposez un algorithme non récursif pour la puissance rapide a^n. Idée : écrire n en base 2. Parcourir les bits de n de gauche à droite.

Partir de R=1. Pour les bits à zéro, élever R au carré. Pour les bits à 1, élever R au carré et multiplier par a. A la fin, R vaut a^n (si je ne me suis pas trompé).

Comparer à :

Partir de N=0. Pour les bits à zéro, multiplier N par 2. Pour les bits à 1, multiplier N par 2 et lui ajouter 1. A la fin, N vaut n.

Complexité.

1. Un algorithme met un temps T(n)= K n^2 = O(n^2) ; que peut on dire de T(10 n) par rapport à T(n) ?O(n^2) est la complexité du tri naïf. Même question pour O(n^3).

2. Un algorithme met un temps T(n)= K 2^n. Exprimer T(n+1) en fonction de T(n).

3. Certains algorithmes (calcul formel) sont doublement exponentiel : T(n)=2^(2^n). Calculez les premières valeurs de T(n) pour n=0, 1, … 10.

4. diagramme log-log. Parfois on mesure les temps d'exécutaion d'un programme, ce qui donne un ensemble de points (n, T(n)). Au lieu de tracer la courbe (n, T(n)), on trace la courbe passant par les points (x,y) avec x=log n, et y=log( T(n)). Exprimer y en fonction de x pour T(n)=n^d, et pour T(n)=2^n. Que constatez-vous ?

5. résoudre : 2^k = n^x, où l'inconnue est x. C'est nécessaire pour certaines complexités (ex : Karatsuba).

Fibonacci. F(0)=0, F(1)=1, et F(n)=F(n-1)+F(n-2) si n>1.

Donnez en une définition récursive.

Tracer l'arbre des appels récursifs de F(4) : les feuilles de cet arbre sont des 0 et des 1. Quel est le nombre de feuilles 0 et de feuilles 1 pour F(n) ? Quel est le nombre de nœuds de l'arbre (un arbre binaire qui a k feuilles a k-1 nœuds internes : coupe de football).

Donnez une expression matricielle pour Fibonacci : exprimer le vecteur 2 lignes 1 colonne : F(n-1), F(n) en fonction du vecteur 2 lignes 1 colonne F(n-2), F(n-1). Quelle est la matrice ? En utilisant la

(3)

puissance rapide vue en cours, en déduire un algorithme rapide pour calculer F(n).

Calculer les deux valeurs propres de la matrice. C'est (1+ou – sqrt(5.))/2, phi=1.618... et phi'=-0.618...

On peut prouver que F(n) = a phi^n + b phi'^n pour deux constantes a et b. Trouver ces constantes (considérer F(0) et F(1)).

Tri naïf dans un tableau. Préparer le TP.

double v= Math.floor( 10000. * Math.random());

http://ufrsciencestech.u-

bourgogne.fr/licence2/Info31/CORRECTIONS/TRI_NAIF_TABLEAU/trinaif.java

Tri rapide dans un tableau. Préparer le TP. La partie difficile est la partition, quand le tableau est modifié en place (ie on n'utilise pas d'autre tableau). Décrire la méthode vue en cours : le tableau contient : le pivôt, les éléments <= pivôt (initialement vide), les éléments > pivôt (initialement vide), les éléments non traités. Il faut parfois faire un échange de deux éléments. Que se passe-t-il quand tous les éléments sont égaux ? Proposez une méthode de partition en 3 classes : <, ==, >. Parfois, deux échanges sont nécessaires pour insérer un élément non traité dans la partition.

Remarque : la correction contient un Comparator. Elle est dans http://ufrsciencestech.u- bourgogne.fr/licence2/Info31/CORRECTIONS/TRI_RAPIDE_TABLEAU/qksort.java

Tri par fusion d'un tableau. Préparer le TP. Ecrire l'algorithme. Utiliser un tableau auxiliaire.

Algorithme d'Erathostène. La correction est dans http://ufrsciencestech.u-

bourgogne.fr/licence2/Info31/CORRECTIONS/ERATOSTHENE/Eratosthene.java PGCD, Euclide, Bezout.

Calculer le pgcd de a, b= 34, 18 (par exemple), ainsi que u et v tels que au+bv= pgcd(a,b). Utiliser le tableau avec des colonnes : a, b, quotient de a par b, reste de a par b, (ces colonnes sont remplies « en descendant »), pgcd, u et v (remplies en remontant).

Calculer en utilisant la représentation matricielle : le vecteur colonne a,

b

est égal à la matrice 2x2 : quotient a par b, 1

1, 0

par le vecteur b

a modulo b

et on itère jusqu'au reste nul.

Tester cette dernière méthode sur deux nombres de Fibonacci successifs. C'est le pire des cas (théorème de Lamé).

Tri par tas (heap). Préparez le TP. La correction est dans:

http://ufrsciencestech.u-bourgogne.fr/licence2/Info31/CORRECTIONS/HEAPSORT/

Liste. Préparer le TP. Implantation d'une liste. Tri rapide d'une liste. Tri fusion d'une liste. La correction est dans

(4)

http://ufrsciencestech.u-bourgogne.fr/licence2/Info31/CORRECTIONS/TRIS_DE_LISTE/L.java Arbre. Préparer le TP. Trier en insérant dans un arbre binaire (non équilibré) puis en parcourant l'arbre. La correction est dans :

http://ufrsciencestech.u-

bourgogne.fr/licence2/Info31/CORRECTIONS/TRI_PAR_ARBRE_BINAIRE/Arb.java

RECHERCHE ARBORESCENTE. Préparez le TP sur le problème des reines ou sur le Compte est bon. Ne pas donner le fichier Reine.java si le TP est fait sur les reines. Si le TP est fait sur le Compte est bon, demandez aux étudiants quels sont les « fils » d'un état. Insister sur le fait qu'un état doit connaître son histoire, soit sous forme d'arbre (+ (* 7 10) 3) soit sous forme de chaîne postfixe : 7 10 * 3 +. C'est possible d'utiliser un arbre en Java (grâce à son glanage de cellules), c'est plus délicat en C+

+ : soit on ne gère pas la récupération et la mémoire est vite saturée, soit on la gère à la main, ce qui est risqué.

Fichier Search.java interface Search {

public boolean estsolution( Object o);

public L empilefils( Object state, L pile);

public L backtrack( L pile, L solutions);

}

Fichier L.java pour gérer les listes de solutions ou d'états (sommets de l'arbre de recherche) public class L {

Object head;

L tail;

public static L nil=null;

public static boolean isempty( L l) { return null==l; } public static Object hd( L l) { return l.head; }

public static L tl( L l) { return l.tail; }

public static L cons( Object o, L q) { L l=new L(); l.head=o; l.tail=q; return l;}

}

Fichier Backtrack.java

abstract class Backtrack implements Search { public L backtrack( L pile, L solutions)

{ while( L.nil != pile)

{ Object etat= L.hd( pile); pile= L.tl( pile);

if (estsolution( etat)) solutions=L.cons( etat, solutions);

else pile=empilefils( etat, pile);

}

return solutions;

} }

Fichier Pbm.java ( aller de 1 à 100 par doublement et (doublement; incrémentation) public class Pbm extends Backtrack implements Search

{ public boolean estsolution( Object o) { int i= ((Integer)o).intValue(); return 100==i; } public L empilefils( Object s , L pile)

(5)

{ int n=((Integer) s).intValue();

if (n < 100) { Object x1= new Integer(2*n); Object x2 = new Integer(2*n +1);

return L.cons( x1, L.cons( x2, pile)); } else return pile;

}

public static void main (String[] args) { Pbm pb= new Pbm();

L sol= pb.backtrack( L.cons( new Integer( 1), L.nil), L.nil);

for( L l=sol; null!=l; l=L.tl(l))

{ int x=((Integer) L.hd(l)).intValue(); System.out.println( "Solution: "+ x); } }

}

Fichier Reine.java /* ne pas donner si les étudiants font leur TP sur ça */

class Etat

{ public int n;

public int nposees;

public int tab[];

Etat( int nb) { tab=new int[nb]; nposees=0; n = nb; for(int i=0; i<nb; i++) tab[i]= -1; } public String toString()

{ String s=""; for (int k=0; k<nposees; k++) s = s + this.tab[k] + ";" ; return s; } }

public class Reine extends Backtrack implements Search { public boolean estsolution( Object o)

{ Etat etat= (Etat) o;

return etat.nposees==etat.n; } public boolean conflit( Etat e, int col, int lig) { assert( col== e.nposees);

for (int c=0; c<e.nposees; c++)

{ if (e.tab[c]==lig || Math.abs( col-c) == Math.abs( lig – e.tab[c])) return true; } return false;

}

public L empilefils( Object s, L pile) { Etat etat= (Etat) s;

if (estsolution( s)) return pile;

for (int k=0; k<etat.n; k++)

{ if (!conflit( etat, etat.nposees, k)) { Etat fiston=new Etat( etat.n);

for (int t=0; t<etat.nposees; t++) fiston.tab[t]=etat.tab[t];

fiston.tab[ etat.nposees ]=k; fiston.nposees= 1+etat.nposees;

pile= L.cons( fiston, pile); } }

return pile;

}

public static void main (String[] args) { int nb= Integer.parseInt(args[0]);

Reine pb= new Reine(); Etat vide= new Etat( nb);

L sol= pb.backtrack( L.cons( vide, L.nil), L.nil);

int nsol=0;

(6)

for( L l=sol; null!=l; l=L.tl(l), nsol++) { Etat e=(Etat) L.hd(l);

System.out.print( "Solution " + nsol + ": ");

for (int k=0; k<e.nposees; k++) System.out.print( e.tab[k]+"; ");

System.out.println();

} }

}

Backtrack, sudoku, coloriage de graphes. Définir l'état, et la fonction empilefils. Idée possible : gérer pour chaque sommet une liste des couleurs possibles pour ce sommet. Pour colorier, choisir le sommet S qui a le moins de couleurs possibles (possiblement, le sommet qui n'a plus de couleur possible, ce qui provoque l'arrêt de l'exploration de ce sous arbre des possibles), colorier C avec la première couleur possible, enlever pour chaque voisin de S la couleur donnée à ce sommet. L'état est donc : un tableau de liste de couleurs possibles pour chaque sommet.

Backtrack. Transvasements 3, 5, 8. Trois récipients non gradués ont des contenances de 3, 5 et 8 litres. Passer par des transvasements de 0, 0, 8 à 0, 4, 4 litres. Remarque : on peut dessiner le triangle x+y+z=8, limité par x >= 0, y>=0, z>=0, et par x<=3, y<=5, z<=8 pour l'intuition. Comment représenter les états, comment programmer les transitions entre états ?

Optimalité des algorithmes de tri. Il faut au moins log( n!) comparaisons de 2 éléments pour trier n éléments. Montrer (cela a été vu en CM) que log( n!) = O(n log n). La formule de Stirling n'est pas nécessaire, mais la voici :

n ! tend vers (n/e)n sqrt(2 pi n) quand n tend vers l'infini.

Division russe. Pour diviser a par b, retirer de a le plus grand 2kb possible, ajouter 2k au quotient et recommencer sur le reste a- 2kb. Ca peut s'exprimer par le vecteur (a, b) en colonne égal à la matrice 2x2, en première ligne 1, et 2k et en deuxième ligne 0, 1, multipliée par le vecteur colonne (a- 2kb) et b.

On arrête quand le reste est inférieur à b.

Arithmétique. Convertir un entier en la liste de ses chiffres en base 10.

let rec decons l n = if 0=n then l

else decons ((n mod 10)::l) (n/10);;

(*

decons [] 1234;;

- : int list = [1 ; 2 ; 3 ; 4]

*)

Arithmétique. Convertion inverse : reconstruire un entier avec la liste de ses chiffres en base 10.

let rec recons l n=

match l with

| [] -> n

| t::q -> recons q (10*n+t);;

(*

recons [1; 2; 3; 4 ] 0;;

- : int = 1234

*)

(7)

Retourner une liste en utilisant une pile.

let rec reverse l stack = match l with

| [] -> stack

| t::q -> reverse q (t::stack);;

(*

reverse [1; 2; 3; 4 ] [];;

- : int list = [4; 3; 2; 1]

*)

Programmation dynamique. Faire les dates au plus tôt et au plus tard sur un graphe (sans circuit) simple. On peut supposer qu'il y a un sommet initial et un seul sommet terminal. Le graphe est sans cycle. Les arcs portent des durées. Les formules sont :

tôt(initial)= 0, tôt(t) = max pour tous les s prédécesseurs de t de ( tôt(s)+durée(s->t))

tard(final) =tôt(final) ; tard(s) = min pour tous les t successeurs de s de ( tard(t)-durée( s-> t) ) On montre que tard( initial)=0 (sauf erreur de calcul).

Si tôt( v) = tard(v) alors v est un sommet critique. L'arc entre deux sommets critiques est un arc critique. Il y a toujours au moins un chemin critique entre le sommet initial et le sommet terminal.

Programmation dynamique. Voir l'exemple de la pyramide des nombres dans https://fr.wikipedia.org/wiki/Programmation_dynamique

Le parenthésage optimal de deux matrices. Retrouver la formule. Dans quel ordre faut-il remplir la matrice (quand on a l'infortune de programmer en Java) ?

Sac à dos et programmation dynamique. On suppose que les poids sont entiers. Retrouver la formule. C'est aussi le problème du rendu de la monnaie.

La séquence croissante la plus longue. Le faire sur un exemple.

La séquence commune à deux séquences la plus longue. Le faire sur un exemple. Réduire ce problème au problème du chemin le plus long (critique) dans un graphe sans circuit.

Distance d'édition de Levenshtein entre deux mots.

https://fr.wikipedia.org/wiki/Distance_de_Levenshtein

L'algorithme de Smith-Waterman trouve le meilleur appariement entre deux séquences, en bioinformatique. https://fr.wikipedia.org/wiki/Algorithme_de_Smith-Waterman

Références

Documents relatifs

13  Conseil de sécurité des Nations Unies, Security Council imposes sanctions on those derailing Mali peace process, unanimously adopting Resolution 2374

Comme vous pouvez le voir sur les illus- trations, tous les composants utilisés dans le câblage, à l’exception de la diode D1, sont du type à montage en sur face et, de ce fait,

Les deux demi-ondes étant actives durant 15 millisecondes et en pause durant 5 millisecondes, un cycle com- plet aura donc une durée de 20 milli- secondes et, pour calculer la

J’affirme que j’ai construit deux poly` edres convexes : l’un dans lequel toutes les faces ont six arˆ etes ou plus et l’autre dans lequel les nombres d’arˆ etes qui partent

Ajouter une anse réduit de 2 unités la caractéristique d’Euler- Descartes de la surface χ = S + F − A (où S est le nombre de sommets du graphe représentant ce réseau, F son

Lorsque la fourmi arrive sur un côté de la boite, elle choisit la direction géodésique qui lui ferait décrire une ligne droite si les deux faces partageant ce côté

La troisième face devrait contenir un même segment tant pour l’aller que pour le retour et de proche en proche il en serait de même pour chacune des faces où passe la fourmi, ce

HIRTZBERGER Pierre -Ingénieuren chef .IMBERT Pierre - DGST.. LE COUVEZ Jean-Jacques - Contrôleurprincipal des transmissions