Section courante

A propos

Section administrative du site

Principe des tiroirs

Le principe des tiroirs, également appelé principe de Dirichlet, principe des cases ou pigeonhole principle en anglais, est une méthode élémentaire de dénombrement permettant de démontrer qu'une répétition, une collision ou une concentration minimale doit nécessairement se produire.

Dans sa forme la plus simple, ce principe affirme que si l'on place davantage d'objets que de tiroirs, au moins un tiroir doit contenir plusieurs objets. Il ne précise pas quel tiroir sera concerné ni quels objets s'y retrouveront, mais il garantit qu'une telle situation existe.

Malgré sa simplicité, le principe des tiroirs possède de nombreuses applications en mathématiques et en informatique. Il intervient notamment dans les fonctions de hachage, les collisions, les graphes, les tableaux, les bases de données, les réseaux, la cryptographie, les chaînes de caractères, les preuves d'existence, les bornes minimales et l'analyse des algorithmes.

Principe des tiroirs simple

La forme classique du principe des tiroirs est la suivante :

On peut représenter cette situation par :

Nombre d'objets > Nombre de tiroirs

Donc :

Au moins un tiroir contient
au moins deux objets

Par exemple, si 6 objets sont répartis dans 5 tiroirs, il est impossible que chaque tiroir contienne au plus un objet. Au moins un tiroir doit nécessairement en contenir deux ou davantage.

Exemple élémentaire

Supposons que l'on place 4 boules dans 3 boîtes.

Même si l'on essaie de répartir les boules aussi uniformément que possible, on peut obtenir :

Boîte 1 : 2 boules
Boîte 2 : 1 boule
Boîte 3 : 1 boule

Au moins une boîte contient donc deux boules.

Cette conclusion ne dépend pas de la manière exacte dont les objets sont répartis.

Interprétation en termes de fonction

Le principe des tiroirs peut être formulé à l'aide d'une fonction.

Considérons une fonction :

f : A → B

où :

|A| > |B|

Alors la fonction f ne peut pas être injective.

Il existe nécessairement deux éléments distincts :

x1 ≠ x2

tels que :

f(x1) = f(x2)

Les éléments de A représentent les objets et les éléments de B représentent les tiroirs.

Collision

En informatique, lorsque deux valeurs d'entrée différentes produisent la même valeur de sortie, on parle généralement de collision.

Selon le principe des tiroirs, si une fonction associe un ensemble d'entrées plus grand à un ensemble de sorties plus petit, les collisions sont inévitables.

Par exemple, une fonction transformant un nombre arbitrairement grand de fichiers en valeurs de hachage de 32 bits ne peut pas produire une valeur unique pour chaque fichier possible.

Principe généralisé des tiroirs

La forme généralisée du principe affirme que si N objets sont répartis dans k tiroirs, alors au moins un tiroir contient au moins :

⌈N/k⌉

objets.

La notation :

⌈x⌉

désigne le **plafond** de x, c'est-à-dire le plus petit entier supérieur ou égal à x.

Exemple du principe généralisé

Supposons que 100 fichiers soient répartis dans 9 dossiers.

Le nombre moyen de fichiers par dossier est :

100/9 ≈ 11,11

Le plafond vaut :

⌈100/9⌉ = 12

Au moins un dossier contient donc au moins :

12 fichiers

Même avec la répartition la plus équilibrée possible, il est impossible que chaque dossier en contienne au plus 11.

Formulation par contradiction

Le principe généralisé peut être démontré par contradiction.

Supposons que chaque tiroir contienne au plus :

⌈N/k⌉ - 1

objets.

Le nombre total d'objets serait alors au plus :

k(
⌈N/k⌉ - 1
)

Cette quantité est strictement inférieure à **N**, ce qui contredit le fait que les N objets ont tous été placés dans les tiroirs.

Il existe donc nécessairement un tiroir contenant au moins :

⌈N/k⌉

objets.

Répartition la plus équilibrée

Lorsque N objets sont distribués aussi uniformément que possible dans k tiroirs, chaque tiroir contient soit :

⌊N/k⌋

objets, soit :

⌈N/k⌉

objets.

La notation :

⌊x⌋

désigne le plus grand entier inférieur ou égal à x.

Si :

N = qk + r

avec :

0 ≤ r < k

alors :

Exemple de répartition équilibrée

Pour répartir 23 objets dans 5 tiroirs :

23 = 4 × 5 + 3

Trois tiroirs contiennent :

5 objets

et deux tiroirs contiennent :

4 objets

La répartition la plus équilibrée est donc :

5, 5, 5, 4, 4

Au moins un tiroir contient :

⌈23/5⌉ = 5

objets.

Forme duale

Une forme duale du principe affirme que si N objets sont répartis dans k tiroirs, alors au moins un tiroir contient au plus :

⌊N/k⌋

objets.

