INF411 — TD3
Au téléphone avec le Président

Ce TD est plus court que les précédents, mais aussi moins guidé. Votre code est à placer comme d'habitude dans un fichier TD3.java. Il n'y a pas de squelette de code fourni, seulement quelques fichiers pour vous aider à tester votre code à certaines questions. Vous pouvez aussi, comme d'habitude, vous aider de la documentation officielle de la bibliothèque standard de Java.

Le sujet est adapté de ce problème du Projet Euler.

Le problème

On considère un réseau dynamique qui évolue de la façon suivante.

L'objectif est de déterminer au bout de combien d'appels téléphoniques un sommet donné (le « Président ») est relié à une certaine proportion, par exemple 99%, de la population totale.

1. Un générateur pseudo-aléatoire

Pour tirer « au hasard » les appels téléphoniques, on utilise un générateur pseudo-aléatoire, c'est-à-dire un procédé déterministe dont le résultat « ressemble » du point de vue statistique à une suite de nombres aléatoires. (La méthode Math.random() que l'on a utilisée au TD1 donne aussi accès à un générateur pseudo-aléatoire. Mais aujourd'hui, nous allons implémenter le nôtre.) Le générateur utilisé ici s'appelle un générateur de Fibonacci à retard.

On définit une suite (Si) par la relation de récurrence

On souhaite pouvoir traiter des valeurs de m de l'ordre du million et calculer plusieurs centaines de millions de termes de la suite (Si).

On observe que pour i = 54, on a 300007i3 = 47240302248 ≥ 231. Or le type int de Java permet de représenter les entiers compris entre −231 et 231 − 1 (inclus) uniquement. Il faudra donc faire attention à la façon de mener les calculs pendant la phase d'initialisation du générateur.

Question 1

Écrivez une classe PRNG fournissant

de sorte que les appels successifs à getNext() sur un objet de la classe PRNG nouvellement construit renvoient les termes de la suite (S0, S1, …) un à un.

Testez votre code en exécutant le fichier Test1.java.

Indications

Déposez le fichier TD3.java.

2. Les appels téléphoniques

Les appels sont définis à partir de la suite (Si), avec un paramètre m égal à la population du réseau.

Au temps i (pour i = 0, 1, 2, …), l'individu S2i appelle l'individu S2i+1. L'appel est réussi si S2iS2i+1 ; les individus S2i et S2i+1 sont alors reliés. Lorsque S2i = S2i+1, l'appel échoue et il ne se passe rien.

On se propose dans un premier temps de répondre aux questions suivantes :

Question 2

Écrivez une classe Network fournissant

Notez qu'il n'est pas utile à ce stade de garder trace de quels individus sont reliés.

Testez votre code en exécutant le fichier Test2.java.

Déposez le fichier TD3.java.

3. Connectivité du réseau

Le but de cette partie est de répondre à des questions portant sur la connectivité du réseau, à savoir :

  1. Après combien d'appels (réussis) y a-t-il une suite d'appels qui relie le Président à la Première ministre ?
  2. Au premier appel impliquant le Président, combien y a-t-il d'individus en lien avec le Président ? Et au deuxième ?

sans oublier la question initiale :

  1. Après combien d'appels réussis 99% des individus (au moins) sont-ils reliés au Président ?

Question 3.1

Ajoutez à la classe Network une méthode public void runUntilConnected(int u, int v) qui simule des appels jusqu'à ce que les deux individus u et v soient reliés (par une suite d'appels téléphoniques, sans tenir compte de qui appelle et qui est appelé).

Testez votre code en exécutant le fichier Test3.java.

Indications

On pourra utiliser la structure de données union-find étudiée en amphi.

Question 3.2

Ajoutez à la classe Network une méthode public int getContactCount(int u) qui renvoie le nombre d'individus connectés à un individu u donné (en comptant u lui-même).

Testez votre code en exécutant le fichier Test3.java après y avoir décommenté la ligne correspondante.

Indications

Question 3.3

Le numéro de téléphone du Président est 524287, et la population compte un million d'individus. Après combien d'appels réussis au moins 1% des individus (le Président inclus) sont-ils reliés au Président ? 50% ? 99% ? 100% ? (Avant de faire le calcul, avez-vous une idée de l'ordre de grandeur du résultat attendu ?)

Réponses pour vérifier

1% — 1 840 579 appels.

50% — 1 840 579 appels.

99% — 2 325 629 appels.

100% — 8 834 905 appels.

Déposez le fichier TD3.java.

4. Bonus (facultatif)

Avant de continuer...

Si vous n'avez pas terminé le TD2, c'est le moment d'y revenir.

Question 4

Tracez la courbe de la taille du plus grand groupe d'utilisateurs reliés entre eux en fonction du nombre d'appels réussis, par exemple pour un réseau de 1000 utilisateurs.

On pourra adapter le code de l'amphi pour la manipulation de fenêtres graphiques.

Qu'observe-t-on ? (Un peu de lecture à ce sujet.)