DM - PS

Morgan Crociati

Polytech INFO4

set.seed(seed = 10151998)

Exercice 1

Q.1.1.

a = 100;
n = 2; #n > 2
N = 1000;

echantillons = replicate(N, runif(n, 0, a));
donnee = as.data.frame((echantillons));
donneeMax = sapply(donnee, max);

plot(donneeMax, main = paste("Maximums de N échantillons (n = ", n, ")"),
     sub = paste("Moyenne des maximums = ", toString(round(mean(donneeMax),2))),
     xlab = "Numero d'échantillons",
     ylab = "Valeur maximal de l'échantillon");

a = 100;
n = 10; #n > 2
N = 1000;

echantillons = replicate(N, runif(n, 0, a));
donnee = as.data.frame((echantillons));
donneeMax = sapply(donnee, max);

plot(donneeMax, main = paste("Maximums de N échantillons (n = ", n, ")"),
     sub = paste("Moyenne des maximums = ", toString(round(mean(donneeMax),2))),
     xlab = "Numero d'échantillons",
     ylab = "Valeur maximal de l'échantillon");

a = 100;
n = 100; #n > 2
N = 1000;
echantillons = replicate(N, runif(n, 0, a));
donnee = as.data.frame((echantillons));
donneeMax = sapply(donnee, max);

plot(donneeMax, main= paste("Maximums de N échantillons (n = ", n, ")"),
     sub = paste("Moyenne des maximums = ", toString(round(mean(donneeMax),2))),
     xlab = "Numero d'échantillons",
     ylab = "Valeur maximal de l'échantillon");

En faisant plusieurs simulation de notre problème, je remaruqe que plus n augmente plus la moyenne des maximum de des échantillon tend vers a.

esperanceEmpiriqueMax = function(N, a, n){
  #N est le nombre de simulation à réaliser
  #a est la borne supérieur de la génération uniforme
  #n est le nombre d'essaie à généré à l'aide de notre loi uniforme 
  if(n < 2)
    stop(message = "n doit être supérieur ou égal à 2");
  if(a <= 0)
    stop(message = "a doit être strictement positif");
  if(N < 1)
    stop(message = "N doit être strictement positif");
  
  echantillon = replicate(N, runif(n, 0, a));
  donnee = as.data.frame((echantillon));
  donneeMax = sapply(donnee, max);
  
  return(mean(donneeMax));
}

esperanceMax = function(a, n){
  return((1.0-1.0/(n+1.0))*a);
}

c(esperanceEmpiriqueMax(10000,100,19),esperanceMax(100, 19));
## [1] 94.89316 95.00000

Après avoir créé une fonction pour faciliter mes testes sur notre problèmes aléatoires. J’ai trouvé que plus on augmentait la taille de nos échantillons plus cela tendait vers (1 - 1/(n + 1))a. Cette formule trouvait de manière empirique me parait plutôt réaliste. Pour “corriger” M, il faut augmenter n le plus possible. Car quand on regarde dans notre formule on veut avoir (1 - 1/(n + 1))a ~ a et donc 1/(n + 1) ~ 0. Or limite de 1/(n + 1) quand n tend vers l’infinie est égal à 0.

varianceEmpiriqueMax = function(N, a, n){
  #N est le nombre de simulation à réaliser
  #a est la borne supérieur de la génération uniforme
  #n est le nombre d'essaie à généré à l'aide de notre loi uniforme 
  if(n < 2)
    stop(message = "n doit être supérieur ou égal à 2");
  if(a <= 0)
    stop(message = "a doit être strictement positif");
  if(N < 1)
    stop(message = "N doit être strictement positif");
  
  echantillon = replicate(N, runif(n, 0, a));
  donnee = as.data.frame((echantillon));
  donneeMax = sapply(donnee, max);
  return(var(donneeMax));
}

var_n = c()
var_a = c()
for(i in 2:100){
  var_n[i - 1] = varianceEmpiriqueMax(1000,100,i);
}
for(i in 1:100){
  var_a[i] = varianceEmpiriqueMax(1000,i,10);
}
plot(var_n, main= "Variance de N échantillons en fonction de n (a = 100)",
     xlab = "Valeur de n",
     ylab = "Variance");

plot(var_a, main= "Variance de N échantillons en fonction de a (n = 10)",
     xlab = "Valeur de a",
     ylab = "Variance");

Pour estimer la variance empirique j’utilise tout simplement la fonction var inclus dans le langage R permettant de calculer la variance d’un ensemble de donnée. Pour faciliter les testes, j’utilise la même forme de fonction que j’avais fait précédemment. Les deux graphes me permettent de voir que la variance augmente plus n est inférieur à la valeur de a.