Cette version est utile lorsqu'on cherche une catégorie faiblement représentée.

Ainsi, dans une répartition de 100 éléments entre 9 catégories, au moins une catégorie contient au plus :

⌊100/9⌋ = 11

éléments.

Garantie d'au moins r objets dans un tiroir

Pour garantir qu'au moins un tiroir contienne au moins r objets, il faut placer :

k(r-1)+1

objets dans k tiroirs.

En effet, si chaque tiroir contient au plus :

r-1

objets, le nombre total maximal est :

k(r-1)

L'objet supplémentaire force donc un tiroir à atteindre au moins r objets.

Exemple de garantie

Combien de personnes faut-il pour garantir qu'au moins 4 personnes soient nées le même mois ?

Il existe :

12

mois.

Chaque mois pourrait contenir au plus 3 personnes sans atteindre 4.

Le nombre maximal de personnes dans cette situation est :

12 × 3 = 36

Il faut donc :

36 + 1 = 37

personnes pour garantir qu'au moins 4 d'entre elles sont nées durant le même mois.

Anniversaires et mois

Dans un groupe de 13 personnes, au moins deux personnes sont nées durant le même mois.

Les objets sont :

13 personnes

Les tiroirs sont :

12 mois

Comme :

13 > 12

au moins un mois correspond à la naissance d'au moins deux personnes.

Cette démonstration ne tient pas compte du jour ni de l'année de naissance.

Anniversaires et jours de l'année

Dans un groupe de 367 personnes, au moins deux personnes partagent nécessairement le même jour d'anniversaire, en considérant une année de 366 jours.

Les objets sont :

367 personnes

Les tiroirs sont :

366 dates possibles

Le principe garantit donc un anniversaire commun.

Avec seulement 366 personnes, cette répétition n'est pas garantie, car chaque personne pourrait avoir une date différente.

Reste d'une division

Lorsque plusieurs entiers sont divisés par un même entier positif m, les restes possibles sont :

0, 1, 2, ..., m-1

Il existe donc exactement :

m

classes de restes.

Si l'on choisit :

m+1

entiers, au moins deux possèdent le même reste modulo m.

Conséquence modulaire

Si deux entiers a et b possèdent le même reste modulo m, alors :

a ≡ b (mod m)

Donc :

m divise a-b

Le principe des tiroirs permet ainsi de démontrer l'existence de deux nombres dont la différence est divisible par un entier donné.

Exemple modulo 10

Parmi 11 entiers quelconques, au moins deux possèdent le même dernier chiffre.

Les tiroirs correspondent aux dix restes modulo 10 :

0, 1, 2, 3, 4, 5, 6, 7, 8, 9

Les deux nombres ayant le même dernier chiffre ont une différence divisible par 10.

Différence divisible par n

Parmi :

n+1

entiers quelconques, il existe toujours deux entiers dont la différence est divisible par n.

Chaque entier est classé selon son reste modulo n.

Il existe seulement :

n

restes possibles.

Deux nombres doivent donc appartenir à la même classe de congruence.

Sous-sommes divisibles

Le principe des tiroirs peut également être appliqué aux sommes partielles.

Considérons une suite de n entiers :

a1, a2, ..., an

Définissons les sommes partielles :

S1 = a1
S2 = a1+a2
...
Sn = a1+a2+...+an

Si une somme partielle est divisible par n, le résultat est immédiat.

Sinon, les n sommes partielles possèdent des restes non nuls parmi seulement :

n-1

valeurs possibles.

Deux sommes partielles possèdent donc le même reste.

Conséquence sur les sous-séquences

Si :

Si ≡ Si (mod n)

avec :

i < j

alors :

Si - Si

est divisible par n.

Or :

Si - Si
=
ai+1 + ai+2 + ... + ai

Il existe donc toujours une sous-séquence contiguë non vide dont la somme est divisible par n.

Exemple de sous-somme

Considérons les cinq entiers :

3, 1, 4, 2, 6

Les sommes partielles sont :

3
4
8
10
16

Modulo 5, les restes sont :

3
4
3
0
1

La somme partielle :

10

est divisible par 5.

La sous-séquence :

3 + 1 + 4 + 2

possède donc une somme divisible par 5.

Principe des tiroirs et parité

Chaque entier est soit :

pair

soit :

impair

Il existe donc deux tiroirs correspondant à la parité.

Parmi trois entiers quelconques, au moins deux possèdent la même parité.

Leur somme et leur différence sont alors paires.

Exemple avec la parité

Considérons trois entiers :

7, 12, 19

Deux d'entre eux sont impairs :

7

et :

19

Leur différence est :

19 - 7 = 12

Elle est paire.

Le principe garantit l'existence d'une telle paire sans qu'il soit nécessaire d'examiner toutes les combinaisons.

Points dans un carré

Le principe des tiroirs peut être appliqué à des régions géométriques.

