Exercice 1 : Question préliminaire à propos d’estimation

# Alice CHOISIT secrètement un nombre a > 0
a = 10
# n est un nombre fixe et décidé par Alice et Bob avant de jouer
n = 10
# Elle tire ensuite secrètement n >= 2 nombres Xi
# indémendamment et uniformément dans l'intervalle [0, a]
X = runif(n=n, min=0, max=a)

Question 1

Je remarque que lorsque \(n\) grandit, \(M\) est plus proche de \(a\). De la même manière, lorsque \(a\) grandit, \(M\) est moins proche de \(a\).

# Calcul de M (non corrigé)
calculateM = function(a, n) {
  return(replicate(n = N, max(runif(n=n, min=0, max=a))))
}

# Espérance et variance expérimentales
Eexp = function(M) {
  return(mean(M))
}
Vexp = function(M) {
  return(Eexp(M**2) - (Eexp(M))**2)
}

# Calcul des espérances théoriques pour différentes valeurs de a et n
Eexp(calculateM(a=10, n=10)) ; Eexp(calculateM(a=10, n=100)) ; Eexp(calculateM(a=100, n=10))
## [1] 9.102567
## [1] 9.900115
## [1] 90.90509

Si on avait \(n = 1\) intuitivement on sait qu’on aurait \(E[M] = {a \over 2} = a \times {1 \over 2}\) puisqu’en faisant un tirage on tomberait en moyenne sur la moitié de \(a\), ce qui donne la formule suivante pour l’espérance de \(M\) (confirmée expérimentalement juste après) :

\[ E[M] = a \times {n \over n + 1} \]

# Espérance théorique
Eth = function(a, n) {
  return(a * (n/(n+1)))
}

# Calcul de l'espérance et de la variance théoriques de M (non corrigé)
a = 10 ; n = 10
M = calculateM(a, n)
Eexp(M) ; Eth(a, n)
## [1] 9.088699
## [1] 9.090909

On peut “corriger” \(M\) en le multipliant par \({n+1 \over n}\), ainsi \(E[M] = a\), comme montré par la simulation ci-dessous.

# Calcul de M corrigé
calculateMfix = function(a, n) {
  return(replicate(n = N, ((n+1)/n) * max(runif(n=n, min=0, max=a))))
}

# Calcul de l'espérance et de la variance théoriques de M (corrigé)
a = 10 ; n = 10
Mfix = calculateMfix(a, n)
Eexp(Mfix) ; Vexp(Mfix)
## [1] 9.997492
## [1] 0.8317815

De la même manière que pour l’espérance on trouve pour la variance (de \(M\) non corrigé) :

\[ Var[M] = {n(a^2) \over n+2} - \Big({na \over n+1}\Big)^2 \]

# Variance théorique
Vth = function(a, n) {
  return((a**2) * (n/(n+2)) - Eth(a, n)**2)
}

# Comparaison entre les variances expérimentale et théorique de M (non corrigé)
a = 10 ; n = 10
M = calculateM(a, n)
Vexp(M) ; Vth(a, n)
## [1] 0.6863243
## [1] 0.6887052

Question 2