Q.1.2.

a = 100;
n = 2; #n > 2
N = 1000;

echantillons = replicate(N, runif(n, 0, a));
donnee = as.data.frame((echantillons));
donneeMax = sapply(donnee, sum);
donneeMax = donneeMax *(2/n);

plot(donneeMax, main= paste("Maximums de N échantillons (n = ", n, ")"),
     sub = paste("Moyenne des maximums = ", toString(round(mean(donneeMax),2))),
     xlab = "Numero d'échantillons",
     ylab = "Valeur maximal de l'échantillon");

a = 100;
n = 10; #n > 2
N = 1000;

echantillons = replicate(N, runif(n, 0, a));
donnee = as.data.frame((echantillons));
donneeMax = sapply(donnee, sum);
donneeMax = donneeMax *(2/n);

plot(donneeMax, main= paste("Maximums de N échantillons (n = ", n, ")"),
     sub = paste("Moyenne des maximums = ", toString(round(mean(donneeMax),2))),
     xlab = "Numero d'échantillons",
     ylab = "Valeur maximal de l'échantillon");

a = 100;
n = 100; #n > 2
N = 1000;
echantillons = replicate(N, runif(n, 0, a));
donnee = as.data.frame((echantillons));
donneeMax = sapply(donnee, sum);
donneeMax = donneeMax *(2/n);
mean(donneeMax)
## [1] 100.2192
plot(donneeMax, main= paste("Maximums de N échantillons (n = ", n, ")"),
     sub = paste("Moyenne des maximums = ", toString(round(mean(donneeMax),2))),
     xlab = "Numero d'échantillons",
     ylab = "Valeur maximal de l'échantillon");

Avec cette méthode, je remarque que les résultats obtenue sont beaucoup plus proche de la réalité que ceux précédant en utilisant des valeurs pour n beaucoup plus faible. Mais je remarque aussi que la précision de la réponse n’augmente pas avec n, elle reste plutôt constante peut importe la valeur n. J’en conclue que cette méthode est meilleur pour estimer notre borne supérieur dans généralitée, tandis que la méthode précédante permet d’estimer plus précisément avec des n beaucoup plus important.

varianceEmpiriquePrime = function(N, a, n){
  #N est le nombre de simulation à réaliser
  #a est la borne supérieur de la génération uniforme
  #n est le nombre d'essaie à généré à l'aide de notre loi uniforme 
  if(n < 2)
    stop(message = "n doit être supérieur ou égal à 2");
  if(a <= 0)
    stop(message = "a doit être strictement positif");
  if(N < 1)
    stop(message = "N doit être strictement positif");
  
  echantillon = replicate(N, runif(n, 0, a));
  donnee = as.data.frame((echantillon));
  donneeMax = sapply(donnee, sum);
  donneeMax = donneeMax *(2/n);
  return(mean(donneeMax));
}

var_n = c()
var_a = c()
for(i in 2:100){
  var_n[i - 1] = varianceEmpiriquePrime(1000,100,i);
}
for(i in 1:100){
  var_a[i] = varianceEmpiriquePrime(1000,i,10);
}
plot(var_n, main= "Variance de N échantillons en fonction de n (a = 100)",
     xlab = "Valeur de n",
     ylab = "Variance");

plot(var_a, main= "Variance de N échantillons en fonction de a (n = 10)",
     xlab = "Valeur de a",
     ylab = "Variance");

On remarque que la variance de cette méthode est beaucoup plus importante en moyenne que avec la précédente. En effet la précédente méthode avait une variance forte lorsque n était grandement inférieur à notre borne supérieur, mais avec cette méthode on voit que la variance ne change pas en fonction de n mais seulement en fonction de a. Plus la borne supérieur est grande plus la variance de cette méthode sera grande. Cette méthode permet d’estimer notre borne supérieur avec exactitude (ou accuracy en anglais) mais pas avec précision (precision en anglais). C’est pourquoi je pense que cette méthode ne soit pas la plus adapté car sa variance est trop importante pour le jeu que joue Bob. Les effets de la variance sont effacé sur un grand nombre d’essaie mais sur un plus petit nombre d’essaie ils sont visibles. Pour notre jeu cette méthode n’est pas adapté car M’ peut avoir une valeur supérieur à la borne supérieur a, et donc cela rendrait impossible la partie pour Bob.

Exercice 2

Q.2.3.

