Dichotomie

La dichotomie est une méthode pour encadrer une solution à une équation.

Par soucis de simplifier le problème, toutes les équations seront ramenées à la forme f(x) = 0.

dichotomie python
Maman intervalle et ses petits

Principe de la dichotomie

Avant tout, il faut s’assurer que la fonction est continue et strictement monotone (soit strictement croissante, soit strictement décroissante) sur un intervalle [a ; b], et que f(a) et f(b) n’ont pas le même signe (ce qui assure, d’après le corollaire du théorème des valeurs intermédiaires, l’existence d’une unique solution à l’équation sur l’intervalle considéré).

Considérons donc une fonction f continue et strictement monotone sur un intervalle [a;b]. La dichotomie consiste à:

  1. le milieu m de l’intervalle [a ; b] est calculé
  2. son image par la fonction f est ensuite calculée
  3. si f(a)×f(m) > 0 alors cela signifie que f(a) et f(m) ont le même signe; comme f est strictement monotone, cela signifie donc que la solution à l’équation f(x) = 0 n’est pas entre a et m. Dans ce cas, elle se trouve sur l’intervalle [m ; b]. On change donc d’intervalle et [a ; b] devient [m ; b]. On va alors au point 1 tant que l’amplitude de l’intervalle est supérieur au seuil que l’on se fixe (par exemple, 0,001).
  4. Dans le cas contraire, [a ; b] devient [a ; m] et on repart au point 1 tant que l’amplitude de l’intervalle est supérieure au seuil que l’on se fixe.

Un exemple pas à pas de la dichotomie

Prenons:$$f(x)=x^2-2.$$Plaçons-nous sur l’intervalle [0 ; 2] (donc a = 0 et b = 2). Voici un tableau des étapes des calculs (en prenant une marge de 0,1 pour finir plus vite):

abmf(a)f(b)f(m)amplitude
021-22-12
121.5-120.251
11.51.25-10.25-0.43750.5
1.251.51.375-0.43750.25-0.1093750.25
1.3751.51.4375-0.1093750.250.0664060.125
1.3751.43751.40625-0.1093750.066406-0.022460.0625

D’après ce tableau, la solution de l’équation \(x^2-2=0\) qui se trouve dans [0 ; 2] est la valeur \(\alpha\) telle que \(1,375 < \alpha < 1,4375\). On obtient ainsi un encadrement de la solution à \(10^{-1}\) près.

Calcul de l’erreur

D’après le principe de la dichotomie, les intervalles successifs sont divisés en deux à chaque étape. Ainsi, le dernier intervalle (après n étapes) aura une amplitude égale à \(\displaystyle\frac{b-a}{2^n}\). Si \(\varepsilon\) représente l’amplitude maximale désirée, alors:$$\begin{align}\frac{b-a}{2^n} \leqslant \varepsilon & \iff \frac{2^n}{b-a} \geqslant \frac{1}{\varepsilon}\\&\iff 2^n \geqslant \frac{b-a}{\varepsilon}\\&\iff n \geqslant \log_2\left(\frac{b-a}{\varepsilon}\right)\end{align}$$On dit que la vitesse de convergence est linéaire car \(|x_{n+1} – \alpha| \leqslant k|x_n – \alpha|\).

Par exemple, si [a ; b] = [0 ; 2] comme précédemment, et si nous voulons un encadrement à \(\varepsilon=10^{-5}\) près, il faudra:$$n\geqslant\log_2\left(2\times10^{5}\right)\approx17,6$$soit au minimum 18 étapes pour avoir un tel encadrement.

Je ne suis pas là pour critiquer… mais quand-même… Oserais-je dire que la dichotomie est à la résolution d’équation ce que Facebook est aux réseaux sociaux (à savoir tout pourri) ?

La dichotomie en Python

On ne va pas se mentir (on est entre amis), je n’ai pas fait les calculs des nombres qui paraissent dans le tableau précédent à la main… car je ne suis pas non plus trop con… Je sais écrire une fonction Python qui le fait pour moi alors pourquoi me priver ? D’ailleurs, la voici:

def dichotomie(f,a,b,e):
    delta = 1
    while delta > e:
        m = a + (b - a) / 2
        delta = abs(b - a)
        print("{:15} , {:15} , {:15} , {:15} , {:15} , {:15} , {:15} ".format(a,b,m,f(a),f(b),f(m),delta) )
        if f(m) == 0:
            return m
        elif f(a) * f(m)  > 0:
            a = m
        else:
            b = m
    return a, b, delta
        
print( dichotomie(lambda x: x*x - 2, 0, 2, 0.001) )

Dans la fonction dichotomie, la variable delta représente l’amplitude de l’intervalle, donc |ba|. Tant que cette amplitude est supérieure à celle donnée en argument (représentée par la variable e), on effectue les opérations:

  • le milieu de l’intervalle [a ; b] est calculé → ligne 4
  • l’amplitude (qui change à chaque fois) de l’intervalle est calculée → ligne 5
  • on affiche les différentes valeurs (parce que l’on est très curieux) → ligne 6
  • l’algorithme de dichotomie commence → lignes 7 à 12

Il est à noter aussi la syntaxe de la fonction sous la forme:

lambda x: <expression>

C’est un choix personnel… pour simplifier la saisie. Mais on aurait tout aussi bien pu écrire:

def dichotomie(a,b,e):
    delta = 1
    while delta > e:
        m = a + (b - a) / 2
        delta = abs(b - a)
        print("{:15} , {:15} , {:15} , {:15} , {:15} , {:15} , {:15} ".format(a,b,m,f(a),f(b),f(m),delta) )
        if f(m) == 0:
            return m
        elif f(a) * f(m)  > 0:
            a = m
        else:
            b = m
    return a, b, delta

def f(x):
    return x*x - 4

print( dichotomie(0, 9, 0.001) )

Notez alors que j’ai enlevé un argument à la fonction dichotomie (celui représentant la fonction f) et que j’ai écrit une autre fonction retournant l’image d’un nombre x. Ces deux syntaxes sont équivalentes.

Autres méthodes de résolution d’équations

Comme je l’ai suggéré précédemment, cette méthode n’est pas la plus efficace, mais elle a le mérite d’être simple à comprendre.

Une autre méthode, bien plus performante mais plus compliquée est la méthode de Newton.

Et n’oubliez pas que si vous avez des problèmes en mathématiques, je peux vous aider par webcam (cours ponctuels ou réguliers).