Le TP est à rendre sur arche ou par mail au responsable du cours, et ce avant 16h05.
Les différents fichiers nécessaires à la résolution du TP sont ici.
Le rendu consiste en quelques fichiers Java
, quelques fichiers à
lire avec gnuplot
et un petit fichier texte répondant à la
dernière question de la deuxième partie.
La classe Tableau.java
qui vous est donné permet de représenter un
tableau d'entiers. Comme vous pouvez le voir, le tableau est
représenté en interne par une ArrayList
d'entiers, mais ce n'est
pas important.
La classe dispose des méthodes suivantes:
Tableau()
qui crée un nouveau tableau vide
Tableau(int n)
qui crée un nouveau tableau de n
cases remplies par les entiers de 1 à n
display()
qui affiche le tableau
add(int x)
qui ajoute x
à la fin du tableau.
get(int i)
qui renvoie la i
ème case du tableau
set(int i, int x)
qui permet de changer la valeur de la i
ème case du tableau
size()
qui renvoie la taille du tableau
Attention les cases du tableau sont numérotées à partir de 0
.
shuffle()
qui mélange le tableau. On utilisera l'algorithme de Fisher-Yates vu en devoir.
select(int x)
qui renvoie le ième plus
petit élément du tableau. On utilisera la méthode quickselect vue en TD
(voir la fin de ce document pour un rappel sur quickselect)
Tableau(int n, int no)
qui crée un
tableau contenant n
cases dont no
sont initialisées à la
valeur 0
et les autres à 1
. On appellera la fonction
shuffle
sur le résultat pour que la position des 0
soit
aléatoire.
search()
qui renvoie une position i
où
se trouve un 0
. L'algorithme search
fonctionnera de la façon
suivante: Il choisit des cases au hasard jusqu'à trouver 0
(en particulier l'algorithme boucle s'il n'y a pas de 0
dans
le tableau)
sample(int n)
qui renvoie un tableau
constitué de n
cases distinctes du tableau T choisies
aléatoirement. Par exemple, si T est le tableau [1,3,17,21,6,18,5],
sample(3)
peut renvoyer le tableau [6,17,1], ou encore [21,5,3].
Afin d'étudier la complexité des algorithmes précédents, on va modifier le code pour savoir combien de cases ont été accédées.
get
pour que chaque
appel à cette fonction incrémente un compteur, qui nous permet
ainsi de savoir combien de fois la fonction a été appelée.
Attention: La variable compteur
doit être du type static int
, pour être partagée entre toutes les instances de la classe.
select(n/2)
et regarder combien d'accès au tableau ont été
nécessaires pour quickselect.
On affichera les résultats avec gnuplot
(voir l'exemple).
0
, appeler la
méthode search
et regarder combien d'accès au tableau ont été
nécessaires pour search
. On affichera les résultats avec
gnuplot
. Que constate-t-on ? Expliquer-le.
Le but de cette partie est de s'intéresser à des algorithmes en ligne, c'est à dire des algorithmes qui n'ont le droit de lire leur entrée qu'une seule fois, et qui n'ont pas assez de place pour tout retenir.
Lire bien l'énoncé jusqu'au bout
int rand(Stack <Integer> s)
qui prend une pile
contenant des entiers et qui renvoie un des entiers de la pile au
hasard. Vous n'avez le droit à aucune structure de données (pas de
tableaux, pas d'ArrayList...), vous avez uniquement le droit d'utiliser des
variables de type int
(et une variable de type Random
pour
pouvoir produire des nombres aléatoires, évidemment).
Attention: Sur une pile, les seules méthodes que vous avez le droit
d'utiliser sont s.pop()
qui dépile et vous renvoie le premier
élément de la pile, et s.empty()
qui teste si la pile est vide
(vous pouvez aussi empiler, mais ca ne vous sera pas très utile ici). En
particulier, la seule façon de connaître la taille de la pile est de
tout dépiler, mais comme il n'y a pas moyen de garder en mémoire les
éléments que vous avez lu (puisque qu'aucune structure de
données n'est autorisée), vous allez perdre le contenu de la pile en le faisant.
On rappelle le principe de QuickSelect. QuickSelect part d'un tableau T et d'un entier i et cherche le ième plus petit élément du tableau T.
FRSelect part d'un tableau T et d'un entier i et cherche le ième plus petit élément du tableau T.
sample
). Appelons S le résultat