Université d'evry Val d'essonne Année 2003-2004 SDV1 : Mathématiques 2 ème semestre TP 1 - Eléments de Réponse oor, runif, matrix, cbind, function, %%, &, %in%, t, apply, sort, which Exercice 1 (Tirage de deux dés) 1) Une réalisation d'une v.a. uniforme discrète entre 1 et 6. 2) R> n <- 10 R> tirage <- floor(runif(2*n)*6)+1 3) R> n <- 100 R> tirage <- matrix(floor(runif(2*n)*6)+1,ncol=2,nrow=n,byrow=t) Exercice 2 (Echantillons et probabilités) 1) La solution la plus ecace : R> sum((tirage[,1]+tirage[,2])<=5) Autre solution : ajouter une colonne contenant les sommes des deux lancers, et compter le nombre de fois où cette somme dépasse 5. R> tirage <- cbind(tirage,(tirage[,1]+tirage[,2])) R> sum(tirage[,3]<=5) Remarque : l'instruction tirage[,3]<-tirage[,1]+tirage[,2] aurait provoqué une erreur, car la déclaration de la matrice tirage ne prévoit que deux colonnes. 2) 5 réalisations d'une loi binomiale de paramètres n et p : la probabilité que la somme des deux nombres soit inférieure ou égale à 5. 3) Cette probabilité p est approchée par la proportion des lancers dont la somme est au plus 5. 4) On considère le tableau suivant qui donne la valeur des sommes des deux dés : Dé 1 \ Dé 2 1 2 3 4 5 6 1 2 3 4 5 6 7 2 3 4 5 6 7 8 3 4 5 6 7 8 9 4 5 6 7 8 9 10 5 6 7 8 9 10 11 6 7 8 9 10 11 12 Le nombre de sommes inférieures ou égales à 5 est 5 4/2 = 10 ; chaque somme a une probabilité de 1/(6 6) d'être tirée. On en déduit p = 10/36 soit p 0.44. 5) Plus n est grand, plus la proportion empirique est proche de la vraie valeur de la probabilité p. Ceci illustre la loi des grands nombres, car l'espérance de la proportion empirique est p. Exercice 3 (Simulations) On estime par simulations les probabilités des événements. On prendra n=10000 pour plus de précisions.
a) "obtenir au moins 12 avec 3 dés" R> n <- 10000 ; nbdes <- 3 R> tirage <- cbind(tirage,(tirage[,1]+tirage[,2]+tirage[,3])) R> sum(tirage[,4]>=12) # On obtient environ 0.27 Remarque : la fonction apply permet d'appliquer une fonction à chaque ligne ou à chaque colonne d'une matrice. Cette fonction nécessite 3 paramètres obligatoire : (a) la variable contenant la matrice (b) la dimension sur laquelle la fonction sera appliquée (ex. : 1 pour les lignes, et 2 pour les colonnes) (c) la fonction qui sera appliquée (d) (Eventuellement, d'autres paramètres qui seront passés à la fonction qui sera appliquée) Par exemple, le vecteur v de taille n contenant la somme de toutes les colonnes du tableau tirage peut être obtenus de la façon suivante : R> v <- apply(tirage, 1, FUN=sum) b) "la somme de 5 dés est divisible par 3" R> n <- 10000 ; nbdes <- 5 R> tirage <- cbind(tirage, apply(tirage, 1, FUN=sum)) R> sum(tirage[,nbdes+1]%%3==0)/n # On obtient environ 0.33 c) "la somme de 3 dés est paire" R> n <- 10000 ; nbdes <- 3 R> tirage <- cbind(tirage, apply(tirage, 1, FUN=sum)) R> sum(tirage[,nbdes+1]%%2==0)/n # On obtient environ 0.50 d) "le produit de 5 dés est divisible par 6" R> n <- 10000 ; nbdes <- 5 R> tirage <- cbind(tirage, apply(tirage, 1, FUN=prod)) R> sum(tirage[,nbdes+1]%%6==0)/n # On obtient environ 0.84 Exercice 4 (421) 1) No comment. 2) No comment. 3) On procède, comme dans l'exercice précédemment, par simulation. On prendra soin d'éviter l'utilisation des boucles for, qui ralentissent considérablement l'exécution du programme. Il est vivement conseillé de commencer par simuler une petite quantité de tirage (n=10) an de controler que chaque étape de la simulation se déroule comme attendue. Le tableau des tirages s'obtient de la façon suivante :
R> n <- 10000 ; nbdes <- 3 R> tirage <- t(apply(tirage, 1, FUN=sort, decreasing=t)) Les probabilités estimées par simulation dépendent grandement de la qualité des estimations. Il n'est pas possible de vérier exactement que les données sont bien simulées selon la loi espérée. Néanmoins, il est possible de vérier que le tirage obtenu n'est pas trop improbable (par rapport à la distribution désirée). Par exemple, la probabilité de tirer 531 qui est donnée par 3! doit être en accord avec la proportion empirique de 6 3 531 dans les simulations. Comment calculer cette proportion est donné ci dessous. 4) a) "421" R> sum(tirage[,4]==421)/n # On obtient environ 0.03 b) "mieux que 433 (sans tenir compte des gures)" R> sum(tirage[,4]>433)/n # On obtient environ 0.75 c) "une suite quelconque" R> sum((tirage[,1]==tirage[,2]+1)&(tirage[,2]==tirage[,3]+1))/n # On obtient environ 0.12 Autre solution : R> sum(tirage[,4]%in% c(654,543,432,321))/n d) "un brelan quelconque" R> sum((tirage[,1]==tirage[,2])&(tirage[,2]==tirage[,3]))/n # On obtient environ 0.03 5) Diérentes stratégies pour l'événement "421", a) On retire le dé le plus grand. On ne retirera que si l'on a pas déjà obtenu 421 au premier essai. Il y a donc deux étapes pour calculer la probabilité d'obtenir 421 en 2 coups. indices421.1 contient les numéros des lignes qui ont réussi dès le premier lancer, et n421.1 leur nombre. Rappel : tableau[-c(2,5,6),] désigne le tableau tableau privé de ses lignes 2, 5 et 6. R> indices421.1 <- which(tirage[,4]%in% c(421)) R> n421.1 <- length(indices421.1) # On tire à nouveau le dé le plus grand pour les lignes qui # n'ont pas réalisées "421" R> tirage[-indices421.1,1] <- floor(runif(n-n421.1)*6)+1 # On réordonne les colonnes. ATTENTION, il ne faut réordonner que # les 3 premières colonnes. REMARQUE : nous avons choisi ici de # conserver le resultat du premier tirage dans la colonne 4. # Ce n'est pas strictement nécessaire pour traiter l'exercice, # mais cela pourra être utile. R> tirage <- cbind(t(apply(tirage[,1:3], 1, FUN=sort, decreasing=t)),tirage[,4]) # On calcule la nouvelle valeur # ATTENTION, comme le tableau possède déjà 4 colonnes, le # deuxième tirage se trouve en colonne 5 R> sum(tirage[,5]%in% c(421))/n # On obtient environ 0.07
b) On retire les deux dés les plus grands. Après avoir généré un nouveau tableau de tirage : R> indices421.1 <- which(tirage[,4] %in% c(421)) R> n421.1 <- length(indices421.1) # On tire à nouveau les deux dés les plus grands pour les lignes qui # n'ont pas réalisées "421" R> tirage[-indices421.1,c(1,2)] <- floor(runif((n-n421.1)*2)*6)+1 # La suite est presque la même qu'à la question précédente R> tirage <- cbind(t(apply(tirage[,1:3], 1, FUN=sort, decreasing=t)),tirage[,4]) R> sum(tirage[,5]%in% c(421))/n # environ 7% c) On retire tout dé dont le résultat n'est ni "4", ni "2", ni "1". C'est plus simple dans ce cas, il sut de tirer à nouveau les valeurs qui ne sont pas 4 dans la première colonne, 2 dans la deuxième, et 1 dans la dernière. Après avoir généré un nouveau tableau de tirage : # Pour la première colonne : R> indices4.1 <- which(tirage[,1]==4) R> n4.1 <- length(indices4.1) R> tirage[-indices4.1,1] <- floor(runif(n-n4.1)*6)+1 # Pour la deuxième colonne : R> indices2.1 <- which(tirage[,2]==2) R> n2.1 <- length(indices2.1) R> tirage[-indices2.1,2] <- floor(runif(n-n2.1)*6)+1 # Pour la deuxième colonne : R> indices3.1 <- which(tirage[,3]==1) R> n3.1 <- length(indices3.1) R> tirage[-indices3.1,3] <- floor(runif(n-n3.1)*6)+1 # On place le nouveau tirage dans la colonne 5 R> tirage <- cbind(t(apply(tirage[,1:3], 1, FUN=sort,decreasing=T)),tirage[,4]) R> sum(tirage[,5]%in% c(421))/n # proba aproximative 0.085 6) Même question en autorisant le jeu "à fond" (en trois jets). On ne reprend que la dernière stratégie. Le premier tirage se trouve en colonne 4, le deuxième en colonne 5 et le dernier en colonne 6. L'avant dernière instructions cbind a été modié de façon adéquate. a) Après avoir généré un nouveau tableau de tirage : R> for (i in 1:2) { R> indices4 <- which(tirage[,1]==4) R> n4 <- length(indices4) R> tirage[-indices4,1] <- floor(runif(n-n4)*6)+1 R> indices2 <- which(tirage[,2]==2) R> n2 <- length(indices2) R> tirage[-indices2,2] <- floor(runif(n-n2)*6)+1 R> indices3 <- which(tirage[,3]==1) R> n3 <- length(indices3) R> tirage[-indices3,3] <- floor(runif(n-n3)*6)+1 R> tirage <- cbind(t(apply(tirage[,1:3], 1,FUN=sort,decreasing=T)),
tirage[,-c(1:3)]) R> } R> sum(tirage[,6]%in% c(421))/n # proba aproximative 0.165 7) A vous de jouer... Complément : Ecrire une fonction simple Toutes les questions de cet exercice nécessitait la création d'un tableau contenant les tirages des dés ; le nombre de colonnes de ce tableau est égale au nombre de dés nbdes, et le nombre de ligne est égale au nombre de lancers n. Il a donc été nécessaire de taper à chaque fois l'instruction suivante permettant de créer les données (qui devront être stockée dans une variable, par ex. tirage) : tirage <- matrix(floor(runif(nbdes*n)*6)+1,ncol=nbdes,nrow=n,byrow=t) Selon l'exercice considéré, deux paramêtres peuvent changer : le nombre de dés, et le nombre de tirage. Ecrire cette ligne de commande à chaque fois peut être fastidieux d'une part, mais surtout sujet à erreurs : a-t-on pensé à changer la valeur de n ou de nbdes par exemple? Dans un cas, comme celui-ci, il est avantageux en termes de temps, et aussi en terme de sureté du programme, de dénir une sorte de boîte noire qui prendra les deux paramètres en entrée, et donnera un jeu de données correct en sortie, sans que l'on ait plus ensuite à se soucier de la manière de créer le jeu de données. Il surait de taper par exemple tirage <- lance.des(n=1000,nbdes=5) pour obtenir dans la variable tirage 1000 lancers de 5 dés. Avant de pouvoir utiliser cette commande, il est nécessaire de dénir la fonction lance.des, c'est à dire 1. Spécier le nom de la fonction 2. Identier les paramètres en entrée (ici n et nbdes) 3. Donner la suite d'instructions R permettant de créer la sortie en fonction des paramètres d'entrée. Dans notre cas : lance.des <- function(n,nbdes) { matrix(floor(runif(nbdes*n)*6)+1,ncol=nbdes,nrow=n,byrow=t) } De la même manière que l'on dit de tirage est une matrix, on déclare de lance.des est une fonction à l'aide du mot clé \function. On spécie ensuite quelles seront (éventuellement) les paramètres en entrée de la fonction. Une fonction peut être plus complexe et contenir plusieurs lignes d'instructions. Par exemple, la fonction tire.421 dénie ci-dessous, génère un tableau de tirage de 3 dés et calcule le nombre correspondant dans la quatrième colonne. Cette fonction n'a qu'un seul paramètre en entrée (le nombre de dés est xé).
tire.421 <- function (n) { tirage <- matrix(floor(runif(3*n)*6)+1,ncol=3,nrow=n,byrow=t); tirage <- t(apply(tirage, 1, FUN=sort, decreasing=t)) tirage <- cbind(tirage,tirage[,1]*100+tirage[,2]*10+tirage[,3]) tirage } que l'on appellera ensuite : tirage <- tire.421(1000) Remarque : la variable tirage à l'intérieur de la fonction n'a rien à voir avec la variable tirage à l'extérieur de la fonction. Il ne s'agit ici que d'exemples simples de fonctions, et beaucoup de subtilités ont été omises ici. Si vous êtes amenés à écrire des fonctions en R, il vous est fortement recommandé de lire préalablement des tutoriels plus complet sur le sujets.