Supposons qu'un carré soit divisé en quatre petits carrés égaux.

Si cinq points sont placés dans le grand carré, au moins deux points appartiennent au même petit carré.

Les points représentent les objets et les quatre petits carrés représentent les tiroirs.

Cette observation permet ensuite de déterminer une borne sur la distance séparant deux points.

Distance entre deux points

Considérons un carré de côté 2 divisé en quatre carrés de côté 1.

Si cinq points sont placés dans le carré initial, deux d'entre eux se trouvent dans le même petit carré.

La distance maximale entre deux points appartenant à un carré de côté 1 est sa diagonale :

√2

Il existe donc deux points distants d'au plus :

√2

Découpage géométrique

Dans les applications géométriques, le choix des tiroirs est essentiel.

Les tiroirs peuvent être :

Le découpage doit être choisi de manière que deux objets placés dans la même région satisfassent la propriété recherchée.

Nombres dans un intervalle

Considérons n+1 nombres réels appartenant à l'intervalle :

[0,1]

On divise l'intervalle en **n sous-intervalles** de longueur :

1/n

Au moins deux nombres se trouvent dans le même sous-intervalle.

Leur distance est donc au plus :

1/n

Cette propriété est une conséquence directe du principe des tiroirs.

Valeurs rapprochées

Plus généralement, si N valeurs sont réparties sur un intervalle de longueur L et que celui-ci est divisé en k segments égaux, au moins deux valeurs se trouvent dans le même segment lorsque :

N > k

Leur distance est alors inférieure ou égale à :

L/k

Cette méthode fournit une borne d'existence sur la proximité de deux valeurs.

Graphe et degrés des sommets

Dans un graphe simple comportant n sommets, le degré d'un sommet peut théoriquement prendre les valeurs :

0, 1, 2, ..., n-1

Cependant, un graphe simple ne peut pas contenir simultanément :

Si un sommet est relié à tous les autres, aucun sommet ne peut être isolé.

Il existe donc au plus :

n-1

valeurs de degré effectivement disponibles.

Deux sommets de même degré

Comme le graphe contient :

n sommets

et au plus :

n-1

degrés possibles, au moins deux sommets possèdent le même degré.

Cette propriété est vraie pour tout graphe simple fini comportant au moins deux sommets.

Le principe des tiroirs fournit ici une preuve très courte d'un résultat de théorie des graphes.

Chaînes de caractères

Supposons qu'une chaîne utilise un alphabet de m symboles.

Toute chaîne de longueur :

m+1

contient nécessairement au moins un symbole répété.

Les caractères sont les objets et les symboles de l'alphabet sont les tiroirs.

Cette propriété est utilisée dans l'analyse de chaînes et la détection de répétitions.

Fréquence minimale d'un caractère

Dans une chaîne de longueur N utilisant un alphabet de m symboles, au moins un symbole apparaît au moins :

⌈N/m⌉

fois.

Par exemple, dans une chaîne de 100 caractères formée uniquement avec les 26 lettres de l'alphabet, au moins une lettre apparaît au moins :

⌈100/26⌉ = 4

fois.

Octets et valeurs possibles

Un octet peut prendre :

256

valeurs différentes, de :

0

à :

255

Dans une séquence contenant 257 octets, au moins deux octets possèdent la même valeur.

Dans une séquence contenant N octets, au moins une valeur apparaît :

⌈N/256⌉

fois.

Adresses IP

Une adresse IPv4 contient 32 bits.

Il existe donc au plus :

232

adresses binaires différentes.

Si un système devait attribuer plus de :

232

adresses IPv4 distinctes simultanément, au moins deux appareils recevraient la même adresse.

Dans la pratique, certaines plages sont réservées, ce qui réduit encore le nombre d'adresses utilisables.

Fonctions de hachage

Une fonction de hachage associe des données de taille variable à une valeur de taille fixe.

Par exemple, une fonction produisant un résultat de **b bits** possède au plus :

2b

valeurs de sortie possibles.

Comme le nombre de messages possibles est généralement beaucoup plus grand, il existe nécessairement plusieurs messages produisant le même hachage.

Les collisions ne peuvent donc pas être éliminées complètement.

Exemple de hachage sur 8 bits

Une fonction de hachage de 8 bits produit :

256

valeurs possibles.

Si 257 entrées distinctes sont hachées, au moins deux produisent nécessairement la même valeur.

Le principe garantit la collision, même si la fonction répartit les valeurs aussi uniformément que possible.

Table de hachage

Dans une table de hachage possédant m cases, l'insertion de plus de m clefs distinctes provoque nécessairement au moins une collision.

Cependant, une collision peut apparaître bien avant que toutes les cases soient utilisées.

Le principe des tiroirs fournit uniquement une garantie à partir d'un certain seuil. Il ne donne pas la probabilité d'une collision avant ce seuil.

