Médaille
N°1 pour apprendre & réviser du collège au lycée.
Méthode de Monte-Carlo pour un calcul d'aire - Python
Découvrez, sur SchoolMouv, des milliers de contenus pédagogiques, du CP à la Terminale, rédigés par des enseignants de l’Éducation nationale.
Les élèves de troisième, de première ou de terminale bénéficient, en plus, de contenus spécifiques pour réviser efficacement leur brevet des collèges, leur bac de français ou leur baccalauréat édition 2023.
Fiche méthode

Introduction :

Dans cette fiche, nous allons voir comment donner la valeur approchée d’une aire avec… des probabilités ! Ces méthodes, qui permettent d’approcher des valeurs par des probabilités, sont dites de Monte-Carlo.
Nous verrons donc, dans un premier temps, le principe de cette méthode. Puis nous programmerons une fonction Python qui permettra de donner une approximation de l’aire sous la courbe d’une fonction, soit l’intégrale de la fonction sur l’intervalle considéré

Principe de la méthode de Monte-Carlo

Considérons pour commencer un cas évident : soit un rectangle ABCDABCD, que nous divisons en deux parties égales :

Alt mathématique terminale aire intégrale algorithme Python méthode de Monte-Carlo

Nous comprenons très facilement que, si nous prenons un point de manière aléatoire dans le rectangle ABCDABCD, la probabilité pour qu’il appartienne à AEFDAEFD est égale à :

aire(AEFD)aire(ABCD)=12\dfrac {\text{aire}(AEFD)}{\text{aire}(ABCD)}=\dfrac 12

Il en va de même pour une figure F\mathcal F quelconque inscrite dans le rectangle :

Alt mathématique terminale aire intégrale algorithme Python méthode de Monte-Carlo

La probabilité pp qu’un point pris au hasard dans ABCDABCD appartienne à F\mathcal F est égale à :

p=aire(F)aire(ABCD)p=\dfrac {\text{aire}(\mathcal F)}{\text{aire}(ABCD)}

  • On en déduit :

aire(F)=p×aire(ABCD)\text{aire}(\mathcal F) = p\times \text{aire}(ABCD)

bannière à retenir

À retenir

Voilà en quoi consiste la méthode de Monte-Carlo :

  • la figure dont on cherche l’aire A\mathcal A est incluse dans un rectangle dont on peut calculer facilement l’aire Arect\mathcal A_\text{rect} ;
  • on prend au hasard un grand nombre nn de points appartenant au rectangle, et on compte ceux qui appartiennent à la figure, pour obtenir leur nombre cc ;
  • on en déduit la fréquence f=cnf=\frac cn d’appartenance à la figure ;
  • plus on prend de points, plus la fréquence d’appartenance à la figure ff approche de la probabilité théorique (loi des grands nombres) ;
  • nous obtenons ainsi l’approximation :

Af×Arectcn×Arect\begin{aligned} \mathcal A&\approx f\times \mathcal A\text{rect} \ &\approx \dfrac cn\times \mathcal A\text{rect} \end{aligned}

Programme Python

Prérequis

