Soit f une fonction de [0, n[ sur [0, n[, on souhaite analyser les trajectoires f^n(i) pour tout n et i et ainsi détecter les cycles et les branches menant à ces cycles. Lorsque la topographie est finie, on veut aussi compter le nombre de cycles différents et le nombre de branches différentes: en moyenne, ces deux nombres doivent être 1/2 Log n et .
Définir un générateur pseudo-aléatoire de fonctions de [0, n[ sur [0, n[. Une telle fonction sera représentée par une fonction Caml enclosant un vecteur caractérisant sa trace c'est-à-dire un vecteur v tel que v.(i) = f(i).
Définir une fonction imprimant la trace d'une fonction telle que précédemment engendrée. Par exemple:
voir_fonction (engendrer_fonction 10) 10;; (0 -> 9) (1 -> 8) (2 -> 9) (3 -> 2) (4 -> 9) (5 -> 6) (6 -> 3) (7 -> 0) (8 -> 1) (9 -> 6) - : unit = ()
Comme il est enquiquinant de fournir n à voir_fonction, adopter un codage de la fonction contenant n c'est-à-dire tel que l'on puisse manipuler la fonction sous la forme d'une unique valeur. Pour cela prendre un enregistrement à deux champs (l'un pour n, l'autre pour la fonction proprement dite). Définir le type fonction et refaire alors les fonctions engendre_fonction et voir_fonction.
Définir un type topographie associant à chaque élément i de l'ensemble de départ, la branche et le cycle de sa trajectoire. Le branche est la partie initiale de la trajectoire menant au cycle, ce dernier exclus. On définira aussi le type chemin pour une suite d'éléments de [0, n[.
Définir une fonction imprimant bellement une topographie. Vous pouvez vous inspirer de ce qui suit mais vous aurez aussi intérêt à séparer les fonctionnalités et savoir indépendamment imprimer trajectoire, branche et cycle.
imprimer_topographie [| \camlbslash{}{ branche = [1]; cycle = [5;6] \camlbslash{}}; \camlbslash{}{ branche = [2;3]; cycle = [4] \camlbslash{}}; \camlbslash{}{ branche = [3]; cycle = [4] \camlbslash{}}; \camlbslash{}{ branche = []; cycle = [4] \camlbslash{}} |];; 0: 1 [5 6 ...] 1: 2 3 [4 ...] 2: 3 [4 ...] 3: [4 ...] - : unit = ()
Calculer la topographie d'une fonction. Il faut pour cela, identifier la branche et le cycle. Tâchez de partager les représentations des trajectoires.
Pour vous faciliter la tâche, on pourra écrire la fonction extraire_branche_et_cycle i deja_vus où deja_vus est la suite des points []. Si le nouveau point i appartient à deja_vus alors on identifie facilement le cycle de la branche.
On peut ensuite pour chaque point du domaine, enumérer les valeurs composant la trajectoire jusqu'à identifier branche et trajectoire. Si l'on souhaite partager les représentations c'est un peu plus complexe car on calcule en fait de multiples trajectoires en même temps. Si j=f(i) alors la trajectoire de i se déduit aisément de celle de j.
Écrire une fonction comparant deux cycles. Attention 4 5 ... est semblable à 5 4 ....
Extraire les cycles différents présents dans une topographie afin de les compter ou les imprimer.
Écrire un prédicat comparant deux branches. Il répond vrai si la première est un tronc de la seconde ou récriproquement. Par exemple,
Extraire les branches différentes dans une topographie afin de les compter ou de les imprimer.
Cartographier les fonctions c'est-à-dire compter leur nombre de cycles et de branches. Pour ce faire, on engendrera des fonctions aléatoirement, on comptera leur cycles et branches et l'on maintiendra la moyenne de ces nombres jusqu'à ce que ces compteurs n'évoluent plus (à epsilon près).