Collision certaine et collision probable

Il faut distinguer :

Dans un espace de m valeurs, une collision est certaine à partir de :

m+1

objets.

Cependant, en raison du paradoxe des anniversaires, une collision peut devenir probable avec un nombre d'objets beaucoup plus faible, approximativement de l'ordre de :

√m

Identifiants et clefs

Supposons qu'un système utilise des identifiants numériques compris entre :

0

et :

999

Il existe :

1000

identifiants possibles.

Si 1001 enregistrements doivent posséder chacun un identifiant de ce domaine, au moins deux enregistrements partageront le même identifiant.

Pour garantir l'unicité, le domaine des identifiants doit être au moins aussi grand que le nombre d'éléments à identifier.

Bases de données

Dans une base de données, une colonne utilisée comme clé primaire doit contenir des valeurs uniques.

Si son domaine possède seulement m valeurs possibles, elle ne peut identifier plus de m lignes sans répétition.

Le principe des tiroirs permet donc de vérifier si la capacité théorique d'un type de données est suffisante.

Par exemple, une clé sur un entier non signé de 8 bits ne peut identifier que 256 lignes distinctes.

Codes de longueur fixe

Si un code possède n positions et que chaque position peut contenir m symboles, le nombre de codes possibles est :

mn

Si davantage de mn objets doivent recevoir un code, au moins deux objets partageront le même code.

Cette limite est indépendante de l'algorithme utilisé pour attribuer les codes.

Couleurs d'un écran

Supposons qu'une image utilise une palette de 256 couleurs.

Si l'image contient plus de 256 pixels, au moins deux pixels possèdent nécessairement la même couleur.

Dans une image contenant N pixels, au moins une couleur est utilisée :

⌈N/256⌉

fois.

Cette conclusion ne dépend pas de la disposition spatiale des pixels.

Fichiers répartis sur des serveurs

Si N fichiers sont répartis entre k serveurs, au moins un serveur contient au moins :

⌈N/k⌉

fichiers.

Ce résultat permet d'établir une charge minimale inévitable sur au moins une machine.

Il ne prouve toutefois pas que la répartition est équilibrée ni que les tailles des fichiers sont comparables.

Charge de travail

Supposons que 100 tâches soient attribuées à 8 processeurs.

Au moins un processeur reçoit :

⌈100/8⌉ = 13

tâches.

Cette conclusion porte uniquement sur le nombre de tâches.

Si les tâches possèdent des durées différentes, le processeur recevant le plus de tâches n'est pas nécessairement celui dont la charge totale est la plus élevée.

Répartition de requêtes

Si un serveur reçoit 10 000 requêtes réparties sur 60 secondes, au moins une seconde contient :

⌈10 000/60⌉ = 167

requêtes.

Le principe permet de déduire l'existence d'un pic minimal de requêtes par seconde.

Il ne précise pas la seconde concernée ni la distribution exacte dans le temps.

Mémoire et adresses

Si un programme tente de stocker davantage d'objets simultanés que de positions mémoire disponibles, au moins deux objets devraient partager la même position.

Sans mécanisme de remplacement, de pagination ou de stockage externe, cette situation est impossible.

Le principe des tiroirs exprime ici une limite fondamentale de capacité.

Registres et valeurs

Un registre de **b bits** peut représenter au plus :

2b

configurations binaires.

Si un calcul doit distinguer davantage de 2b états, certaines configurations devront partager la même représentation.

Cela peut conduire à :

Automates finis

Un automate fini possède un nombre limité d'états.

Si l'automate traite une entrée suffisamment longue, il doit nécessairement revisiter un état déjà rencontré.

Les positions successives dans le traitement sont les objets, et les états de l'automate sont les tiroirs.

Cette observation est à la base de plusieurs résultats sur les langages réguliers.

Répétition d'état dans un automate

Considérons un automate possédant m états.

Après avoir observé :

m+1

configurations successives, au moins deux configurations utilisent le même état.

La portion de traitement comprise entre ces deux occurrences forme une boucle potentiellement répétable.

Cette idée intervient dans le lemme de l'étoile, également appelé lemme de pompage.

Suites ultimement périodiques

Considérons un système déterministe possédant m états possibles.

À partir d'un état initial, il produit une suite :

s0, s1, s2, ...

Après au plus :

m+1

termes, un état doit se répéter.

Comme l'évolution est déterministe, la suite devient ensuite périodique.

Générateurs pseudo-aléatoires

Un générateur pseudo-aléatoire utilisant un état interne de b bits possède au plus :

2b

états différents.

Après un nombre suffisant d'itérations, un état doit se répéter.

À partir de cette répétition, la séquence produite recommence selon un cycle.

La période maximale ne peut donc pas dépasser le nombre d'états disponibles.

Détection de cycles

Le principe des tiroirs justifie l'existence d'un cycle dans toute suite déterministe évoluant dans un ensemble fini.