Soit gg la fonction définie et continue sur [0 ;+[[0\ ;\, +\infty[ par :

g(x)=x(x23x+3)g(x)=x(x^2-3x+3)

Nous nous intéressons à l’aire A\mathcal A du domaine D\mathscr D sous la courbe représentative de gg, sur l’intervalle [0 ;1][0\ ;\, 1].

  • Nous avons, dans un repère (O ;I,J)(O\ ;\, I,\,J), avec K(1 ;1)K\,(1\ ;\, 1) :

Alt texte Légende

gg est strictement croissante et positive sur [0 ;+[[0\ ;\, +\infty[ (vous pouvez le montrer).
Et nous avons g(0)=0g(0)=0 et g(1)=1g(1)=1.

  • Cela signifie donc que la partie d’aire A\mathcal A est incluse dans le carré OIKJOIKJ.

Remarquons que cette aire est égale à :

A=01g(x)dx\mathcal A = \int_{0}^{1} g(x) \text d x

bannière attention

Attention

Dans toute cette fiche, nous travaillerons avec des fonctions positives sur l’intervalle considéré. Ainsi, le programme que nous écrirons ne permettra de travailler qu’avec de telles fonctions (mais vous pourrez aussi adapter pour que cela marche également avec des fonctions négatives sur l’intervalle).

Comme nous l’avons vu dans la première partie, nous prendrons de manière aléatoire un grand nombre de points appartenant au carré OIKJOIKJ, d’aire égale à 1 u.a.1\ \text{u.a.}

Pour chaque point, nous regarderons s’il appartient à D\mathscr D.
Pour savoir si un point M(xM ;yM)M\,(xM\ ;\, yM) appartient à D\mathscr D, il suffit de calculer f(xM)f(xM) et de comparer le résultat à yMyM.

  • En effet, logiquement :
  • si yMg(xM)yM \leq g(xM), alors MM est sous la courbe et appartient à D\mathscr D ;
  • si yM>g(xM)yM > g(xM), alors MM est au-dessus de la courbe et n’appartient pas à D\mathscr D.

Nous compterons ceux qui appartiennent à D\mathscr D et en déduirons la fréquence ff de tels points.

  • Cela nous permettra de donner une approximation de A\mathcal A :

Af×aire(OIKJ)f [car aire(OIKJ)=1 u.a.]\begin{aligned} \mathcal A&\approx f\times \text{aire}(OIKJ) \ &\approx f \footnotesize{\textcolor{#A9A9A9}{\text{ [car aire$(OIKJ)=1\ \text{u.a.}$]}}} \end{aligned}

Programme Python

Pour choisir au hasard un point, nous utiliserons la fonction random()\purple{\text{random()}} du module random\purple{\text{random}}, pour générer de manière aléatoire son abscisse et son ordonnée, comprise entre 00 et 11.

  • Nous commençons donc par importer le module :

 from random import \text{ from random import $\ast$}
  • Définissons aussi notre fonction g\purple{\text{g}}, qui prend en paramètre x\purple{\text{x}} :

def g(x):\text{def g(x):}
  • g:xx(x23x+3)g:x\mapsto x(x^2-3x+3) : nous demandons à la fonction de faire le calcul et de retourner le résultat.

return x  (x2 - 3  x + 3)\text{return x $\ast$ (x$\ast\ast\,$2 - 3 $\ast$ x + 3)}
  • Notre fonction Python aire\purple{\text{aire}} prend en paramètres :
  • la fonction f\purple{\text{f}} à laquelle on s’intéresse (dans notre cas, il s’agira donc de g\purple{\text{g}}) ;
  • le nombre n\purple{\text{n}} de points que nous voulons générer aléatoirement.

def aire(f, n):\text{def aire(f, n):}
  • Nous initialisons le compteur c\purple{\text{c}}, qui comptabilisera le nombre de points qui sont sous la courbe :

c = 0\text{c = 0}
  • Nous utilisons une boucle for\purple{\text{for}} pour générer les n\purple{\text{n}} points :

for i in range(n):\text{for i in range(n):}

Pour générer un point, nous utilisons la fonction random()\purple{\text{random()}} pour choisir aléatoirement deux nombres x\purple{\text{x}} et y\purple{\text{y}} compris entre 00 et 11, qui représenteront respectivement :

  • son abscisse,
  • et son ordonnée.

x = random()y = random()\begin{aligned} &\text{x = random()} \ &\text{y = random()} \end{aligned}
  • Comme nous l’avons dit, nous regardons alors si y\purple{\text{y}} est inférieur ou égal à l’image de x\purple{\text{x}} par la fonction f\purple{\text{f}} :

if y <= f(x):\text{if y <= f(x):}
  • Dans ce cas, nous comptabilisons le point comme étant sous la courbe :

c = c + 1\text{c = c + 1}
  • Nous allons maintenant pouvoir donner l’approximation de l’aire.
  • Comme nous l’avons dit en prérequis, elle vaut environ la fréquence, que l’on calcule en divisant le nombre de points sous la courbe par le nombre total de points :

\begin{aligned} &\text{print($^{\backprime\backprime}$L'aire sous la courbe vaut environ : $^{\prime\prime}$)} \\ &\text{print(c / n, $^{\backprime\backprime}$u.a.$^{\prime\prime}$)} \end{aligned}
bannière à retenir

À retenir

Le programme est terminé :

\begin{aligned} \textcolor{#A9A9A9}{\text{1}}&\quad\text{from random import $\ast$} \ \textcolor{#A9A9A9}{\text{2}}& \ \textcolor{#A9A9A9}{\text{3}}&\quad\text{def g(x):} \ \textcolor{#A9A9A9}{\text{4}}&\quad\qquad\text{return x $\ast$ (x$\ast\ast\,$2 - 3 $\ast$ x + 3)} \ \textcolor{#A9A9A9}{\text{5}}& \ \textcolor{#A9A9A9}{\text{6}}&\quad\text{def aire(f, n):} \ \textcolor{#A9A9A9}{\text{7}}&\quad\qquad\text{c = 0} \ \textcolor{#A9A9A9}{\text{8}}&\quad\qquad\text{for i in range(n):} \ \textcolor{#A9A9A9}{\text{9}}&\quad\qquad\qquad\text{x = random()} \ \textcolor{#A9A9A9}{\text{10}}&\quad\qquad\qquad\text{y = random()} \ \textcolor{#A9A9A9}{\text{11}}&\quad\qquad\qquad\text{if y <= f(x):} \ \textcolor{#A9A9A9}{\text{12}}&\quad\qquad\qquad\qquad\text{c = c + 1} \ \textcolor{#A9A9A9}{\text{13}}&\quad\qquad\text{print($^{\backprime\backprime}$L'aire sous la courbe vaut environ : $^{\prime\prime}$)} \ \textcolor{#A9A9A9}{\text{14}}&\quad\qquad\text{print(c / n, $^{\backprime\backprime}$u.a.$^{\prime\prime}$)} \end{aligned}
bannière exemple

Exemple

Exécutez ce programme pour la fonction g\purple{\text{g}}, avec 10610^6 points à choisir aléatoirement :

aire(g, 106)\purple{\text{aire(g, 10$\ast\ast\,$6)}}

  • Faites-le plusieurs fois et donnez une approximation de A\mathcal A.

Maintenant, calculez, comme vous l’avez appris en cours :

01x(x23x+3)dx\int_{0}^{1} x(x^2-3x+3) \text d x

  • Confrontez les résultats.
bannière astuce

Astuce

aire\purple{\text{aire}} reste valable pour toute fonction continue et positive sur [0 ;1][0\ ;\, 1], si son maximum sur cet intervalle est inférieur ou égal à 11. (Sinon, le carré OIKJOIKJ ne contiendrait pas tout le domaine dont on cherche l’aire…)

  • Vous pouvez essayer avec la fonction carrée, dont, pour confrontation, on calcule facilement l’intégrale sur [0 ;1][0\ ;\, 1] :

01x2dx=[13x3]01=13\begin{aligned} \int{0}^{1} x^2 \text d x &= \left[\dfrac 13x^3\right]0^1 \ &=\dfrac 13 \end{aligned}

Une fonction Python améliorée

Nous l’avons dit, la fonction aire\purple{\text{aire}} que nous avons programmée ne fonctionne que si on travaille sur l’intervalle [0 ;1][0\ ;\, 1] avec une fonction positive dont le maximum est inférieur ou égal à 11.

Nous allons donner ci-dessous une fonction aire2\purple{\text{aire2}}, qui sera plus générale.
Cette fonction prendra pour arguments :

  • une fonction f\purple{\text{f}}, comme dans le précédent programme ;
  • les bornes a\purple{\text{a}} et b\purple{\text{b}} de l’intervalle sur lequel on souhaite travailler (a<b\purple{\text{a}} < \purple{\text{b}}) ;
  • la « hauteur » h\purple{\text{h}} du rectangle, qui doit donc inclure l’ensemble du domaine dont on cherche l’aire :
  • on pourra déterminer h\purple{\text{h}} graphiquement, si on a une représentation graphique de f\purple{\text{f}}, on choisira alors h\purple{\text{h}} supérieur ou égal au maximum de la fonction sur [a ;b][\purple{\text{a}}\ ;\, \purple{\text{b}}] (choisir h\purple{\text{h}} le plus proche possible du maximum) ;
  • si on connaît le maximum, on pourra l’entrer directement ;
  • si on sait juste que f\purple{\text{f}} admet un maximum sur [a ;b][\purple{\text{a}}\ ;\, \purple{\text{b}}] en m\purple{\text{m}}, on peut mettre directement en argument, pour h\purple{\text{h}} : f(m)\purple{\text{f(m)}} ;
  • si f\purple{\text{f}} admet un maximum en a\purple{\text{a}} ou b\purple{\text{b}} (pour une fonction monotone sur [a ;b][\purple{\text{a}}\ ;\, \purple{\text{b}}], par exemple), on peut tout simplement mettre 0\purple{\text{0}}, le programme prendra la plus grande valeur entre f(a)\purple{\text{f(a)}} et f(b)\purple{\text{f(b)}} ;
  • le nombre n\purple{\text{n}} de points que nous souhaitons.
bannière astuce

Astuce

Pour générer un nombre aléatoire non plus compris entre 00 et 11, mais compris entre pp et qq, on utilise la fonction présente dans le module random\purple{\text{random}} :

uniform(p, q)\purple{\text{uniform(p, q)}}

bannière à retenir

À retenir

\begin{aligned} \textcolor{#A9A9A9}{\text{1}}&\quad\text{from random import $\ast$} \\ \textcolor{#A9A9A9}{\text{2}}& \\ \textcolor{#A9A9A9}{\text{3}}&\quad\text{def aire2(f, a, b, h, n):} \\ \textcolor{#A9A9A9}{\text{4}}&\quad\qquad\text{l = b - a} \\ \textcolor{#A9A9A9}{\text{5}}&\quad\qquad\text{if h == 0:} \\ \textcolor{#A9A9A9}{\text{6}}&\quad\qquad\qquad\text{h = max(f(a), f(b))} \\ \textcolor{#A9A9A9}{\text{7}}&\quad\qquad\text{r = l $\ast$ h} \\ \textcolor{#A9A9A9}{\text{8}}&\quad\qquad\text{c = 0} \\ \textcolor{#A9A9A9}{\text{9}}&\quad\qquad\text{for i in range(n):} \\ \textcolor{#A9A9A9}{\text{10}}&\quad\qquad\qquad\text{x = uniform(a, b)} \\ \textcolor{#A9A9A9}{\text{11}}&\quad\qquad\qquad\text{y = uniform(0, h)} \\ \textcolor{#A9A9A9}{\text{12}}&\quad\qquad\qquad\text{if y <= f(x):} \\ \textcolor{#A9A9A9}{\text{13}}&\quad\qquad\qquad\qquad\text{c = c + 1} \\ \textcolor{#A9A9A9}{\text{14}}&\quad\qquad\text{print($^{\backprime\backprime}$L'aire sous la courbe vaut environ :$^{\prime\prime}$)} \\ \textcolor{#A9A9A9}{\text{15}}&\quad\qquad\text{print(r $\ast$ c / n, $^{\backprime\backprime}$u.a.$^{\prime\prime}$)} \end{aligned}
bannière attention

Attention

Ce programme Python ne fonctionne toujours que pour les fonctions positives sur [a ;b][a\ ;\, b].

bannière exemple

Exemple

La fonction x4x2+3xx\mapsto 4x^2+3x est continue, positive et strictement croissante sur [0 ;+[[0\ ;\, +\infty[.

  • En vous servant du dernier programme, donnez une valeur approchée de :

I=132(4x2+3x)dxI = \int_{1}^{\frac 32} (4x^2+3x)\text d x

  • Calculez maintenant la valeur exacte de II.