If you're seeing this message, it means we're having trouble loading external resources on our website.

Si vous avez un filtre web, veuillez vous assurer que les domaines *. kastatic.org et *. kasandbox.org sont autorisés.

Contenu principal

Les marches aléatoires

Avant d'aborder la complexité des vecteurs ou les mouvements liés à la physique, réfléchissons à ce que peut bien signifier un déplacement simple sur l'écran. Commençons avec une des simulations les plus faciles à coder et les plus connues de déplacement : la marche aléatoire.
Imaginez que vous vous tenez debout au milieu d'une poutre d'équilibre. Tous les dix secondes, vous lancez une pièce. Pile, vous faites un pas en avant. Face, vous faites un pas en arrière. C'est une marche aléatoire (un chemin parcouru en suivant une série de pas aléatoire). Descendez de cette poutre d'équilibre, et sur le sol, vous allez maintenant effectuer une marche aléatoire en deux dimensions, en lançant cette même pièce deux fois et en respectant les résultats suivants :
Lancer 1Lancer 2Résultat
PilePileUn pas en avant.
PileFaceUn pas vers la droite.
FacePileUn pas vers la gauche.
FaceFaceUn pas vers l'arrière.
Oui, ça peut sembler être un algorithme particulièrement simpliste. Néanmoins, les marches aléatoires peuvent être utilisées pour modéliser des phénomènes qui se produisent dans le monde réel, comme les mouvements des molécules dans un gaz, ou le comportement d'un joueur passant une journée dans un casino. Quant à nous, nous débutons ce sujet en étudiant l'implémentation d'une marche aléatoire en JavaScript.

L'objet Marcheur Aléatoire