Des algorithmes comme :

permettent de détecter ce cycle sans stocker tous les états précédents.

Exemple d'évolution modulo m

Considérons la suite :

xn+1 =
f(xn) mod m

Les valeurs possibles sont seulement :

0, 1, ..., m-1

Après au plus :

m+1

termes, une valeur se répète.

La suite devient alors ultimement périodique.

Sous-tableaux et sommes

Le principe des tiroirs est utile pour démontrer l'existence de sous-tableaux possédant certaines propriétés.

Par exemple, dans un tableau de n entiers, il existe toujours un sous-tableau contigu non vide dont la somme est divisible par n.

Cette propriété repose sur les restes modulo n des sommes préfixes.

Sommes préfixes

Pour un tableau :

a[1..n]

on définit :

préfixe[0] = 0

et :

préfixe[i]
=
a[1] + a[2] + ... + a[i]

Il existe :

n+1

sommes préfixes.

Leurs restes modulo n appartiennent à seulement :

n

classes possibles.

Démonstration avec préfixe nul

Comme il existe n+1 sommes préfixes et seulement n restes, deux sommes préfixes possèdent le même reste.

Supposons :

préfixe[i]

préfixe[j]
(mod n)

avec :

i < j

Alors :

préfixe[j] - préfixe[i]

est divisible par n.

Cette différence correspond à la somme du sous-tableau :

a[i+1..j]

Algorithme de recherche d'un sous-tableau divisible

MODULE TrouverSousTableauDivisible(tableau)

   n ← longueur(tableau)
   premièrePosition[0..n-1] ← -1

   somme ← 0
   premièrePosition[0] ← 0

   POUR i ← 1 JUSQU'A n

      somme ← somme + tableau[i]
      reste ← ((somme MOD n)+n) MOD n
      SI premièrePosition[reste] ≠ -1 ALORS
         début ← premièrePosition[reste] + 1
         fin ← i
         RETOURNER (début,fin)
      SINON
         premièrePosition[reste] ← i
      FIN SI
   FIN POUR

L'algorithme mémorise la première position associée à chaque reste.

Complexité de l'algorithme

L'algorithme examine chaque élément une seule fois.

Sa complexité temporelle est :

O(n)

La mémoire supplémentaire utilisée est :

O(n)

pour conserver la première position de chaque reste possible.

Recherche de doublons

Pour détecter un doublon dans un tableau de n+1 entiers dont les valeurs appartiennent à :

{1,2,...,n}

le principe des tiroirs garantit qu'au moins une valeur apparaît plusieurs fois.

Cette garantie est indépendante de l'ordre des éléments.

Le problème consiste ensuite à localiser le doublon efficacement.

Exemple de doublon garanti

Considérons le tableau :

[1, 4, 3, 2, 5, 3]

Il contient 6 éléments, mais les valeurs possibles sont limitées à :

1, 2, 3, 4, 5

Comme :

6 > 5

un doublon est obligatoire.

Dans cet exemple, la valeur répétée est :

3

Détection avec une table de fréquences

MODULE TrouverDoublon(tableau,n)
   vu[1..n] ← FAUX
   POUR CHAQUE valeur DANS tableau
      SI vu[valeur] ALORS
         RETOURNER valeur
      FIN SI
      vu[valeur] ← VRAI
   FIN POUR
   RETOURNER AUCUN

Cet algorithme fonctionne en :

O(n)

temps et utilise :

O(n)

mémoire supplémentaire.

Détection sans mémoire proportionnelle

Lorsque le tableau contient n+1 valeurs appartenant à :

{1,...,n}

et qu'il peut être interprété comme une structure de pointeurs, l'algorithme de Floyd peut parfois trouver un doublon en :

O(n)

temps et :

O(1)

mémoire supplémentaire.

Le principe des tiroirs garantit l'existence du doublon, tandis que l'interprétation en cycle permet de le localiser.

Séquences et préfixes identiques

Si un ensemble contient davantage de chaînes que de préfixes possibles d'une longueur donnée, au moins deux chaînes possèdent le même préfixe.

Par exemple, il existe :

263

préfixes possibles de trois lettres majuscules.

Parmi :

263 + 1

noms utilisant uniquement ces lettres, au moins deux commencent par le même préfixe de trois lettres.

Suffixes et extensions de fichiers

Le même raisonnement s'applique aux suffixes.

Si un système classe des fichiers selon m extensions possibles, tout ensemble de plus de m fichiers contient au moins deux fichiers possédant la même extension.

Dans un ensemble de N fichiers, une extension apparaît au moins :

⌈N/m⌉

fois.

Résidus de hachage et partitionnement

Dans certains systèmes, une clef est affectée à une partition selon :

partition =
hachage(clef) mod k

Il existe :

k

partitions.

Pour N clefs, au moins une partition reçoit au moins :

