Boucles

Pour i dans la séquence de 1 au nombre total de marches, levez votre pied droit, posez-le sur la marche i puis, ramenez votre pied gauche sur la marche i.

C’est une manière de monter un escalier et c’est aussi une boucle.

Apprendre à coder une boucle, c’est une base essentielle de la programmation. Nous verrons plus tard que R nous permet, dans la plupart des cas, de nous en passer mais est très utile que vous connaissiez ces animaux-là.

Les deux formes les plus fréquentes de boucles sont les boucles for (i.e. réitérez l’opération autant de fois qu’il y a de marches) et les boucles while (i.e. réitérez l’opération jusqu’à ce que vous soyez arrivé en haut de l’escalier).

for

Dans R, un boucle for s’écrit :

for(i in séquence) {
 Faire quelque chose…
}

Le mieux, comme toujours, c’est de prendre un exemple. Imaginez que vous souhaitiez créer un vecteur x qui contient les 20 premiers membres de la suite de Fibonacci.

Une manière de faire ça consiste à créer un vecteur vide de la longueur désirée :

x <- rep(NA, 20)

Notez que NA signifie Not Available, c’est l’équivalent du #N/A d’Excel.

À ce stade, nous avons donc un vecteur vide :

> x
 [1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA

Par définition de la suite de Fibonacci, les deux premiers membres de la suite sont égaux à 1. Vous savez faire ça :

> x[1:2] <- 1
> x
 [1]  1  1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA

Maintenant, du troisième au dernier membre de x, nous voulons que chaque membre du vecteur soit égal à la somme des deux précédents.

Voici la boucle for :

for(i in 3:length(x)) {
 x[i] <- x[i-2] + x[i-1]
}

En pratique, voilà ce qu’il va se passer : i (que nous aurions pu appeler n’importe comment) va successivement prendre toutes les valeurs de 3 à length(x) et, pour chaque valeur de i, nous allons affecter au ième élément de x la somme des deux précédents (i-1 et i-2).

C’est-à-dire que pour i = 3, nous allons faire :

 x[3] <- x[3-2] + x[3-1]

Pour i = 4, nous allons faire :

 x[4] <- x[4-2] + x[4-1]

Et ainsi de suite jusqu’à i = length(x).

Exécutez la boucle et vous obtenez ceci :

> x
 [1]    1    1    2    3    5    8   13   21   34   55   89  144  233  377
[15]  610  987 1597 2584 4181 6765

Félicitation ! Vous venez de coder votre première boucle !

while

On utilise une boucle while quand on ne sait pas combien d’itérations seront nécessaires — on ne connait pas le nombre de marches de l’escalier et donc on s’arrêtera une fois arrivé en haut (i.e. quand la proposition « il reste une marche » sera fausse).

Dans R, une boucle while s’écrit :

while(test = TRUE) {
 Faire quelque chose…
}

Si par exemple vous souhaitez une suite de Fibonacci jusqu’à ce que le dernier membre soit supérieur ou égal à 1 million, vous pouvez procéder comme suit :

Initialisez la suite :

x <- c(1, 1)

Voici la boucle while :

while(tail(x, 1) < 1e6) {
 x <- c(x, sum(tail(x, 2)))
}

En pratique, tant que tail(x, 1) — c’est-à-dire que le dernier élément de x — sera inférieur à 1 million (notez la syntaxe exponentielle), on rajoute à x un nouvel élément (avec la fonction c) égal à la somme des deux précédents : sum(tail(x, 2)).

À la première itération, on a :

> x
[1] 1 1

Et comme :

> tail(x, 1) < 1e6
[1] TRUE

On va donc rajouter un élément à x :

> c(x, sum(tail(x, 2))
[1] 1 1 2

Lors de la deuxième itération :

> tail(x, 1) < 1e6
[1] TRUE

Donc :

> c(x, sum(tail(x, 2))
[1] 1 1 2 3

Et ainsi de suite jusqu’à ce que :

> tail(x, 1) < 1e6
[1] FALSE

La boucle s’arrête et on obtient :

> x
 [1]       1       1       2       3       5       8      13      21      34
[10]      55      89     144     233     377     610     987    1597    2584
[19]    4181    6765   10946   17711   28657   46368   75025  121393  196418
[28]  317811  514229  832040 1346269

Comme vous pouvez le constater, ça n’a rien de sorcier.

Sachez tout de même que si l’adresse du siège d’Apple est le 1 infinite loop (boucle infinie) à Cupertino en Californie, c’est parce que cette rue est circulaire ; c’est-à-dire que si votre objectif est d’arriver au bout de la rue, vous allez tourner indéfiniment.

C’est le risque des boucles while : si vous n’y faites pas attention, vous pourriez créer une boucle infinie et découvrir l’utilité du bouton STOP du menu. Vous êtes prévenu :

x <- c(1, 1)
while(head(x, 1) < 1e6) {
 x <- c(x, sum(tail(x, 2)))
}

Oups ! J’ai confondu head et tail : head(x, 1) sera toujours inférieur à 1e6 puisque le premier élément de x est toujours égal à 1…

Notez qu’à moins que vous ne soyez très (très) rapide pour cliquer sur STOP, vous devriez obtenir un vecteur x dont la fin ressemble à ça (R limitant le nombre d’éléments que vous pouvez afficher dans la console, vous ne verrez que la fin du vecteur) :

(…)
[32509]           Inf           Inf           Inf           Inf
[32513]           Inf           Inf           Inf           Inf
[32517]           Inf           Inf           Inf           Inf
[32521]           Inf           Inf           Inf           Inf
[32525]           Inf           Inf           Inf           Inf
[32529]           Inf           Inf           Inf           Inf
[32533]           Inf           Inf           Inf           Inf
[32537]           Inf           Inf           Inf           Inf
[32541]           Inf

Dans R, Inf c’est l’infini. Au-delà de la 1 476ème itération, on atteint des nombres si grand que R les considère infinis.

Juste pour le plaisir, vous pouvez vérifier ça avec une boucle repeat dans laquelle vous insérerez un if(condition) break pour sortir de la boucle :

x <- c(1, 1)
repeat {
 x <- c(x, sum(tail(x, 2)))
 if(tail(x, 1) == Inf) break
}

Vous observerez que :

> x
   [1]  1.000000e+00  1.000000e+00  2.000000e+00  3.000000e+00  5.000000e+00
   [6]  8.000000e+00  1.300000e+01  2.100000e+01  3.400000e+01  5.500000e+01
  [11]  8.900000e+01  1.440000e+02  2.330000e+02  3.770000e+02  6.100000e+02
  [16]  9.870000e+02  1.597000e+03
  (…)
[1471] 1.178511e+307 1.906872e+307 3.085383e+307 4.992255e+307 8.077638e+307
[1476] 1.306989e+308           Inf

Voilà, vous savez écrire des boucles.

Aucun commentaire:

Enregistrer un commentaire