Pourquoi étudier l'algorithmique en maths ?
De quoi parle-t-on ?
L'algorithmique est la science de la résolution méthodique de problèmes. En Terminale, Python est l'outil qui permet de mettre en œ uvre les algorithmes pour résoudre des problèmes que le calcul à la main ne peut pas traiter : trouver un zéro de fonction, approcher une intégrale, simuler des expériences aléatoires, résoudre des équations différentielles numériquement.
Les 7 algorithmes du programme
L'idée directrice
Cours Python : Les bases pour débutants
Les variables : des boîtes avec une étiquette
x = 5 # la boîte x contient 5
nom = "Alice" # la boîte nom contient le texte "Alice"
pi = 3.14159 # la boîte pi contient 3.14159
x = x + 3 # on prend la valeur de x (5), on ajoute 3,
# et on remet le résultat (8) dans x
print(x) # affiche 8
Les types de données
Les opérations de calcul
Afficher et lire : print et input
x = 42
print(x) # affiche : 42
print("La valeur est", x) # affiche : La valeur est 42
print(f"x vaut {x}") # affiche : x vaut 42 (f-string)
print(f"x² = {x**2}") # affiche : x² = 1764
Les comparaisons et les booléens
La conditionnelle : if / elif / else
note = 14
if note >= 16:
print("Très bien") # exécuté si note >= 16
elif note >= 12:
print("Bien") # exécuté si 12 <= note < 16
elif note >= 10:
print("Passable") # exécuté si 10 <= note < 12
else:
print("Insuffisant") # exécuté si note < 10
# Ici, affiche "Bien" car 14 >= 12 et 14 < 16
La boucle for : répéter un nombre connu de fois
# Affiche 0, 1, 2, 3, 4 (5 valeurs, de 0 à 4)
for i in range(5):
print(i)
# Affiche 1, 2, 3, 4, 5 (de 1 à 5)
for i in range(1, 6): # ATTENTION : 6 est exclu !
print(i)
# Affiche 0, 2, 4, 6, 8 (de 0 à 8, de 2 en 2)
for i in range(0, 10, 2):
print(i)
La boucle while : répéter tant qu'une condition est vraie
# Trouver le plus petit n tel que 2^n > 1 000 000
n = 0
while 2**n <= 1000000: # tant que 2^n ≤ 1 000 000
n = n + 1 # passer au n suivant
print(n) # affiche 20 (car 2^20 = 1 048 576)
Comprendre le mécanisme :
| Tour | \(n\) | \(2^n\) |
|---|---|---|
| – | 0 | 1 \(\leqslant\) 1 000 000 \(\to\) on continue |
| 1 | 1 | 2 \(\leqslant\) 1 000 000 \(\to\) on continue |
| 2 | 2 | 4 \(\leqslant\) 1 000 000 \(\to\) on continue |
| \(\vdots\) | \(\vdots\) | \(\vdots\) |
| 19 | 19 | 524 288 \(\leqslant\) 1 000 000 \(\to\) on continue |
| 20 | 20 | 1 048 576 \(>\) 1 000 000 \(\to\) on sort ! |
Les fonctions : créer ses propres outils
# DÉFINIR la fonction (rien ne s'exécute encore)
def carre(x):
return x ** 2 # renvoie x²
# APPELER la fonction (maintenant ça s'exécute)
resultat = carre(5) # resultat = 25
print(carre(3)) # affiche 9
print(carre(7) + 1) # affiche 50
import math # OBLIGATOIRE pour utiliser les fonctions maths
def f(x):
return x**2 - 3*x + 1 # f(x) = x² - 3x + 1
def g(x):
return math.exp(x) - 2*x # g(x) = e^x - 2x
def h(x):
return math.log(x) + math.sqrt(x) # h(x) = ln(x) + √x
def derive_approx(f, x, h=1e-6):
return (f(x + h) - f(x)) / h # f'(x) ≈ [f(x+h) - f(x)] / h
# Appels :
print(f(2)) # 4 - 6 + 1 = -1
print(g(0)) # 1 - 0 = 1
print(h(1)) # 0 + 1 = 1
Les listes : stocker plusieurs valeurs
# Créer une liste
L = [10, 20, 30, 40, 50]
# Lire un élément (ATTENTION : on compte à partir de 0 !)
print(L[0]) # 10 (premier élément)
print(L[2]) # 30 (troisième élément)
print(L[-1]) # 50 (dernier élément)
print(len(L)) # 5 (nombre d'éléments)
# Ajouter un élément à la fin
L.append(60) # L = [10, 20, 30, 40, 50, 60]
# Modifier un élément
L[1] = 99 # L = [10, 99, 30, 40, 50, 60]
# Liste des carrés de 0 à 9
carres = [] # liste vide
for k in range(10):
carres.append(k**2)
print(carres) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# Même chose en UNE ligne (compréhension de liste)
carres = [k**2 for k in range(10)]
# Fonctions utiles sur les listes
print(sum(carres)) # 285 (somme)
print(max(carres)) # 81 (maximum)
print(min(carres)) # 0 (minimum)
Le module random : simuler le hasard
import random
# Nombre décimal aléatoire entre 0 (inclus) et 1 (exclu)
x = random.random() # ex: 0.7234...
# Entier aléatoire entre a et b (les deux inclus)
d = random.randint(1, 6) # simule un dé : 1, 2, 3, 4, 5 ou 6
# Choisir un élément au hasard dans une liste
couleur = random.choice(["rouge", "bleu", "vert"])
Récapitulatif : les structures à connaître au bac
Les algorithmes du programme
Algorithme de dichotomie (TVI)
def dichotomie(f, a, b, eps):
"""Retourne une valeur approchée d'un zéro de f sur [a,b]."""
while b - a > eps:
m = (a + b) / 2
if f(a) * f(m) <= 0:
b = m
else:
a = m
return (a + b) / 2
Méthode d'Euler (équations différentielles)
def euler(f, t0, y0, h, n):
"""Méthode d'Euler : n pas de taille h."""
T = [t0]
Y = [y0]
t, y = t0, y0
for k in range(n):
y = y + h * f(t, y)
t = t + h
T.append(t)
Y.append(y)
return T, Y
Sommes de Riemann (intégrales)
def riemann_gauche(f, a, b, n):
h = (b - a) / n
return h * sum(f(a + k * h) for k in range(n))
def riemann_droite(f, a, b, n):
h = (b - a) / n
return h * sum(f(a + k * h) for k in range(1, n + 1))
def riemann_milieux(f, a, b, n):
h = (b - a) / n
return h * sum(f(a + (k + 0.5) * h) for k in range(n))
Simulation aléatoire et loi des grands nombres
import random
# Pile ou Face (Bernoulli de paramètre 0.5)
def bernoulli(p):
return 1 if random.random() < p else 0
# Simuler n lancers et calculer la fréquence
def frequence(p, n):
return sum(bernoulli(p) for _ in range(n)) / n
print(frequence(0.5, 10000)) # ≈ 0.50 (LGN)
import random
import matplotlib.pyplot as plt
def loi_grands_nombres(p, n):
"""Trace la convergence de la fréquence vers p."""
X = []
S = 0
for k in range(1, n + 1):
S += bernoulli(p)
X.append(S / k)
plt.plot(X, linewidth=0.8)
plt.axhline(y=p, color='red', linestyle='--')
plt.xlabel('n')
plt.ylabel('Fréquence')
plt.title('Loi des grands nombres')
plt.show()
loi_grands_nombres(0.3, 10000)
def binomiale(n, p):
"""Simule X ~ B(n, p)."""
return sum(bernoulli(p) for _ in range(n))
# Histogramme de 10000 simulations de B(20, 0.3)
echantillon = [binomiale(20, 0.3) for _ in range(10000)]
plt.hist(echantillon, bins=range(22), density=True,
edgecolor='black', alpha=0.7)
plt.title('Histogramme B(20, 0.3)')
plt.show()
Suites récurrentes : calcul de termes et recherche de seuil
def termes_suite(f, u0, n):
"""Retourne la liste [u_0, u_1, ..., u_n]."""
U = [u0]
u = u0
for k in range(n):
u = f(u)
U.append(u)
return U
# Exemple : u_{n+1} = √(2 + u_n), u_0 = 0
import math
U = termes_suite(lambda u: math.sqrt(2 + u), 0, 20)
print(U[-1]) # ≈ 2.0 (la suite converge vers 2)
def seuil(f, u0, M):
"""Retourne le plus petit n tel que u_n > M."""
u = u0
n = 0
while u <= M:
u = f(u)
n += 1
return n
# Exemple : u_{n+1} = 1.05 * u_n (croissance 5
# Combien d'années pour dépasser 200 ?
n = seuil(lambda u: 1.05 * u, 100, 200)
print(n) # 15 (il faut 15 ans pour doubler)
Recherche d'extremum et tri
def maximum_balayage(f, a, b, n):
"""Maximum approché de f sur [a,b] avec n points."""
h = (b - a) / n
x_max = a
y_max = f(a)
for k in range(1, n + 1):
x = a + k * h
y = f(x)
if y > y_max:
x_max = x
y_max = y
return x_max, y_max
# Exemple : maximum de f(x) = x * e^(-x) sur [0, 5]
import math
xm, ym = maximum_balayage(lambda x: x * math.exp(-x), 0, 5, 10000)
print(f"Max en x = {xm:.4f}, f(x) = {ym:.4f}")
# ≈ x = 1.0000, f(x) = 0.3679 (max théorique en x = 1)
Calcul de coefficients binomiaux et triangle de Pascal
def pascal(n):
"""Retourne le triangle de Pascal jusqu'à la ligne n."""
T = [[1]]
for k in range(1, n + 1):
ligne = [1]
for j in range(1, k):
ligne.append(T[k-1][j-1] + T[k-1][j])
ligne.append(1)
T.append(ligne)
return T
# Coefficients binomiaux C(10, k)
T = pascal(10)
print(T[10]) # [1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]
import math
def binom(n, k):
"""C(n, k) = n! / (k! * (n-k)!)"""
return math.factorial(n) // (math.factorial(k) * math.factorial(n - k))
# Ou directement : math.comb(n, k) (Python 3.8+)
print(math.comb(10, 3)) # 120
Visualisation graphique
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-2, 4, 1000)
y = x**2 - 3*x + 1
plt.figure(figsize=(8, 5))
plt.plot(x, y, color='steelblue', linewidth=2, label=r'$f(x)=x^2-3x+1$')
plt.axhline(0, color='black', linewidth=0.5)
plt.axvline(0, color='black', linewidth=0.5)
plt.grid(alpha=0.3)
plt.legend(fontsize=12)
plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('Graphe de f')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
def euler_plot(f, t0, y0, h, n):
T, Y = euler(f, t0, y0, h, n)
plt.plot(T, Y, 'o-', markersize=2, label=f'Euler (h={h})')
# y' = -2y + 6, y(0) = 1
f = lambda t, y: -2*y + 6
euler_plot(f, 0, 1, 0.5, 10) # pas grossier
euler_plot(f, 0, 1, 0.1, 50) # pas moyen
euler_plot(f, 0, 1, 0.01, 500) # pas fin
# Solution exacte
t = np.linspace(0, 5, 200)
plt.plot(t, -2*np.exp(-2*t) + 3, 'r--', linewidth=2, label='Exacte')
plt.legend()
plt.title("Méthode d'Euler : effet du pas h")
plt.show()
Résumé : quel algorithme pour quel problème ?
Boîte à outils : Réflexes pour le bac
Exercices
Exercice 1 ★☆☆ : Lire un algorithme
Que retourne la fonction suivante pour n = 5 ?
def mystere(n):
S = 0
for k in range(1, n + 1):
S = S + k**2
return S
Exercice 2 ★☆☆ : Compléter un algorithme
Compléter le programme pour qu'il calcule \(n!\) (factorielle de \(n\)) :
def factorielle(n):
F = ... # à compléter
for k in range(..., ...): # à compléter
F = ... # à compléter
return F
Exercice 3 ★☆☆ : Suite récurrente
On définit \(u_0=1\) et \(u_{n+1}=\frac{u_n+3}{2}\).
Écrire un programme qui affiche les \(20\) premiers termes.
Vers quelle valeur semble converger la suite ?
Écrire un programme qui détermine le plus petit \(n\) tel que \(|u_n-3|<10^{-6}\).
Exercice 4 ★★☆ : Dichotomie
Utiliser la dichotomie pour résoudre \(\e^x=3x\) sur \([1,2]\) à \(10^{-8}\) près.
Combien d'étapes sont nécessaires ?
Adapter pour trouver \(\sqrt[3]{7}\) (zéro de \(x^3-7\) sur \([1,2]\)).
Exercice 5 ★★☆ : Méthode d'Euler
Appliquer Euler à \(y'=y\), \(y(0)=1\) avec \(h=0{,}1\) et \(n=10\) (donc \(t\in[0,1]\)). Comparer \(y_{10}\) à \(\e\).
Même question avec \(h=0{,}01\) et \(n=100\). L'approximation est-elle meilleure ?
Appliquer Euler à \(y'=-y+\sin(t)\), \(y(0)=0\) avec \(h=0{,}01\) sur \([0,10]\). Tracer la solution.
Exercice 6 ★★☆ : Sommes de Riemann
Calculer \(\int_0^1 x^3\,\mathrm{d}x\) par les sommes à gauche avec \(n=100\), \(1000\), \(10000\). Comparer à la valeur exacte \(\frac{1}{4}\).
Calculer \(\int_0^\pi\sin(x)\,\mathrm{d}x\) par la méthode des milieux. Comparer à \(2\).
Estimer \(\int_0^1\frac{1}{1+x^2}\,\mathrm{d}x\) et vérifier que c'est \(\approx\frac{\pi}{4}\).
Exercice 7 ★★☆ : Simulation de probabilités
Simuler \(10\,000\) lancers de deux dés et estimer la probabilité d'obtenir une somme égale à \(7\).
Simuler le paradoxe des anniversaires : pour \(n\) personnes, estimer par simulation la probabilité d'une coïncidence.
Simuler la marche aléatoire : un pion part de \(0\) et avance de \(+1\) ou \(-1\) (équiprobable) à chaque pas. Tracer \(5\) trajectoires sur \(1000\) pas.
Exercice 8 ★★☆ : Lecture et compréhension
Que calcule la fonction suivante ?
import math
def f(x):
return math.log(x) - 2
def algo(eps):
a, b = 1, 100
while b - a > eps:
m = (a + b) / 2
if f(a) * f(m) <= 0:
b = m
else:
a = m
return (a + b) / 2
Quelle équation résout cet algorithme ?
Que retourne
algo(0.001)? Donner la valeur exacte.
Exercice 9 ★★☆ : Seuil et suite géométrique
On place \(1000\)€ à un taux annuel de \(3\%\) (intérêts composés).
Écrire la suite \((u_n)\) du capital après \(n\) années.
Écrire un programme qui détermine le nombre d'années pour doubler le capital.
Vérifier avec la formule \(n=\frac{\ln 2}{\ln 1{,}03}\approx 23{,}4\).
Exercice 10 ★★☆ : Exécuter à la main
Exécuter à la main l'algorithme suivant et donner la valeur de S en sortie :
S = 0
u = 1
for k in range(5):
S = S + u
u = u * 2
print(S)
Exercice 11 ★★☆ : Euler et équation différentielle
On considère l'équation \(y'=-0{,}5y+2\), \(y(0)=10\).
Déterminer la solution exacte.
Appliquer Euler avec \(h=0{,}5\) et faire les 4 premières étapes à la main.
Comparer avec les valeurs exactes en \(t=0{,}5\), \(1\), \(1{,}5\), \(2\).
Exercice 12 ★★☆ : Intervalle de confiance par simulation
On ne connaît pas \(p\) (probabilité de succès d'un événement). On effectue \(n=1000\) essais et on observe \(f_n=0{,}62\).
Donner un intervalle de confiance théorique pour \(p\) au seuil \(95\%\) (Tchebychev).
Écrire un programme qui simule \(10\,000\) échantillons de taille \(1000\) avec \(p=0{,}6\) et vérifie que la fréquence tombe dans l'intervalle \([p-\frac{1}{\sqrt{20n}}\,;\,p+\frac{1}{\sqrt{20n}}]\) environ \(95\%\) du temps.
Exercice 13 ★★★ : Méthode de Monte-Carlo
Pour estimer \(\pi\) : on tire aléatoirement \(n\) points \((x,y)\) dans le carré \([0,1]^2\) et on compte ceux qui tombent dans le quart de disque \(x^2+y^2\leqslant 1\).
Expliquer pourquoi la fréquence des points dans le disque converge vers \(\frac{\pi}{4}\).
Écrire le programme. Estimer \(\pi\) pour \(n=10^4\) et \(n=10^6\).
Quelle précision attend-on pour \(n=10^6\) ? (Utiliser \(\sigma(\overline{X}_n)\approx\frac{1}{2\sqrt{n}}\).)
Exercice 14 ★★★ : Comparer Euler et solution exacte
On considère \(y'=\cos(t)-y\), \(y(0)=0\).
La solution exacte est \(y(t)=\frac{1}{2}(\sin t+\cos t-\e^{-t})\). Vérifier en dérivant.
Programmer Euler avec \(h=0{,}1\), \(h=0{,}01\), \(h=0{,}001\) sur \([0,10]\).
Tracer sur le même graphique les 3 approximations et la solution exacte.
Mesurer l'erreur maximale pour chaque \(h\). Vérifier qu'elle est proportionnelle à \(h\).
Problème : La méthode de Newton ★★★
Soit \(f:\R\to\R\) dérivable, de dérivée \(f'\). On cherche \(\alpha\) tel que \(f(\alpha)=0\).
Partie A : Le principe géométrique
Écrire l'équation de la tangente à la courbe de \(f\) au point d'abscisse \(x_n\).
Cette tangente coupe l'axe des abscisses en un point \(x_{n+1}\). Montrer que :
\[\boxed{x_{n+1}=x_n-\frac{f(x_n)}{f'(x_n)}}\]Illustrer géométriquement : à chaque étape, on remplace la courbe par sa tangente et on prend le zéro de cette tangente comme nouvelle approximation.
Partie B : Programmation
Écrire une fonction Python
newton(f, df, x0, eps, max_iter)qui implémente la méthode de Newton.Appliquer à \(f(x)=x^2-2\) (donc \(f'(x)=2x\)) avec \(x_0=1\). Combien d'itérations pour atteindre \(10^{-15}\) ?
Comparer avec la dichotomie : combien d'itérations faut-il en dichotomie pour la même précision ?
Partie C : Convergence
On note \(e_n=x_n-\alpha\) l'erreur à l'étape \(n\). En utilisant un développement de Taylor de \(f\) autour de \(\alpha\), montrer que :
\[e_{n+1}\approx\frac{f''(\alpha)}{2f'(\alpha)}\cdot e_n^2\]Que signifie \(e_{n+1}\approx C\cdot e_n^2\) ? Expliquer pourquoi Newton est quadratiquement convergente : le nombre de décimales correctes double à chaque étape.
Pour \(f(x)=x^2-2\) et \(x_0=1\), calculer \(x_1\), \(x_2\), \(x_3\), \(x_4\) et compter les décimales correctes de \(\sqrt{2}\).
Partie D : Limites de la méthode
Que se passe-t-il si \(f'(x_n)=0\) ? Donner un exemple concret.
Tester Newton sur \(f(x)=x^3-2x+2\) avec \(x_0=0\). Que constate-t-on ? (La méthode peut ne pas converger si \(x_0\) est mal choisi.)
Proposer une stratégie hybride : utiliser la dichotomie pour s'approcher du zéro, puis Newton pour affiner.
Corrigés détaillés
Exercice 1
On trace le tableau d'exécution pour \(n=5\) :
| \(k\) | \(k^2\) | \(S\) |
|---|---|---|
| – | – | 0 |
| 1 | 1 | 1 |
| 2 | 4 | 5 |
| 3 | 9 | 14 |
| 4 | 16 | 30 |
| 5 | 25 | 55 |
La fonction retourne \(S=1^2+2^2+3^2+4^2+5^2=\boxed{55}\).
En général, mystere(n) retourne \(\sum_{k=1}^n k^2=\frac{n(n+1)(2n+1)}{6}\).
Exercice 2
def factorielle(n):
F = 1
for k in range(1, n + 1):
F = F * k
return F
\(F\) commence à \(1\) (élément neutre de la multiplication) et k va de \(1\) à \(n\).
Exercice 3
a) et b) :
u = 1
for n in range(20):
print(f"u_{n} = {u:.10f}")
u = (u + 3) / 2
On observe que \(u_n\to 3\). Vérification : le point fixe de \(f(x)=\frac{x+3}{2}\) est \(\ell=\frac{\ell+3}{2}\Rightarrow\ell=3\).
c) :
u = 1
n = 0
while abs(u - 3) >= 1e-6:
u = (u + 3) / 2
n += 1
print(n) # 21
Il faut \(n=21\) étapes. En effet, \(u_n-3=-2\cdot\bigl(\frac{1}{2}\bigr)^n\), donc \(|u_n-3|<10^{-6}\iff 2\cdot 2^{-n}<10^{-6}\iff n>\frac{\ln(2\times 10^6)}{\ln 2}\approx 20{,}9\).
Exercice 4
a) On cherche le zéro de \(f(x)=\e^x-3x\) sur \([1,2]\).
\(f(1)=\e-3\approx -0{,}282<0\) et \(f(2)=\e^2-6\approx 1{,}389>0\).
import math
def f(x):
return math.exp(x) - 3*x
resultat = dichotomie(f, 1, 2, 1e-8)
print(resultat) # ≈ 1.51213455
b) Nombre d'étapes : \(n\geqslant\frac{\ln(1/10^{-8})}{\ln 2}=\frac{8\ln 10}{\ln 2}\approx 26{,}6\), donc \(27\) étapes.
c) Zéro de \(g(x)=x^3-7\) sur \([1,2]\) : \(g(1)=-6<0\), \(g(2)=1>0\).
resultat = dichotomie(lambda x: x**3 - 7, 1, 2, 1e-8)
print(resultat) # ≈ 1.91293118
Exercice 5
a) \(y'=y\), \(y(0)=1\), solution exacte \(y(t)=\e^t\).
Euler avec \(h=0{,}1\) : \(y_{k+1}=y_k+0{,}1\cdot y_k=1{,}1\cdot y_k\). Donc \(y_k=1{,}1^k\).
\(y_{10}=1{,}1^{10}\approx 2{,}5937\). Valeur exacte : \(\e\approx 2{,}7183\). Erreur \(\approx 4{,}6\%\).
b) Avec \(h=0{,}01\) : \(y_{100}=1{,}01^{100}\approx 2{,}7048\). Erreur \(\approx 0{,}5\%\). Oui, bien meilleure.
c)
import math
T, Y = euler(lambda t, y: -y + math.sin(t), 0, 0, 0.01, 1000)
plt.plot(T, Y)
plt.title("y' = -y + sin(t)")
plt.show()
Exercice 6
a) \(\int_0^1 x^3\,\mathrm{d}x=\frac{1}{4}=0{,}25\).
| \(n\) | Somme à gauche | Erreur |
|---|---|---|
| \(100\) | \(0{,}245025\) | \(5\times 10^{-3}\) |
| \(1000\) | \(0{,}249500\) | \(5\times 10^{-4}\) |
| \(10000\) | \(0{,}249950\) | \(5\times 10^{-5}\) |
L'erreur diminue comme \(\frac{1}{n}\) (comme prévu).
b) \(\int_0^\pi\sin(x)\,\mathrm{d}x=2\). Milieux avec \(n=10000\) : \(\approx 2{,}0000000\) (erreur \(<10^{-8}\)). La méthode des milieux est bien meilleure (erreur en \(\frac{1}{n^2}\)).
c) \(\int_0^1\frac{1}{1+x^2}\,\mathrm{d}x=\arctan(1)=\frac{\pi}{4}\approx 0{,}7854\). Vérifié.
Exercice 7
a)
import random
compteur = 0
N = 10000
for _ in range(N):
d1 = random.randint(1, 6)
d2 = random.randint(1, 6)
if d1 + d2 == 7:
compteur += 1
print(compteur / N) # ≈ 0.167 (théorique : 6/36 = 1/6)
b)
def anniversaire_simulation(n, N=10000):
compteur = 0
for _ in range(N):
dates = set()
collision = False
for _ in range(n):
d = random.randint(1, 365)
if d in dates:
collision = True
break
dates.add(d)
if collision:
compteur += 1
return compteur / N
print(anniversaire_simulation(23)) # ≈ 0.507
c)
for _ in range(5):
positions = [0]
x = 0
for _ in range(1000):
x += random.choice([-1, 1])
positions.append(x)
plt.plot(positions, linewidth=0.5)
plt.title("5 marches aléatoires")
plt.show()
Exercice 8
a) \(f(x)=\ln(x)-2\). L'algorithme cherche le zéro de \(f\), c'est-à-dire la solution de \(\ln(x)=2\), soit \(x=\e^2\).
b) algo(0.001) retourne une valeur approchée de \(\e^2\approx 7{,}389\), à \(0{,}001\) près.
Exercice 9
a) \(u_0=1000\) et \(u_{n+1}=1{,}03\cdot u_n\). Donc \(u_n=1000\times 1{,}03^n\).
b)
u = 1000
n = 0
while u <= 2000:
u = 1.03 * u
n += 1
print(n) # 24
Il faut \(24\) années pour que le capital dépasse \(2000\)€.
c) \(1{,}03^n>2\iff n>\frac{\ln 2}{\ln 1{,}03}\approx 23{,}45\). Donc \(n=24\), cohérent.
Exercice 10
Tableau d'exécution :
| \(k\) | \(S\) (avant) | \(u\) (avant) | \(S\) (après) |
|---|---|---|---|
| 0 | 0 | 1 | 1 |
| 1 | 1 | 2 | 3 |
| 2 | 3 | 4 | 7 |
| 3 | 7 | 8 | 15 |
| 4 | 15 | 16 | 31 |
\(S=1+2+4+8+16=\boxed{31}=2^5-1\).
En général, cet algorithme calcule \(\sum_{k=0}^{n-1}2^k=2^n-1\).
Exercice 11
a) \(y'=-0{,}5y+2\) est de la forme \(y'=ay+b\) avec \(a=-0{,}5\), \(b=2\). Solution générale : \(y(t)=C\e^{-0{,}5t}+4\). Avec \(y(0)=10\) : \(C=6\), donc \(y(t)=6\e^{-0{,}5t}+4\).
b) Euler avec \(h=0{,}5\) :
\(y_0=10\).
\(y_1=10+0{,}5\times(-0{,}5\times 10+2)=10+0{,}5\times(-3)=8{,}5\).
\(y_2=8{,}5+0{,}5\times(-0{,}5\times 8{,}5+2)=8{,}5+0{,}5\times(-2{,}25)=7{,}375\).
\(y_3=7{,}375+0{,}5\times(-0{,}5\times 7{,}375+2)=7{,}375+0{,}5\times(-1{,}6875)=6{,}531\).
\(y_4=6{,}531+0{,}5\times(-0{,}5\times 6{,}531+2)=6{,}531+0{,}5\times(-1{,}266)=5{,}898\).
c) Comparaison :
| \(t\) | Euler (\(h=0{,}5\)) | Exacte | Erreur |
|---|---|---|---|
| \(0{,}5\) | \(8{,}500\) | \(8{,}680\) | \(2{,}1\%\) |
| \(1{,}0\) | \(7{,}375\) | \(7{,}639\) | \(3{,}5\%\) |
| \(1{,}5\) | \(6{,}531\) | \(6{,}804\) | \(4{,}0\%\) |
| \(2{,}0\) | \(5{,}898\) | \(6{,}207\) | \(5{,}0\%\) |
Exercice 12
a) Tchebychev : \(p\in\bigl[f_n-\frac{1}{\sqrt{20n}}\,;\,f_n+\frac{1}{\sqrt{20n}}\bigr]\).
Avec \(n=1000\) : \(\frac{1}{\sqrt{20\times 1000}}=\frac{1}{\sqrt{20000}}\approx 0{,}00707\).
IC \(95\%\) : \(p\in[0{,}62-0{,}007\,;\,0{,}62+0{,}007]=[0{,}613\,;\,0{,}627]\).
b)
import random
p = 0.6
n = 1000
marge = 1 / (20 * n)**0.5
compteur = 0
for _ in range(10000):
fn = sum(1 for _ in range(n) if random.random() < p) / n
if p - marge <= fn <= p + marge:
compteur += 1
print(compteur / 10000) # ≈ 0.65 (bien au-dessus de 95
La borne de Tchebychev est très pessimiste : l'intervalle est plus fiable que \(95\%\) en pratique (par le TCL, c'est plutôt \(\approx 99{,}8\%\)).
Exercice 13
a) L'aire du quart de disque est \(\frac{\pi}{4}\), l'aire du carré est \(1\). Un point aléatoire uniforme dans \([0,1]^2\) tombe dans le quart de disque avec probabilité \(\frac{\pi}{4}\). Par la LGN, la fréquence converge vers \(\frac{\pi}{4}\).
b)
import random
def monte_carlo_pi(n):
compteur = 0
for _ in range(n):
x = random.random()
y = random.random()
if x**2 + y**2 <= 1:
compteur += 1
return 4 * compteur / n
print(monte_carlo_pi(10**4)) # ≈ 3.14 (2 décimales)
print(monte_carlo_pi(10**6)) # ≈ 3.1416 (3-4 décimales)
c) \(\sigma(\overline{X}_n)\approx\frac{1}{2\sqrt{n}}\). Pour \(n=10^6\) : \(\sigma\approx\frac{1}{2000}=0{,}0005\). L'erreur sur \(\pi\approx 4\sigma\approx 0{,}002\), soit \(\approx 3\) décimales. Monte-Carlo est simple mais lent (précision en \(\frac{1}{\sqrt{n}}\)).
Exercice 14
a) \(y(t)=\frac{1}{2}(\sin t+\cos t-\e^{-t})\).
\(y'(t)=\frac{1}{2}(\cos t-\sin t+\e^{-t})\).
\(\cos t-y(t)=\cos t-\frac{1}{2}\sin t-\frac{1}{2}\cos t+\frac{1}{2}\e^{-t}=\frac{1}{2}\cos t-\frac{1}{2}\sin t+\frac{1}{2}\e^{-t}=y'(t)\). ✓
\(y(0)=\frac{1}{2}(0+1-1)=0\). ✓
b)–c)
import math, numpy as np, matplotlib.pyplot as plt
for h in [0.1, 0.01, 0.001]:
n = int(10 / h)
T, Y = euler(lambda t, y: math.cos(t) - y, 0, 0, h, n)
plt.plot(T, Y, label=f'h={h}')
t = np.linspace(0, 10, 1000)
y_exact = 0.5 * (np.sin(t) + np.cos(t) - np.exp(-t))
plt.plot(t, y_exact, 'k--', linewidth=2, label='Exacte')
plt.legend()
plt.show()
d) Erreur maximale :
| \(h\) | Erreur max |
|---|---|
| \(0{,}1\) | \(\approx 0{,}048\) |
| \(0{,}01\) | \(\approx 0{,}0048\) |
| \(0{,}001\) | \(\approx 0{,}00048\) |
L'erreur est bien proportionnelle à \(h\) : diviser \(h\) par \(10\) divise l'erreur par \(10\). C'est la convergence d'ordre 1 d'Euler.
Corrigé du problème : La méthode de Newton
Partie A : Le principe géométrique
1. Tangente en \((x_n, f(x_n))\) : \(y=f(x_n)+f'(x_n)(x-x_n)\).
2. Cette tangente coupe l'axe \(y=0\) :
\(0=f(x_n)+f'(x_n)(x_{n+1}-x_n)\quad\Longrightarrow\quad x_{n+1}-x_n=-\frac{f(x_n)}{f'(x_n)}\) \(\boxed{x_{n+1}=x_n-\frac{f(x_n)}{f'(x_n)}}\)3. Géométriquement : on suit la tangente jusqu'à l'axe des abscisses. Si \(f\) est convexe et le point initial bien choisi, les approximations convergent rapidement vers le zéro.
Partie B : Programmation
4.
def newton(f, df, x0, eps, max_iter=100):
x = x0
for i in range(max_iter):
fx = f(x)
if abs(fx) < eps:
return x, i
dfx = df(x)
if dfx == 0:
return None, i # tangente horizontale
x = x - fx / dfx
return x, max_iter
5. \(f(x)=x^2-2\), \(f'(x)=2x\), \(x_0=1\) :
resultat, nb = newton(lambda x: x**2 - 2, lambda x: 2*x, 1, 1e-15)
print(f"x = {resultat}, itérations = {nb}")
# x = 1.4142135623730951, itérations = 5
Seulement 5 itérations pour \(15\) décimales correctes !
6. En dichotomie sur \([1,2]\) : \(n\geqslant\frac{\ln(1/10^{-15})}{\ln 2}\approx 50\) itérations.
Rapport : Newton \(5\) vs. dichotomie \(50\). Newton est environ \(10\) fois plus rapide.
Partie C : Convergence
7. Taylor de \(f\) autour de \(\alpha\) (\(f(\alpha)=0\)) :
\(f(x_n)=f(\alpha)+f'(\alpha)e_n+\frac{f''(\alpha)}{2}e_n^2+\cdots=f'(\alpha)e_n+\frac{f''(\alpha)}{2}e_n^2+\cdots\)\(f'(x_n)=f'(\alpha)+f''(\alpha)e_n+\cdots\approx f'(\alpha)\) (au premier ordre).
\(e_{n+1}=x_{n+1}-\alpha=x_n-\frac{f(x_n)}{f'(x_n)}-\alpha=e_n-\frac{f'(\alpha)e_n+\frac{f''(\alpha)}{2}e_n^2}{f'(\alpha)+\cdots}\) \(\approx e_n-e_n-\frac{f''(\alpha)}{2f'(\alpha)}e_n^2=\frac{f''(\alpha)}{2f'(\alpha)}\cdot e_n^2\). \(\square\)8. \(e_{n+1}\approx C\cdot e_n^2\) signifie que l'erreur est mise au carré à chaque étape. Si \(e_n\approx 10^{-k}\), alors \(e_{n+1}\approx C\cdot 10^{-2k}\). Le nombre de décimales correctes double à chaque itération :
\(1\to 2\to 4\to 8\to 16\) décimales en 5 itérations.
9. Pour \(f(x)=x^2-2\), \(f'(x)=2x\) :
\(x_{n+1}=x_n-\frac{x_n^2-2}{2x_n}=\frac{x_n^2+2}{2x_n}=\frac{1}{2}\bigl(x_n+\frac{2}{x_n}\bigr)\)(C'est la méthode de Héron / babylonienne !)
\(x_0=1\). \(x_1=\frac{1}{2}(1+2)=1{,}5\). \(x_2=\frac{1}{2}(1{,}5+\frac{2}{1{,}5})=\frac{1}{2}\times\frac{17}{6}\approx 1{,}41\underline{6667}\).
\(x_3\approx 1{,}41421\underline{5686}\). \(x_4\approx 1{,}41421356237\underline{3095}\).
\(\sqrt{2}\approx 1{,}41421356237\underline{3099}\). Après \(4\) itérations : \(13\) décimales correctes.
Partie D : Limites de la méthode
10. Si \(f'(x_n)=0\), la tangente est horizontale et ne coupe pas l'axe des \(x\) : division par zéro. Exemple : \(f(x)=x^2\) près de \(0\), \(f'(0)=0\).
11. \(f(x)=x^3-2x+2\), \(x_0=0\). \(f(0)=2\), \(f'(0)=-2\).
\(x_1=0-\frac{2}{-2}=1\). \(f(1)=1\), \(f'(1)=1\).
\(x_2=1-\frac{1}{1}=0\). On revient à \(x_0=0\) ! La méthode oscille indéfiniment et ne converge pas. (Le zéro réel est \(\approx -1{,}77\), trop loin de \(x_0\).)
12. Stratégie hybride :
def newton_hybride(f, df, a, b, eps):
"""Dichotomie pour se rapprocher, puis Newton pour affiner."""
# Phase 1 : dichotomie grossière
x = dichotomie(f, a, b, 0.1)
# Phase 2 : Newton pour la précision
resultat, _ = newton(f, df, x, eps)
return resultat
La dichotomie garantit la convergence (robustesse), Newton accélère la précision (rapidité). C'est la stratégie utilisée dans les logiciels professionnels.
Maîtrise du chapitre
Validation contrôlée
Réponds aux QCM, sélectionne les bonnes propositions ou remets les étapes dans l'ordre. Le site vérifie chaque réponse avant d'ouvrir la balise suivante.