⌈N/k⌉

clefs.

Cette borne ne garantit toutefois pas que la fonction de hachage répartit correctement les clefs.

Processus distribués

Supposons que N processus soient répartis entre k machines.

Au moins une machine exécute :

⌈N/k⌉

processus.

Cette borne peut servir à estimer la charge minimale maximale d'une répartition, également appelée charge du serveur le plus occupé.

Une stratégie optimale ne peut pas produire une charge maximale inférieure à cette valeur.

Ordonnancement

Dans un problème d'ordonnancement, si N tâches doivent être réparties entre k processeurs, la charge en nombre de tâches du processeur le plus occupé est au moins :

⌈N/k⌉

Cette borne inférieure peut être utilisée pour évaluer la qualité d'une solution.

Cependant, lorsque les durées des tâches diffèrent, une borne basée sur la somme des durées est généralement plus pertinente.

Borne inférieure sur la charge

Si les tâches possèdent des durées :

t1, t2, ..., tn

et qu'elles sont réparties entre k processeurs, au moins un processeur possède une charge d'au moins :


(t1+t2+...+tn)/k

lorsque les durées sont entières.

Cette version applique le même raisonnement à la charge totale plutôt qu'au simple nombre de tâches.

Compression sans perte

Une méthode de compression sans perte doit permettre de reconstituer exactement les données initiales.

Il est impossible que toutes les chaînes de longueur n soient compressées en chaînes strictement plus courtes.

En effet, le nombre total de chaînes plus courtes est inférieur au nombre de chaînes de longueur n.

Le principe des tiroirs implique que deux entrées distinctes recevraient la même représentation comprimée, rendant la décompression ambiguë.

Démonstration pour les chaînes binaires

Il existe :

2n

chaînes binaires de longueur n.

Le nombre total de chaînes binaires de longueur strictement inférieure à n est :

1 + 2 + 22 + ... + 2n-1

soit :

2n - 1

Il n'existe donc pas assez de chaînes plus courtes pour représenter sans collision toutes les chaînes de longueur n.

Conséquence sur la compression

Un algorithme de compression sans perte peut raccourcir certaines données, mais il doit nécessairement :

Il ne peut pas compresser strictement toutes les entrées possibles.

Cette limite est une conséquence directe du principe des tiroirs.

Cryptographie

En cryptographie, le principe des tiroirs intervient dans l'étude :

Il établit plusieurs limites théoriques indépendantes de la puissance de calcul disponible.

Chiffrement déterministe

Un chiffrement réversible utilisant une clé fixe doit être injectif sur son espace de messages.

Si l'espace des textes chiffrés est plus petit que l'espace des messages possibles, deux messages distincts produiraient le même texte chiffré.

La décryption ne pourrait alors pas déterminer le message initial.

Le domaine de sortie doit donc avoir une capacité au moins égale à celle du domaine d'entrée.

Principe des tiroirs infini

Une version infinie du principe affirme que si une infinité d'objets est répartie dans un nombre fini de tiroirs, au moins un tiroir contient une infinité d'objets.

Par exemple, si tous les entiers naturels sont classés selon leur reste modulo 5, chaque classe contient une infinité d'entiers.

Au moins une classe doit nécessairement être infinie, et dans cet exemple elles le sont toutes.

Suite infinie sur un alphabet fini

Toute suite infinie formée à partir d'un alphabet fini contient au moins un symbole apparaissant une infinité de fois.

Si chaque symbole apparaissait seulement un nombre fini de fois, la suite entière serait finie.

Cette contradiction démontre le résultat.

Version pondérée

Le principe peut être généralisé à des charges ou à des poids.

Si des objets de poids total W sont répartis dans k tiroirs, au moins un tiroir reçoit un poids d'au moins :

W/k

Plus précisément, pour des poids entiers, un tiroir reçoit au moins :

⌈W/k⌉

unités de poids.

Cette version est utilisée dans les problèmes de répartition de ressources.

Moyenne et principe des tiroirs

Le principe généralisé peut être interprété à partir de la moyenne.

Si la moyenne du nombre d'objets par tiroir est :

N/k

alors au moins un tiroir contient un nombre d'objets supérieur ou égal à cette moyenne.

Comme le contenu est entier, il contient au moins :

⌈N/k⌉

objets.

De même, au moins un tiroir contient au plus :

⌊N/k⌋

objets.

Principe de la moyenne

Une formulation apparentée affirme que, parmi plusieurs valeurs, au moins une est supérieure ou égale à leur moyenne et au moins une est inférieure ou égale à leur moyenne.

Pour des valeurs :

x1, x2, ..., xk

de moyenne :

μ =
(x1+x2+...+xk)/k

il existe au moins un indice i tel que :

xi ≥ μ

et au moins un indice j tel que :

xi ≤ μ

Principe des tiroirs et invariants