Cela est une bonne stratégie car: On a M = (1 - 1/(n+1))a Et n = 10 donc M = (10/11)a Si Bob choisie de multiplier par 1.1 (ou 11/10) le résultat obtenue alors: (10/11)a(11/10) = ((1011)/(1110))*a = a Donc d’après la formule moyenne trouvé précédement sa réponse devrait être a (enfin proche de a)

C’est donc une bonne méthode car dans la théorie sa moyenne de réponse sera égal à a, sauf que si la moyenne est égal à cela signifie que des valeurs supérieur et inférieur existe pour former la moyenne. Il aurait peut être été plus malin de prendre un coefficient multiplicateur un peu moins important pour maximiser les chances de pouvoir repartir avec quelque chose. De plus si M est supérieur à environ 0.91, alors la réponse que Bob donnera sera toujours fausse car sa réponse sera supérieur à 1 (la borne supérieur de l’intervalle de a). Plus simplement si M est supérieur à 10/11*a alors la réponse donnée sera fausse.

esperanceEmpiriqueGain_n10 = function(N, a){
  #N est le nombre de simulation à réaliser
  #a est la borne supérieur de la génération uniforme
  #n est le nombre d'essaie à généré à l'aide de notre loi uniforme 
  n = 10;
  if(a < 0 || a > 1)
    stop(message = "a doit être compris entre 0 et 1");
  if(N < 1)
    stop(message = "N doit être strictement positif");
  
  echantillon = replicate(N, runif(n, 0, a));
  donnee = as.data.frame((echantillon));
  donneeMax = sapply(donnee, max);
  donneeMaxCoef = donneeMax * 1.1
  donneeMaxGain = donneeMaxCoef - donneeMax
  donneeMaxGain[donneeMaxCoef > a] = 0
  return(mean(donneeMaxGain));
}
x = c()
for(i in 0:100){
  x[i+1] = esperanceEmpiriqueGain_n10(1000, i/100);
}
plot(x = (0:100)/100, y = x, xlab = "a", ylab = "Euro (€)",
     main = "Euro moyen gagné avec 1.1M en fonction de a (n  = 10)",
     sub = paste("Euro moyen = ", toString(round(mean(x), 4)), "€"));
lines(x = (0:100)/100, y =(0:100)/100/30); #Formule trouvé empiriquement a/30

Dans cette situation l’esperance de gain de Bob augmente plus la borne supérieur augmente. Car plus les valeurs de M sont importante plus 1.1M sera important, et donc leur différence le sera aussi (augmentant les gains pour Bob).

Q.2.4.

simulationDiscrete = function(N, n){
  generate = function(a, n, m){
    A = sample(x = (0:(10))/10, size = 1);
    X = sample(x = (0:(A*10))/10, size = n, replace = T);
    M = max(X);
    return(A == a && M == m);
  }
  Matrice = matrix(nrow = 11, ncol = 11, dimnames =
                     list(c("a:0", "a:0.1", "a:0.2", "a:0.3", "a:0.4", "a:0.5", "a:0.6", "a:0.7", "a:0.8", "a:0.9", "a:1"),
                          c("m:0", "m:0.1", "m:0.2", "m:0.3", "m:0.4", "m:0.5", "m:0.6", "m:0.7", "m:0.8", "m:0.9", "m:1")));
  for(i in (0:10)){
    for(j in (0:10)){
      Matrice[i + 1, j + 1] = mean(replicate(n = N, generate(i/10, n, j/10)));
    }
  }
  return(Matrice);
}
m = simulationDiscrete(10000, 3)
m
##          m:0  m:0.1  m:0.2  m:0.3  m:0.4  m:0.5  m:0.6  m:0.7  m:0.8  m:0.9
## a:0   0.0897 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
## a:0.1 0.0114 0.0782 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
## a:0.2 0.0026 0.0255 0.0617 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
## a:0.3 0.0008 0.0103 0.0258 0.0525 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
## a:0.4 0.0009 0.0053 0.0153 0.0255 0.0458 0.0000 0.0000 0.0000 0.0000 0.0000
## a:0.5 0.0004 0.0030 0.0086 0.0177 0.0279 0.0357 0.0000 0.0000 0.0000 0.0000
## a:0.6 0.0001 0.0018 0.0048 0.0095 0.0183 0.0242 0.0329 0.0000 0.0000 0.0000
## a:0.7 0.0002 0.0006 0.0024 0.0073 0.0109 0.0143 0.0202 0.0329 0.0000 0.0000
## a:0.8 0.0001 0.0009 0.0015 0.0048 0.0077 0.0125 0.0147 0.0203 0.0279 0.0000
## a:0.9 0.0002 0.0017 0.0021 0.0030 0.0044 0.0081 0.0116 0.0175 0.0213 0.0261
## a:1   0.0000 0.0008 0.0015 0.0014 0.0052 0.0067 0.0100 0.0110 0.0154 0.0186
##          m:1
## a:0   0.0000
## a:0.1 0.0000
## a:0.2 0.0000
## a:0.3 0.0000
## a:0.4 0.0000
## a:0.5 0.0000
## a:0.6 0.0000
## a:0.7 0.0000
## a:0.8 0.0000
## a:0.9 0.0000
## a:1   0.0202
#sum(m) ~ 1