On remarque que l’espérance de \(M'\) est bien plus proche de \(a\) que celle de \(M\) (non corrigé) : \(0.013 << 0.909\). Mais la variance de \(M'\) est bien plus grande que celle de \(M\) (non corrigé) : \(3.291 >> 0.686\). Il est difficile de choisir entre \(M'\) et \(M\) (non corrigé).

En revanche, l’espérance de \(M'\) et de \(M\) (corrigé) sont toutes deux très proches de \(a\) : \(0.0129 \simeq 0.0025\). Mais la variance de \(M'\) est bien plus grande que celle de \(M\) (corrigé) : \(3.291 >> 0.832\). Cet estimateur \(M'\) semble moins bon que le précédent \(M\) une fois corrigé.

# Calcul de M pour la question 2
calculateMQ2 = function(a, n) {
  return(replicate(n = N, (2/n) * sum(runif(n=n, min=0, max=a))))
}
a = 10 ; n = 10
M2 = calculateMQ2(a, n)

# Comparaison des espérances par rapport à a
# et comparaison des variances, pour les différents M
abs(a - Eexp(M2)) ; abs(a - Eexp(M)) ; abs(a - Eexp(Mfix))
## [1] 0.01294651
## [1] 0.9097094
## [1] 0.002508082
Vexp(M2) ; Vexp(M) ; Vexp(Mfix)
## [1] 3.291063
## [1] 0.6863243
## [1] 0.8317815

Exercice 2 : Un deuxième jeu à base de max

# Alice TIRE secrètement un nombre a > 0
# uniformément dans l'intervalle [0, 1]
a = runif(n=1, min=0, max=1)
# n est un nombre fixe et décidé par Alice et Bob avant de jouer
n = 10
# Elle tire ensuite secrètement n >= 2 nombres Xi
# indémendamment et uniformément dans l'intervalle [0, A]
X = runif(n=n, min=0, max=a)
# Elle annonce à Bob la plus grande valeur obtenue M < A
M = max(X)

Question 3

Cela me semble être une bonne stratégie à première vue, car en visant un peu au-dessus de \(M\) il est certain de ne pas perdre d’argent : dans le pire des cas il n’en perd pas et dans le meilleur des cas il gagne \(0.1 \times M\). Dans la simulation ci-dessous, Bob gagne en moyenne \(0.02\text{€}\) à chaque partie.

# Calcul du gain
calculGain = function(rM, a, M) {
  return(if (rM > a) 0 else (rM - M))
}

# Stratégie 1 avec alpha*M
strategie1 = function(M, a, alpha) {
  rM = alpha * M
  return(calculGain(rM, a, M))
}

# Calcule de la moyenne des gains avec la stratégie 1
n = 10
Gains=c()
for (i in 1:N){
  a = runif(1,0,1)
  X = runif(n,0,a)
  M = max(X)
  Gains[i] = strategie1(M, a, 1.1)
}
mean(Gains)
## [1] 0.01592938

Question 4

Le tableau généré ci-dessous correspond aux valeurs de \(P[A=a | M=m]\) avec \(a\) pour les différentes colonnes et \(m\) pour les différentes lignes. La partie au-dessus de la diagonale (en haut à droite) est nulle : en effet il est impossible d’obtenir \(M > A\), comme \(M\) est le maximum de valeurs inférieures ou égales à \(A\).

Si Alice indique à Bob que \(M=0.5\), on peut lui proposer \(0.5\) étant donné que c’est la valeur de \(a\) qui a la probabilité la plus élevée sur la ligne de \(m=0.5\).

# Calcul de M pour la question 4
calculateMQ4 = function(a,n,m) {
  A = sample(x=aList, size=1);
  X = sample(x=(0:(10*A))/10, size=n, replace=TRUE)
  M = max(X);
  return (A==a && M==m)
}

n = 3
aList = (0:10)/10
res = matrix(nrow=11, ncol=11, dimnames=list(aList, aList))

# Remplissage du tableau des gains par rapport à a et m
for (i in 0:10) {
  for(j in 0:10){
    res[i+1, j+1] = mean(replicate(N/10, calculateMQ4(i/10, n, j/10))) 
  }
}

"a pour les colonnes, m pour les lignes" ; res ; "Ligne de P[A=a | M=0.5]" ;res[6]
## [1] "a pour les colonnes, m pour les lignes"
##         0   0.1   0.2   0.3   0.4   0.5   0.6   0.7   0.8   0.9     1
## 0   0.090 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
## 0.1 0.016 0.084 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
## 0.2 0.004 0.030 0.070 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
## 0.3 0.000 0.014 0.029 0.038 0.000 0.000 0.000 0.000 0.000 0.000 0.000
## 0.4 0.001 0.007 0.017 0.016 0.047 0.000 0.000 0.000 0.000 0.000 0.000
## 0.5 0.000 0.003 0.010 0.022 0.029 0.033 0.000 0.000 0.000 0.000 0.000
## 0.6 0.001 0.004 0.007 0.007 0.013 0.016 0.037 0.000 0.000 0.000 0.000
## 0.7 0.000 0.000 0.003 0.006 0.011 0.013 0.019 0.031 0.000 0.000 0.000
## 0.8 0.000 0.001 0.004 0.003 0.009 0.010 0.009 0.022 0.025 0.000 0.000
## 0.9 0.000 0.001 0.003 0.001 0.003 0.008 0.015 0.015 0.022 0.030 0.000
## 1   0.000 0.000 0.000 0.003 0.003 0.006 0.011 0.012 0.018 0.012 0.034
## [1] "Ligne de P[A=a | M=0.5]"
## [1] 0

Question 5

Cette stratégie semble intéressante. En effet, avec la précédente (\(r(M) = 1.1M\)) si on se place dans le domaine continu on pouvait proposer une valeur absurde, par exemple \(0.99\) : \(1.1 \times 0.99 = 1.089 > 1\). Avec cette nouvelle stratégie, \(1 \geq M^{\alpha} > M\) donc on donne dans tous les cas on donne une valeur qui a du sens.

En faisant la simulation pour tous les \(\alpha\) dans \(\{0, 0.1, ..., 0.9\}\) on voit que le gain est le meilleur pour \(\alpha\) à \(0.5\) (qui d’autant plus appartient aux trois valeurs \(\{0.7, 0.5, 0.3\}\)). Je n’ai pas trouvé de meilleur \(\alpha\) en-dehors de ces trois valeurs.

# Stratégie 2 avec M^alpha
strategie2 = function(M, a, alpha) {
  rM = M ** alpha
  return(if (rM > a) 0 else (rM - M))
}

# Remplissage du tableau de la moyenne des gains pour les différents alpha
remplitGains = function(n, N) {
  alphaList = (0:9)/10
  Gains = rep(0, 10)
  for (i in 1:N) {
    a = runif(n=1, min=0, max=1)
    X = runif(n=n, min=0, max=a)
    M = max(X)
    for (j in 1:10) {
      Gains[j] = Gains[j] + strategie2(M, a, alphaList[j])
    }
  }
  for (j in 1:10) {
    Gains[j] = Gains[j]/N
  }
  return(Gains)
}

# Affichage du tableau de Gains
afficheGains = function(Gains) {
  for (j in 1:10) {
    print(paste((j-1)/10, Gains[j], sep=" "))
  }
}

afficheGains(remplitGains(n=2, N=10000))
## [1] "0 0"
## [1] "0.1 0.0241341084928574"
## [1] "0.2 0.0428576954819128"
## [1] "0.3 0.0559263604758078"
## [1] "0.4 0.0652448068047816"
## [1] "0.5 0.06699630942798"
## [1] "0.6 0.0647969659744892"
## [1] "0.7 0.056408055738983"
## [1] "0.8 0.0435189699554187"
## [1] "0.9 0.0246639585671653"
print("max de Gains") ; max(Gains)
## [1] "max de Gains"
## [1] 0.09028741

Pour \(n=10\) parmi \(\{0.7, 0.5, 0.3\}\) la meilleure valeur pour \(\alpha\) est \(0.7\) et parmi toutes les possibilités testées, la meilleure est \(0.8\). Sa valeur optimale dépend donc de \(n\).

afficheGains(remplitGains(n=10, N=10000))
## [1] "0 0"
## [1] "0.1 0.00170973189499179"
## [1] "0.2 0.00355160405520496"
## [1] "0.3 0.00553764133021913"
## [1] "0.4 0.00754576572673011"
## [1] "0.5 0.00905628543943988"
## [1] "0.6 0.0112729235914845"
## [1] "0.7 0.0133835580239238"
## [1] "0.8 0.0142452397627467"
## [1] "0.9 0.0127594032400963"
print("max de Gains") ; max(Gains)
## [1] "max de Gains"
## [1] 0.09028741

Exercice 3 : Un dernier jeu à base de max et de pile ou face

# Alice CHOISIT secrètement deux nombres 0 <= A1 < A2 <= 1
A1 = 0.5 ; A2 = 0.6
# Elle tire ensuite secrètement à Pile ou Face pour donner A1 ou A2
A = sample(x=c(A1,A2), size=1)

Question 6

Bob n’a pas tord. En répondant toujours “oui”, Bob a une chance sur deux de gagner comme il donne une des deux réponses possibles qui ont la même probabilité. On peut le vérifier en faisant une simulation comme ci-dessous.

mean(sample(x={0:1}, size=10000, replace=TRUE))
## [1] 0.4953

Question 7

On peut proposer à Bob la stratégie de répondre “oui” dans les cas où la valeur annoncée par Alice est supérieure à \(0.5\), “non” sinon. Avec cette stratégie Bob gagne à tous les coups si Alice choisit \(A_1 = 0.4\) et \(A_2 = 0.6\) car \(0.4 \leq 0.5\) et \(0.6 > 0.5\). D’ailleurs ses chances grimpent à \(0.75\) en adoptant cette stratégie, du moins c’est ce qu’on trouve expérimentalement ci-dessous.

N = 10000
Gain = 0
for (i in 1:N) {
  A1 = runif(n=1, min=0, max=1)
  A2 = runif(n=1, min=0, max=1)
  if (A2 < A1) {
    tmp = A1
    A1 = A2
    A2 = tmp
  }
  A = sample(x=c(A1, A2), size=1)
  if ((A==A1 && A<=0.5) || (A==A2 && A>0.5)) {
    Gain = Gain + 1
  }
}
Gain/N
## [1] 0.7477