Dans certaines preuves, les objets sont classés selon un invariant.

Un invariant peut être :

Si le nombre d'objets dépasse le nombre de valeurs possibles de l'invariant, deux objets partagent la même valeur.

Choix des tiroirs

La principale difficulté d'un problème utilisant le principe des tiroirs consiste souvent à déterminer les tiroirs appropriés.

Les tiroirs doivent être choisis de manière que :

Un mauvais choix de catégories peut produire une conclusion vraie mais inutile.

Méthode de résolution

Une méthode générale consiste à suivre les étapes suivantes :

  1. Identifier les objets.
  2. Déterminer les catégories possibles.
  3. Compter les objets.
  4. Compter les catégories.
  5. Comparer les deux quantités.
  6. Appliquer la forme simple ou généralisée.
  7. Traduire la collision obtenue

dans le contexte du problème.

Cette démarche permet d'éviter les erreurs d'interprétation.

Exemple de méthode

Problème :

Les objets sont :

17 entiers

Les tiroirs sont :

16 restes possibles

Comme :

17 > 16

deux entiers possèdent le même reste.

Leur différence est donc divisible par 16.

Problème inverse

Le principe des tiroirs peut également être utilisé pour déterminer le nombre maximal d'objets pouvant être placés sans produire une certaine concentration.

Si l'on veut éviter qu'un tiroir contienne r objets, chaque tiroir peut en contenir au plus :

r-1

Avec k tiroirs, le nombre maximal d'objets est :

k(r-1)

L'objet suivant rend la propriété inévitable.

Exemple du problème inverse

Combien de personnes peut-on avoir sans garantir que 5 soient nées le même mois ?

Chaque mois peut contenir au plus :

4 personnes

Il existe 12 mois.

Le nombre maximal est donc :

12 × 4 = 48

Avec 49 personnes, au moins 5 partagent nécessairement un mois de naissance.

Nombre minimal requis

Le nombre minimal d'objets requis pour garantir qu'un tiroir contienne au moins r objets est :

k(r-1)+1

Cette formule doit être distinguée de :

⌈N/k⌉

La première détermine combien d'objets sont nécessaires pour atteindre une garantie donnée. La seconde détermine la concentration minimale garantie pour un nombre d'objets déjà connu.

Tableau récapitulatif

Situation Conclusion
n+1 objets dans n tiroirs Un tiroir contient au moins 2 objets
N objets dans k tiroirs Un tiroir contient au moins ⌈N/k⌉ objets
N objets dans k tiroirs Un tiroir contient au plus ⌊N/k⌋ objets
Garantir au moins r objets dans un tiroir Il faut k(r-1)+1 objets
Plus de m entrées pour m sorties Une collision existe
m+1 entiers modulo m Deux possèdent le même reste
Suite déterministe dans m états Un état se répète après au plus `m+1` observations
Plus de mn objets avec des codes de longueur n sur m symboles Deux objets partagent le même code

Algorithme de calcul de la borne minimale

MODULE ChargeMinimaleMaximale(nombreObjets,nombreTiroirs)
   SI nombreObjets < 0 ALORS
      ERREUR
   FIN SI

   SI nombreTiroirs ≤ 0 ALORS
      ERREUR
   FIN SI

   RETOURNER
      (
         nombreObjets
         +
         nombreTiroirs
         -
         1
      )
      DIV
      nombreTiroirs

Cette formule calcule :

⌈nombreObjets/nombreTiroirs⌉

sans utiliser de nombres réels.

Algorithme du nombre minimal d'objets

MODULE NombreMinimalPourGarantie(nombreTiroirs,quantitéGarantie)

   SI nombreTiroirs ≤ 0 ALORS
      ERREUR
   FIN SI

   SI quantitéGarantie ≤ 0 ALORS
      ERREUR
   FIN SI

   RETOURNER
      nombreTiroirs
      ×
      (quantitéGarantie-1)
      +
      1

Pour 12 mois et une garantie de 4 personnes :

12 × (4-1) + 1
=
37