Révisons tout d'abord un peu notre programmation orientée objet (POO) en construisant un objet Walker (marcheur en anglais). C'est une revue rapide. Si vous n'avez jamais travaillé avec la POO avant, envisagez de parcourir le module traitant du JavaScript orienté objet.
Un objet en JavaScript est un type de donnée qui possède des propriétés et des fonctionnalités, attachées à lui, via son prototype. Nous comptons concevoir un objet Walker qui sauvegarde des données (où il se situe sur l'écran) et qui peut effectuer certaines actions (comme se dessiner ou faire un pas).
Afin de créer des instances de Walker, il nous faut définir un objet Walker. Nous allons utiliser cet objet comme emporte-pièce à cookie, et chaque nouvelle instance de Walker correspondra à un cookie.
Commençons par créer le type d'objet Walker. Walker ne nécessite que deux données : un nombre pour sa coordonnée x et un nombre pour sa coordonnée y. Nous allons les définir dans sa fonction constructeur, en les initialisant au centre de la zone de dessin.
var Walker = function() {
    this.x = width/2;
    this.y = height/2;
};
En sus de sauvegarder ses coordonnées x et y, notre objet Walker va aussi posséder des méthodes que nous pourrons appeler à travers lui. La première va être une méthode qui permet à l'objet de s'afficher comme un point noir. Souvenez-vous qu'on ajoute des méthodes à un objet, en JavaScript, en les attachant à son prototype.
Walker.prototype.display = function() {
    stroke(0, 0, 0);
    point(this.x, this.y);
};
La seconde méthode va ordonner à l'objet Walker de faire un pas. C'est maintenant que les choses deviennent un peu plus intéressantes. Vous vous souvenez de ce sol sur lequel nous faisions nos pas aléatoires ? Eh bien, nous allons maintenant utiliser notre zone de dessin pour faire la même chose. Il y a quatre pas possibles. Un pas vers la droite peu être simulé en incrémentant x (x++); un pas vers la gauche en décrémentant x (x--); un pas vers l'avant en descendant d'un pixel (y++); et un pas vers l'arrière en montant d'un pixel (y--). Comment choisir parmi ces quatre possibilités ? Nous avons indiqué plus tôt que nous pouvions lancer deux pièces. En ProcessingJS, cependant, si on souhaite faire une sélection aléatoire dans une liste d'options, on peut tirer un nombre aléatoire en utilisant random().
Walker.prototype.walk = function() {
    var choice = floor(random(4));
};
La ligne de code ci-dessus récupère un nombre décimal aléatoire entre 0 et 4, et le convertit en un nombre entier, en utilisant la fonction floor(), afin d'obtenir 0, 1, 2 ou 3. En fait, techniquement, le nombre le plus haut ne sera jamais 4,0, mais plutôt 3,999999999 (avec autant de 9 qu'il y a de décimales permises après la virgule). Étant donné que floor() retourne le nombre entier le plus proche, plus petit ou égal, le résultat le plus haut qu'on peut obtenir est 3. Nous effectuons ensuite le pas (gauche, droite, haut ou bas) correspondant au nombre aléatoire obtenu.
Walker.prototype.walk = function() {
    var choice = floor(random(4));
    if (choice === 0) {
        this.x++;
    } else if (choice === 1) {
        this.x--;
    } else if (choice === 2) {
        this.y++;
    } else {
        this.y--;
    } 
};
Maintenant que nous avons rédigé la classe (type d'objet), il est temps de créer un véritable objet Walker dans notre programme. En supposant que nous ne souhaitions modéliser qu'une seule marche aléatoire, déclarons et initialisons une variable globale de type Walker, avec la fonction constructeur, que nous appelons avec l'opérateur new.
var w = new Walker();
Maintenant, pour faire faire réellement quelque chose au marcheur, on définit la fonction draw(), qui dit au marcheur, à chaque fois qu'elle est appelée, de faire un pas, puis de se dessiner :
draw = function() {
    w.walk();
    w.display();
};
Comme nous n’appelons pas background() dans la fonction draw, on peut voir la chemin suivi par la marche aléatoire sur notre zone de dessin

Améliorer le Marcheur Aléatoire

Nous pouvons améliorer quelque peu le marcheur aléatoire. Pour le moment, le choix des pas est limité à quatre options : haut, bas, gauche et droite. Mais un pixel, dans une fenêtre, a huit voisins accessibles, et une neuvième possibilité est de rester sur place.
Image de Nature of Code
Figure I.1
Pour implémenter un objet Walker pouvant faire un pas vers tous les pixels voisins (ou rester sur place), nous pouvons tirer un nombre entre 0 et 8 (neuf choix possibles). Cependant, un moyen plus efficace d'écrire le code serait de choisir au hasard parmi trois pas possibles, selon l'axe des abscisses (axe des x) (-1, 0 ou 1) et trois pas possibles, selon l'axe des ordonnées (axe des y).
Walker.prototype.walk = function() {
    var stepx = floor(random(3))-1;
    var stepy = floor(random(3))-1;
    this.x += stepx;
    this.y += stepy;
};
En poussant encore plus loin, nous pourrions utiliser des valeurs décimales pour x et y, choisies aléatoirement entre -1 et 1 (en espérant que notre environnement affiche effectivement quelque chose de différent pour "2,2" et "2,4", par exemple) :
Walker.prototype.walk = function() {
    var stepx = random(-1, 1);
    var stepy = random(-1, 1);
    this.x += stepx;
    this.y += stepy;
};
Toutes ces variantes de la marche aléatoire "traditionnelle" possèdent une caractéristique en commun : à chaque instant, la probabilité que le Walker fasse un pas dans une direction donnée est équivalente à la probabilité que le Walker fasse un pas, dans une des directions. En d'autres termes, si il y a quatre pas permis, il y a 1 chance sur 4 (25%), que le Marcheur en choisisse un. Avec neuf pas possibles, il y a 1 chance sur 9 (11,1%).
Cela tombe bien, c'est aussi de cette façon que la fonction random() fonctionne. Son générateur de nombre aléatoire suit ce qu'on appelle une loi de probabilité "uniforme". Nous pouvons tester cette loi en utilisant un programme, qui va dénombrer la quantité de fois qu'un nombre aléatoire est tiré, pour le représenter graphiquement, sur la hauteur, avec des barres rectangulaires :
Les barres ont-elles toutes la même hauteur, après quelques minutes d'exécution ? Probablement pas. La taille de répartition de notre exemple (le nombre de résultats aléatoires possibles) est plutôt réduite et on peut noter quelques écarts, quand certains nombres ont été tirés plus souvent. Mais avec le temps, avec un bon générateur de nombre aléatoire, tout s'égalise.
Les nombres aléatoires que nous tirons avec la fonction random() ne sont pas tout à fait aléatoires. On les dit d'ailleurs “pseudo-aléatoires”. Ils sont le résultat d'une fonction mathématique qui simule le hasard. Il est possible de déceler dans cette fonction un schéma périodique avec le temps, mais comme celui-ci est très long, elle fait pratiquement aussi bien que du pur hasard !
Dans la partie suivante, nous allons parler des différentes manières de créer des marcheurs avec "tendances", plus orientés dans certaines directions. Mais avant de se plonger là dedans, voici un défi pour vous !

Ce cours sur les "simulations de phénomènes naturels" est dérivé de l'ouvrage "The Nature of Code" de Daniel Shiffman, utilisé sous licence Creative Commons Attribution-NonCommercial 3.0 Unported License.

Vous souhaitez rejoindre la discussion ?

Vous comprenez l'anglais ? Cliquez ici pour participer à d'autres discussions sur Khan Academy en anglais.