Illustrer un point avec des statistiques

L’informatique est une science difficile : les notions sont souvent extraites des mathématiques discrètes et prouver des résultats intuitifs peut être complexe. Plutôt que de prouver par l’outil mathématique une propriété, il arrive souvent que celles-ci soient appuyées par des simulations nombreuses et bien pensées. Dans cet article, nous prenons un exemple et nous montrons comment mettre en place une démarche scientifique pour analyser le problème.

Problème

Le problème que nous considérons ici est celui de la célèbre suite de Syracuse (dont il est aussi question sur cette fiche).

Une suite de Syracuse est obtenue par récurrence de la façon suivante :

  • Le premier terme est un paramètre u0, entier strictement positif
  • Le terme ui+1 est calculé comme suit :
    • Si ui est pair alors ui+1 = ui / 2
    • Sinon ui+1 = 3ui + 1

À partir du moment où un 1 est rencontré dans cette suite, le cycle 1,4,2,1,4,2,… se répète indéfiniment.

On conjecture que pour tout choix de u0, la suite va finir par passer par 1 et donc répéter ce cycle. Nul ne sait le prouver cependant.

Nous allons chercher à analyser l’impact de u0 sur le nombre de valeurs que prend la suite avant de rencontrer la valeur 1.

Programme Python

Afin de réaliser ce travail, nous allons utiliser le programme python suivant :

Nous allons enregistrer cette fonction dans un fichier nommé syracuse.py.

Petites valeurs de u0

Dans un premier temps, nous allons regarder ce qu’il se passe avec de petites valeurs de u0. Pour cela, nous allons rendre notre programme interfaçable avec un script, c’est-à-dire rendre facile son exécution avec différents paramètres.

On utilise pour cela le module sys de Python :

Grâce à ce module, on peut maintenant lancer l’exécution de notre programme en mettant u0 en argument. Pour ce faire, nous écrivons dans un terminal :

Nous pouvons alors lire en sortie 17.

Des résultats moyennés

Nous allons demander l’exécution de notre script pour toutes les premières valeurs de u0 afin de voir comment évolue son comportement. Toujours dans un terminal, nous écrivons :

La sortie n’est pas très lisible… À la place nous préférerions avoir une courbe. Pour cela, nous allons créer un fichier au format .csv avec le résultat en fonction de u0. Modifions l’affichage du résultat dans le fichier syracuse.py :

La ligne de commande dans le terminal devient comme suit, où >> results.csv permet de rediriger la sortie du programme vers le fichier results.csv :

Pour lire ces données, nous écrivons dans le terminal :

Nous cochons que les données sont séparées par des espaces et nous pouvons alors tracer la courbe suivante :

syracuse1

Analyse du comportement

Ce que nous avons déjà obtenu est intéressant, il semble que globalement notre courbe soit croissante même s’il y a de fortes variations locales.

Afin de vérifier cette affirmation, nous proposons d’aller voir pour de plus grandes valeurs de u0 pour analyser la situation. Nous ne pouvons pas être exhaustif donc nous allons regarder ce qui se passe pour les premiers multiples de 1.000.000. Le problème est qu’étant données les variations, nous ne pouvons pas nous contenter de tracer une courbe avec un point pour chaque multiple de 1.000.000.

Ce que nous proposons alors est de regarder un grand nombre de nombres proches des multiples de 1.000.000 et d’en faire la moyenne. Pour cela, nous allons utiliser le module random de Python :

En lançant plusieurs fois les tests avec :

on remarque que les valeurs ne changent pas beaucoup, ce qui veut dire que 10.000 tests pour chaque valeur est raisonnable.

Il nous reste à calculer le résultat pour nos différentes valeurs, et à écrire le résultat dans un fichier results.csv :

Ce script prend un peu de temps, ce qui est normal vu la quantité de calculs demandés. On obtient la courbe suivante :

syracuse2

Optimisons le programme

Plutôt que de tout recalculer à chaque fois, on peut placer en mémoire les résultats déjà obtenus pour accélérer les calculs. Ceci se fait aux dépends d’une consommation mémoire beaucoup plus importante (et potentiellement trop importante pour vos ordinateurs : si votre ordinateur tombe à court de mémoire, il va utiliser le SWAP ou pire encore, il va figer. N’hésitez pas à interrompre le programme en appuyant sur CTRL+C en cas de soucis) :

On appelle le programme avec de grandes valeurs :

On obtient la courbe suivante :

Cette courbe a été obtenue grâce à l’outil Gnuplot et au script suivant :

Publié le

Laisser un commentaire