Exemple en Java

  1. public final class PrincipeDesTiroirs {
  2.  
  3.     private PrincipeDesTiroirs() {
  4.     }
  5.  
  6.     public static long concentrationMinimale(
  7.         long nombreObjets,
  8.         long nombreTiroirs
  9.     ) {
  10.         if (nombreObjets < 0) {
  11.             throw new IllegalArgumentException(
  12.                 "Le nombre d'objets ne peut pas être négatif."
  13.             );
  14.         }
  15.  
  16.         if (nombreTiroirs <= 0) {
  17.             throw new IllegalArgumentException(
  18.                 "Le nombre de tiroirs doit être positif."
  19.             );
  20.         }
  21.  
  22.         if (nombreObjets == 0) {
  23.             return 0;
  24.         }
  25.  
  26.         return 1
  27.             + (nombreObjets - 1)
  28.             / nombreTiroirs;
  29.     }
  30.  
  31.     public static long objetsPourGarantir(
  32.         long nombreTiroirs,
  33.         long quantiteGarantie
  34.     ) {
  35.         if (nombreTiroirs <= 0) {
  36.             throw new IllegalArgumentException(
  37.                 "Le nombre de tiroirs doit être positif."
  38.             );
  39.         }
  40.  
  41.         if (quantiteGarantie <= 0) {
  42.             throw new IllegalArgumentException(
  43.                 "La quantité garantie doit être positive."
  44.             );
  45.         }
  46.  
  47.         long produit = Math.multiplyExact(
  48.             nombreTiroirs,
  49.             quantiteGarantie - 1
  50.         );
  51.  
  52.         return Math.addExact(produit, 1);
  53.     }
  54.  
  55.     public static void main(String[] args) {
  56.         System.out.println(
  57.             "Concentration minimale : "
  58.             + concentrationMinimale(100, 9)
  59.         );
  60.  
  61.         System.out.println(
  62.             "Personnes requises : "
  63.             + objetsPourGarantir(12, 4)
  64.         );
  65.     }
  66. }

Le programme affiche :

Concentration minimale : 12
Personnes requises : 37

Vérification d'une collision en Java

  1. import java.util.HashMap;
  2. import java.util.Map;
  3. import java.util.Optional;
  4.  
  5. public final class CollisionSample {
  6.  
  7.     private CollisionSample() {
  8.     }
  9.  
  10.     public static Optional<int[]> trouverCollisionModulo(
  11.         int[] valeurs,
  12.         int module
  13.     ) {
  14.         if (module <= 0) {
  15.             throw new IllegalArgumentException(
  16.                 "Le module doit être positif."
  17.             );
  18.         }
  19.  
  20.         Map<Integer, Integer> premierePosition =
  21.             new HashMap<>();
  22.  
  23.         for (int i = 0; i < valeurs.length; i++) {
  24.             int reste =
  25.                 Math.floorMod(valeurs[i], module);
  26.  
  27.             Integer autrePosition =
  28.                 premierePosition.putIfAbsent(
  29.                     reste,
  30.                     i
  31.                 );
  32.  
  33.             if (autrePosition != null) {
  34.                 return Optional.of(
  35.                     new int[] {
  36.                         autrePosition,
  37.                         i
  38.                     }
  39.                 );
  40.             }
  41.         }
  42.  
  43.         return Optional.empty();
  44.     }
  45.  
  46.     public static void main(String[] args) {
  47.         int[] valeurs = {
  48.             8, 19, 27, 42, 58, 71
  49.         };
  50.  
  51.         trouverCollisionModulo(valeurs, 5)
  52.             .ifPresent(indices ->
  53.                 System.out.println(
  54.                     "Collision entre les positions "
  55.                     + indices[0]
  56.                     + " et "
  57.                     + indices[1]
  58.                 )
  59.             );
  60.     }
  61. }

La méthode recherche deux valeurs possédant le même reste modulo le module fourni.

Complexité de la recherche de collision

Avec une table de hachage ou un tableau de positions, la recherche d'une collision peut être réalisée en :

O(N)

temps.

La mémoire utilisée dépend du nombre de tiroirs :

O(k)

Le principe des tiroirs garantit l'existence d'une collision lorsque :

N > k

mais l'algorithme reste nécessaire pour identifier les objets concernés.

Preuve d'existence et construction

Le principe des tiroirs est principalement un outil de preuve d'existence.

Il démontre qu'un objet, une paire ou une collision existe, mais il ne fournit pas toujours une méthode directe pour la trouver.

Il faut distinguer :

Dans de nombreux cas informatiques, une table de fréquences, un tri ou une structure de hachage permet de rendre la preuve constructive.

Applications

Le principe des tiroirs est utilisé dans de nombreux domaines :

Avantages

Le principe des tiroirs présente plusieurs avantages :

Limites et précautions

Plusieurs précautions doivent être prises :

Remarque

Le principe des tiroirs repose sur une idée très simple : lorsqu'un nombre insuffisant de catégories doit accueillir un nombre plus élevé d'objets, une répétition devient inévitable. Cette observation permet de prouver l'existence de doublons, de collisions, de valeurs rapprochées, de sous-sommes divisibles, d'états répétés et de charges minimales.

En programmation, ce principe explique pourquoi les fonctions de hachage possèdent nécessairement des collisions, pourquoi un automate fini finit par revisiter un état, pourquoi une compression sans perte ne peut raccourcir toutes les données et pourquoi un domaine d'identifiants doit être suffisamment grand. Il prépare naturellement à l'étude des relations de récurrence, des probabilités discrètes, de la théorie des graphes, des algorithmes de hachage et des méthodes de détection de cycles.



Dernière mise à jour : Jeudi, le 16 juillet 2026