Mon intuition est de me dire que sur un cas discret il sera beaucoup plus simple d’atteindre la borne supérieur que dans un cas continue (même avec un petit n). Pour avoir une estimation de la meilleur valeur sachant que M = 0.5, on peut regarder dans la matrice fournis par le programme et prendre la plus haute valeur dans la colones ‘m:0.5’, et cela nous donne ‘a:0.5’.

Q.2.5.

Cette stratégie me semble bonne car avec elle on est sur de ne pas dépasser 1 (qui est la borne supérieur de a). Donc on ne peut renvoyer que des réponses plausibles.

esperanceEmpiriqueGain_alpha = function(N, a, n, alpha){
  #N est le nombre de simulation à réaliser
  #a est la borne supérieur de la génération uniforme
  #n est le nombre d'essaie à généré à l'aide de notre loi uniforme 
  if(n < 2)
    stop(message = "n doit être supérieur ou égal à 2");
  if(a < 0 || a > 1)
    stop(message = "a doit être compris entre 0 et 1");
  if(N < 1)
    stop(message = "N doit être strictement positif");
  if(alpha > 1 || alpha <= 0)
    stop(message = "alpha doit être inférieur à 1 (et supérieur à 0)");
  
  echantillon = replicate(N, runif(n, 0, a));
  donnee = as.data.frame((echantillon));
  donneeMax = sapply(donnee, max);
  donneeMaxAlpha = donneeMax^alpha;
  donneeMaxGain = donneeMaxAlpha - donneeMax;
  donneeMaxGain[donneeMaxAlpha > a] = 0
  return(mean(donneeMaxGain));
}
x = c()
alpha = 0.8
n = 10
for(i in 0:100){
  x[i+1] = esperanceEmpiriqueGain_alpha(1000, i/100, n, alpha);
}
plot(x = (0:100)/100, y = x, xlab = "a", ylab = "Euro (€)",
     main = paste("Euro moyen gagné avec M^alpha en fonction de a (alpha = ", toString(alpha), "& n = ",n , ")"),
     sub = paste("Euro moyen = ", toString(round(mean(x), 4)), "€"))

Pour n = 2, entre alpha = {0.7, 0.5, 0.3} la meilleur valeur est alpha = 0.5. Je pense qu’il est possible que l’optimum soit égal à une valeur un peu inférieur à 0.5, d’après les testes empiriques que j’ai réalisé mais cela pourrait simplement être du à l’aléatoire et à la fluctuation/variation des valeurs que je génére. Pour n = 10, la meilleur valeur de alpha que j’ai trouvé est 0.8.

Exercice 3

Q.3.6.

Si Bob répond toujours oui sa probabilité de gagner est égal à 0.5. Car tout le jeu se base uniquement sur le tire à Pile ou Face.

Q.3.7.

Ma stratégie serait de ne dire oui qu’a des valeurs supérieur à 0.5. Lorsque Alice choisit A1 = 0.4 et A2 = 0.6, cette stratégie fonctionne toujours peut importe ce que Alice nous dis.

generateur = function(){
  A1 = runif(n = 1, min = 0, max = 1);
  A2 = runif(n = 1, min = A1, max = 1);
  ADonnee = -1;
  if(runif(n = 1, min = 0, max = 1) < 0.5){
    ADonnee = A1;
  }
  else{
    ADonnee = A2;
  }
  
  if(ADonnee < 0.5){
    #NON
    if(ADonnee == A1){
      return(TRUE);
    }
    else{ #(ADonnee == A2)
      return(FALSE);
    }
  }
  else{
    #OUI
    if(ADonnee == A1){
      return(FALSE);
    }
    else{ #(ADonnee == A2)
      return(TRUE);
    }
  }
}

mean(replicate(100000, generateur()))
## [1] 0.67195

On voit que la probabilitée de gagner avec cette méthode est d’environ 0.67 et donc supérieur à la première méthode.