Les variantes de boucle

14 Mar 2026 14 Mar 2026 183 vues ESSADDOUKI Mostafa 9 min de lecture

Les variantes de boucle

Qu'est-ce qu'une variante de boucle ?

Lorsque nous concevons des algorithmes itératifs, nous devons nous assurer qu'ils se terminent effectivement. La variante de boucle est un outil fondamental pour prouver la terminaison d'une boucle.

Définition

Une variante de boucle (ou fonction de terminaison) est une expression associée à une boucle qui possède les propriétés suivantes :

  • Elle est évaluée à une valeur entière positive ou nulle.
  • Sa valeur décroît strictement à chaque itération de la boucle.
  • Elle fournit une borne inférieure garantissant que la boucle ne peut pas s'exécuter indéfiniment.

Alors que l'invariant de boucle nous aide à prouver l'exactitude partielle ("si la boucle se termine, elle produit le bon résultat"), la variante de boucle nous aide à prouver la terminaison ("la boucle se termine effectivement").

Invariant vs Variante

ConceptRôlePropriétéExemple
Invariant de boucleProuve l'exactitude du résultatPropriété vraie avant et après chaque itération\(s = 1 + 2 + \dots + (i-1)\)
Variante de boucleProuve la terminaisonValeur positive qui décroît strictement\(n - i\) (nombre d'itérations restantes)
Complémentarité

Invariant et variante sont complémentaires : l'invariant garantit que si la boucle s'arrête, le résultat est correct ; la variante garantit que la boucle s'arrête. Ensemble, ils fournissent une preuve complète d'exactitude.

  Exemple 1 : Boucle for simple

Considérons le programme de somme des entiers déjà étudié :

   
Somme des entiers Python
def somme(n):
    s = 0
    for i in range(1, n+1):
        s += i
    return s

Variante de boucle :

Variante\[ v = n - i + 1 \]

où \(i\) est le compteur de boucle courant.

Vérification des propriétés :

  • Positivité : Au début de la boucle, \(i = 1\), donc \(v = n\). Pendant la boucle, \(i \le n\), donc \(v \ge 1\). La variante est toujours positive.
  • Décroissance stricte : À chaque itération, \(i\) est incrémenté de 1, donc \(v\) diminue exactement de 1. La valeur décroît strictement.
  • Borne inférieure : Lorsque \(v\) atteint 0 (c'est-à-dire \(i = n+1\)), la boucle se termine. On a une garantie de terminaison.

  Exemple 2 : Recherche dichotomique

Considérons l'algorithme de recherche dichotomique dans un tableau trié :

   
Recherche dichotomique Python
def recherche_dichotomique(tab, x):
    debut = 0
    fin = len(tab) - 1
    
    while debut <= fin:
        milieu = (debut + fin) // 2
        if tab[milieu] == x:
            return milieu
        elif tab[milieu] < x:
            debut = milieu + 1
        else:
            fin = milieu - 1
    
    return -1

Variante de boucle :

Variante\[ v = \text{fin} - \text{debut} + 1 \]

qui représente la taille de l'intervalle de recherche courant.

Vérification des propriétés :

  • Positivité : La condition de boucle \(\text{debut} \le \text{fin}\) garantit que \(v \ge 1\).
  • Décroissance stricte: À chaque itération, on remplace l'intervalle courant par sa moitié gauche ou droite :
    • Si on cherche dans la moitié gauche : \(\text{fin}\) devient \(\text{milieu} - 1\)
    • Si on cherche dans la moitié droite : \(\text{debut}\) devient \(\text{milieu} + 1\)
    Dans les deux cas, la taille du nouvel intervalle est strictement inférieure à la taille de l'intervalle précédent (au moins divisée par 2).
  • Borne inférieure : La taille de l'intervalle ne peut pas devenir négative. Lorsqu'elle atteint 0, la condition de boucle \(\text{debut} \le \text{fin}\) devient fausse et la boucle se termine.

  Exemple 3 : Algorithme d'Euclide (PGCD)

L'algorithme d'Euclide calcule le plus grand commun diviseur de deux entiers :

   
Algorithme d'Euclide Python
def pgcd(a, b):
    while b != 0:
        r = a % b
        a = b
        b = r
    return a

Variante de boucle :

Variante\[ v = b \]

la valeur du second paramètre.

Vérification des propriétés :

  • Positivité : La condition de boucle \(b \neq 0\) garantit que \(v > 0\).
  • Décroissance stricte : À chaque itération, \(b\) devient \(a \mod b\). Par définition du modulo, \(0 \le a \mod b < b\). Donc la nouvelle valeur de \(b\) est strictement inférieure à l'ancienne.
  • Borne inférieure : \(b\) est un entier positif qui décroît strictement. Il ne peut pas décroître indéfiniment ; il finira par atteindre 0, ce qui termine la boucle.

  Exemple 4 : Parcours en profondeur (DFS) avec pile explicite

Considérons un parcours en profondeur d'un graphe utilisant une pile :

   
DFS itératif Python
def dfs_iteratif(graphe, depart):
    visites = set()
    pile = [depart]
    
    while pile:
        sommet = pile.pop()
        if sommet not in visites:
            visites.add(sommet)
            for voisin in graphe[sommet]:
                if voisin not in visites:
                    pile.append(voisin)
    return visites

Variante de boucle :

Ici, la terminaison est garantie par le fait que :

  • Chaque sommet ne peut être ajouté à la pile que s'il n'a pas déjà été visité.
  • Le nombre total de sommets est fini.
Variante\[ v = |S| - |\text{visites}| \]

où \(|S|\) est le nombre total de sommets du graphe.

Vérification des propriétés :

  • Positivité : \(v\) est positif tant qu'il reste des sommets à visiter.
  • Décroissance stricte : À chaque fois qu'on visite un nouveau sommet (ajout à l'ensemble visites), \(v\) diminue de 1. Bien que la pile puisse contenir plusieurs éléments, le nombre de sommets non visités décroît strictement à chaque nouvelle découverte.
  • Borne inférieure : \(v\) ne peut pas devenir négatif. Lorsqu'il atteint 0, tous les sommets accessibles ont été visités et la pile finira par se vider.

Cas particuliers et pièges à éviter

Attention aux boucles infinies !

Une variante de boucle mal choisie peut ne pas garantir la terminaison :

  • Variante non strictement décroissante : Si la variante peut stagner, la boucle pourrait ne pas progresser.
  • Variante non bornée inférieurement : Une variante qui peut décroître indéfiniment sans atteindre de borne ne prouve pas la terminaison.
  • Variante qui dépend de données modifiées ailleurs : Il faut s'assurer que la variante est affectée par la boucle elle-même.

  Contre-exemple : boucle infinie

   
Boucle potentiellement infinie Python
def boucle_dangereuse(n):
    i = 0
    while i < n:
        # Oubli d'incrémenter i !
        # La variante (n - i) ne décroît jamais
        print(i)

Ici, la variante \(v = n - i\) ne décroît pas car \(i\) n'est pas modifié. La boucle est infinie.

Récapitulatif des variantes étudiées

AlgorithmeVarianteJustification de la décroissance
Somme des entiers\(n - i + 1\)\(i\) augmente de 1 à chaque itération
Recherche dichotomique\(\text{fin} - \text{debut} + 1\)L'intervalle est au moins divisé par 2
Algorithme d'Euclide\(b\)\(a \mod b < b\)
DFS itératif\(|S| - |\text{visites}|\)Nombre de sommets non visités décroît

Comment trouver une variante ?

Méthodologie
  1. Identifier ce qui progresse : Cherchez une quantité qui s'approche d'une limite à chaque itération (compteur, taille d'intervalle, valeur numérique, etc.).
  2. Vérifier la positivité : Assurez-vous que cette quantité est positive dans la boucle.
  3. Vérifier la décroissance stricte : Montrez que la quantité diminue à chaque itération, quel que soit le chemin d'exécution.
  4. Établir une borne inférieure : Identifiez la valeur minimale que peut atteindre la variante (souvent 0).
  5. Vérifier le lien avec la condition d'arrêt : La variante atteint sa borne exactement quand la condition de boucle devient fausse.

Exercices d'application

  Exercice 1 : Puissance itérative

   
Calcul de puissance Python
def puissance(x, n):
    resultat = 1
    for _ in range(n):
        resultat *= x
    return resultat

Question : Quelle est la variante de boucle ? Démontrez les trois propriétés.

Solution

Variante : \(v = n - i\) où \(i\) est le compteur implicite de la boucle (nombre d'itérations déjà effectuées).

  • Positivité : Initialement \(i = 0\), donc \(v = n\). Tant que \(i < n\), \(v > 0\).
  • Décroissance : À chaque itération, \(i\) augmente de 1, donc \(v\) diminue de 1.
  • Borne : Lorsque \(v = 0\), on a effectué \(n\) itérations et la boucle se termine.

  Exercice 2 : Tri à bulles

   
Tri à bulles basique Python
def tri_bulles(tab):
    n = len(tab)
    for i in range(n-1):
        for j in range(n-1-i):
            if tab[j] > tab[j+1]:
                tab[j], tab[j+1] = tab[j+1], tab[j]
    return tab

Question : Identifiez les variantes pour les deux boucles imbriquées.

Solution

Boucle externe : \(v_1 = n - 1 - i\)

  • Positif pour \(i < n-1\)
  • Décroît de 1 à chaque itération

Boucle interne : \(v_2 = n - 1 - i - j\)

  • Positif pour \(j < n-1-i\)
  • Décroît de 1 à chaque itération de la boucle interne

Les deux boucles se terminent car leurs variantes sont des entiers positifs qui décroissent strictement.

Résumé du cours

Les variantes de boucle sont essentielles pour prouver la terminaison des algorithmes itératifs.

  • Une variante est une expression entière positive qui décroît strictement à chaque itération.
  • Elle complète l'invariant de boucle (qui prouve l'exactitude partielle) pour fournir une preuve complète d'exactitude.
  • Les variantes courantes incluent : compteurs, tailles d'intervalles, valeurs numériques, nombres d'éléments restants.
  • La décroissance stricte garantit qu'on ne peut pas boucler indéfiniment.
  • La borne inférieure (souvent 0) correspond à la condition d'arrêt de la boucle.

Comparaison finale : Invariant vs Variante

PropriétéInvariant de boucleVariante de boucle
ObjectifProuver l'exactitude du résultatProuver la terminaison
NaturePropriété logique (vrai/faux)Valeur numérique (positive)
ÉvolutionDoit rester vrai (stable)Doit décroître strictement
Condition initialeVrai avant la bouclePositive au début
Condition finaleDonne le résultat attenduAtteint sa borne inférieure
Utilisation conjointeInvariant + Variante = Preuve complète d'exactitude

Sortie
// La sortie apparaîtra ici…
Prêt · Ctrl+Entrée pour exécuter

Discussion (0)

Soyez le premier à laisser un commentaire !

Laisser un commentaire

Votre commentaire sera visible après modération.