<figure><img src="image_1.png" /></figure>

HAL
open science

# Trier des cochons sauvages

Emma Caizergues, François Durand, Fabien Mathieu

► To cite this version:

Emma Caizergues, François Durand, Fabien Mathieu. Trier des cochons sauvages. AlgoTel 2023 - 25èmes Rencontres Francophones sur les Aspects Algorithmiques des Télécommunications, May 2023, Cargese, France. hal-04077471

HAL Id: hal-04077471

https://hal.science/hal-04077471

Submitted on 21 Apr 2023

HAL is a multi-disciplinary open access
archive for the deposit and dissemination of sci-
entific research documents, whether they are pub-
lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d'enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.

Public Domain
# Trier des cochons sauvages†

Emma Caizergues<fnref n="1" />,<fnref n="2" />, François Durand<fnref n="2" /> et Fabien Mathieu<fnref n="3" />

Chjara, éleveuse à Cargèse, possède *n* cochons sauvages. Elle aimerait trier son troupeau par poids afin de mieux satisfaire les demandes de ses acheteurs et acheteuses. Chaque bête a un poids distinct, hélas inconnu de Chjara. Elle n'a à sa disposition qu'une balance de Roberval, qui ne lui permet de comparer deux porcins qu'au prix d'une manœuvre acrobatique. La balance, assez vétuste, peut se briser à tout moment. Chjara veut donc trier son troupeau en un minimum de pesées, mais aussi avoir une bonne estimation du résultat après chaque pesée.

Pour aider Chjara, nous posons le problème de la recherche d'un bon *tri interruptible*, au sens de la distance tau de Kendall entre résultat provisoire et liste parfaitement triée, et nous apportons les contributions suivantes :

— Nous introduisons *Corsort*, une famille de tris interruptibles reposant sur des estimateurs.

— Par simulation, nous montrons qu'un *Corsort* bien configuré a un temps de terminaison quasi-optimal, et fournit de meilleures estimations intermédiaires que les meilleurs tris dont nous avons connaissance.

**Mots-clefs** : Tri par comparaison, algorithmes interruptibles, distance tau de Kendall, ordre partiel.

## 1 Contexte

Pour trier des cochons sauvages, comparer est beaucoup plus coûteux que toute autre opération. Des problèmes similaires apparaissent si la comparaison implique une intervention humaine ou des données massives. On doit alors séparer la complexité en comparaisons de la complexité globale [GSS09].

Si la balance de Chjara était indestructible, on retrouverait un problème classique : minimiser le nombre de comparaisons [CLRS09]. En plus d'algorithmes célèbres tels que le tri rapide, le tri fusion et le tri par tas (parmi bien d'autres), on peut citer l'algorithme de Ford-Johnson [FJ59], extrêmement proche de la borne théorique en nombre de comparaisons, et même optimal pour certaines valeurs [Pec04].

La fragilité de la balance nous rapproche des *algorithmes interruptibles* (*anytime algorithms*), qui maintiennent à tout instant une estimation du résultat [Zil96]. Étonnamment, les tris ont été peu étudiés dans cette littérature : les études ne concernent que le tri par sélection, le tri de Shell ou le tri rapide, sans introduire d'algorithmes plus adapté, et les mesures d'écart au résultat final ne sont pas des distances [Hor88, GZ95].

Parmi les problèmes connexes, les *algorithmes progressifs* peuvent aussi être interrompus à tout moment, mais l'accent est mis sur des bornes prouvables de performance en pire cas plutôt que sur l'efficacité moyenne empirique [ABdB⁺¹⁴]. Les *algorithmes par contrat* opèrent également un compromis entre temps et précision, mais supposent que le temps disponible est connu à l'avance [Zil96]. À l'inverse, le *tri approximatif* part d'un objectif en terme d'erreur maximale, et essaie de borner le nombre d'opérations nécessaire pour l'atteindre. L'algorithme ASort donne des garanties de cette nature [GSS09].

Dans la suite de cet article, la section 2 présente les notions de tri interruptible, d'estimateur et de tri *Corsort*; la section 3 évalue la qualité des solutions considérées par des simulations; et la section 4 conclut.

## 2 Tris interruptibles

Formellement, nous voulons trier une liste $X = (X[1], \dots, X[n])$, où $n > 0$, en effectuant des comparaisons du type : *est-ce que* $X[i] < X[j]$ ? Un *tri interruptible* (*anytime sorting algorithm*) est un algorithme capable, à chaque étape $k$ de son exécution, de renvoyer une estimation $X_k$ du résultat. Dans notre modèle,

<footnote n="1">¹Université Paris Dauphine, France</footnote>

<footnote n="2">²Nokia, Massy, France</footnote>

<footnote n="3">³Swapcard, Paris, France</footnote>

<footnote>†Ce travail a été effectué au LINCS (https://www.lincs.fr/).</footnote>
chaque comparaison constitue une étape de l'algorithmie $^*$, et on mesure la qualité de $X_k$ par la distance tau de Kendall [Ken38] entre $X_k$ et la liste triée : $\tau(X_k) = |\{(i, j) : i < j, X_k[i] > X_k[j]\}|$. Idéalement, nous cherchons un tri interruptible dont le profil de performance $k \to \tau(X_k)$, représentant l'erreur commise, est constamment plus bas que celui des autres algorithmes testés.

## 2.1 Tris classiques

Certains algorithmes classiques peuvent être vus comme interruptibles car ils maintiennent une liste courante qui converge vers la liste triée et peut servir d'estimation $X_k$. C'est le cas du tri rapide et du tri fusion, que nous avons implantés d'une manière favorable à l'esprit de l'algorithmie initial : par exemple, pour le tri rapide, la position du pivot est mise à jour dans la liste après chaque comparaison.

Modifier l'ordre des comparaisons effectuées peut améliorer les estimations intermédiaires $X_k$. Pour le tri fusion, naturellement on parcourt l'arbre de récursion en profondeur (DFS), mais on peut aussi le parcourir en largeur $^§$ (BFS). Pour le tri rapide, notre implémentation améliorée est équivalente à l'algorithmie ASort [GSS09], en utilisant la sélection rapide [Hoa61] comme sous-algorithme d'identification de la médiane.

D'autres algorithmes classiques permettent d'obtenir une estimation $X_k$ par une transformation simple de l'état courant. C'est le cas du tri par tas : parcourir le tas à l'envers, puis les éléments déjà triés à l'endroit.

Enfin, certains algorithmes comme Ford-Johnson n'ont pas d'estimation respectant « l'esprit » de l'algorithme. La section suivante montre comment produire des $X_k$ pour n'importe quel algorithme de tri.

## 2.2 Tris classiques avec estimateurs

Pour rendre n'importe quel tri interruptible, nous proposons de construire un estimateur qui ignore l'algorithme de tri utilisé et repose uniquement sur l'historique des comparaisons effectuées.

Notons $C_k = \{X[i_1] < X[j_1], \dots, X[i_k] < X[j_k]\}$ le résultat de $k$ comparaisons. $C_k$ définit par clôture transitive un ordre partiel $\le_k$ sur les indices de la liste initiale (et donc ses éléments). Un *estimateur* est une fonction qui associe à tout ordre partiel un ordre total compatible.

Une première idée est de considérer l'ensemble des ordres totaux compatibles avec $\le_k$ (ses *extensions linéaires*), et d'associer à chaque élément un score correspondant à sa hauteur moyenne dans les extensions linéaires de $\le_k$. On renvoie ensuite la liste issue du tri des scores (trier $n$ scores est bien moins coûteux que comparer deux cochons sauvages). Cet estimateur semble convainquant mais son coût est prohibitif : compter l'ensemble des extensions linéaires d'un ordre partiel est déjà #P-complet [BW91].

On propose donc une fonction de score heuristique pour calculer en $O(n^2)$ une estimation $X_k$ raisonnable. Si $i$ est un indice de la liste initiale, on note $d_k(i) = |\{j \in [n] : j \le_k i\}|$ et $a_k(i) = |\{j \in [n] : i \le_k j\}|$ le nombre de descendants et d'ancêtres de $i$ (lequel est inclus dans les deux ensembles par convention). On définit la fonction de score $\rho_k$ par $\rho_k(i) = d_k(i)/(d_k(i) + a_k(i))$. Cela revient à positionner $i$ comme si ses descendants et ses ancêtres avaient en moyenne des positions régulièrement espacées.

## 2.3 Tris orientés comparaisons (Corsort)

Un tri *Corsort* (*Comparison-ORiented Sort*) fonctionne ainsi : en fonction de l'ordre partiel courant $\le_k$, estimer $X_k$ et choisir la comparaison suivante. On suppose qu'on choisit toujours des paires non comparables selon $\le_k$, ce qui assure de terminer en au plus $n(n-1)/2$ comparaisons.

Comme pour les tris classiques, nous utiliserons la fonction de score $\rho$ pour construire l'estimateur.

Pour la fonction de prochaine comparaison, on doit assurer, à long terme, une terminaison rapide. C'est un problème de *tri sous information partielle*, qui revient à choisir une comparaison dont les deux issues sont aussi équiprobables que possible [CFJ+10]. À cette fin, nous définissons la fonction de score $\Delta_k$ par $\Delta_k(i) = d_k(i) - a_k(i)$. $\Delta_k$ attribue à chaque $i$ un score qui reflète la moyenne entre sa plus basse et sa plus haute positions possibles, et nous souhaitons comparer des éléments dont les scores sont proches. À court terme, pour améliorer $X_k$, il faut acquérir de l'information sur les éléments pour lesquels on en a peu. On introduit donc $I_k(i) = a_k(i) + d_k(i)$, et on souhaite comparer des éléments pour lesquels $I_k$ est faible.

Après moult expérimentations, parmi les paires encore incomparables, nous choisissons la paire $(i, j)$ qui minimise lexicographiquement la paire $ (|\Delta_k(i) - \Delta_k(j)|, \max(I_k(i), I_k(j))) $.

<footnote>$^*$ Par convention, si l'algorithmie termine en moins de $k$ comparaisons, alors $X_k$ est le résultat final, c'est-à-dire la liste triée.</footnote>

<footnote>$^§$ Dans le cas simple où la taille de la liste est une puissance de 2, on fusionne tous les sous-tableaux de taille 1, puis 2, puis 4, etc.</footnote>
# 3 Évaluation

Nous avons développé un paquet Python pour créer des tris interruptibles et mesurer leurs performances.¶. Pour *n* donné, nous tirons 10 000 permutations aléatoires et calculons les comparaisons nécessaires pour un tri complet et les profils de performance *k* → τ(*X*<sub>*k*</sub>). Pour donner un aperçu de la distribution des résultats, nous traçons pour chaque algorithme la médiane (courbe foncée), les quantiles de 25% à 75% (zone claire), et les quantiles de 2,5% à 97,5% (zone très claire) qui représentent un intervalle de confiance à 95%.

La Figure 1 montre le temps de terminaison (en comparaisons) pour des valeurs de *n* allant de 8 à 1024 et les tris suivants : par tas, rapide, Corsort, fusion et Ford-Johnson. L'axe des ordonnées montre l'écart relatif par rapport à la borne inférieure $n \log_2(n) - n/\ln(2) + \log_2(2\pi n)/2$ [CLRS09] : plus une courbe est proche de 0, plus elle est optimale. Notons que le tri par tas compare presque deux fois plus que nécessaire. Le

<figure><img src="image_2.png" /><figcaption>FIGURE 1 : Nombre relatif de comparaisons supplémentaires par rapport à la borne théorique.</figcaption></figure>

tri rapide est meilleur (moins de 30% de surcoût) mais a une grande variance. Les trois tris restants ont un surcoût encore plus faible (5% pour Corsort, 2% pour le tri fusion, 0,3% pour Ford-Johnson) et une variance négligeable. Nous concluons que Corsort est un bon candidat puisqu'il n'est battu que par des algorithmes dont la terminaison est asymptotiquement optimale, i.e. équivalente à $n \log_2(n)$ [FJ59].

La Figure 2 montre les profils de performance des quatre meilleurs tris de la Figure 1 (rapide, Corsort, fusion, et Ford-Johnson). Pour les estimateurs, Corsort et Ford-Johnson utilisent $\rho$. Pour les tris rapide et fusion deux variantes sont utilisées : la version de base avec son estimation naturelle (l'état courant de la liste); une version améliorée (respectivement fusion-BFS et ASort) munie d'un estimateur utilisant $\rho$. La métrique utilisée est la distance à la liste triée : plus elle est faible, meilleure est la performance. La principale observation est la supériorité du profil de Corsort : il est monotone et constamment sous les autres à part en terminaison (il termine un peu plus tard que fusion ou Ford-Johnson). Corsort est donc un excellent tri interruptible que nous recommandons à Chjara pour trier ses cochons sauvages. On remarque aussi que l'utilisation de l'estimateur $\rho$ améliore le profil de performance¶, parfois au prix d'un comportement non-monotone. Enfin, on peut constater la relative bonne performance du tri fusion-BFS muni de $\rho$, qui peut être un choix intéressant si l'on désire un tri interruptible qui soit également rapide, avec une terminaison en $O(n \log(n))$ opérations totales (pas seulement en comparaisons) hors estimateur.

<footnote>¶. https://emczg.github.io/corsort/</footnote>

<footnote>||. Non montré par manque de place, $\Delta$ améliore également le profil mais est généralement moins performant que $\rho$.</footnote>
<figure><img src="image_3.png" /><figcaption>FIGURE 2 : Profils de performance de tris interruptibles pour $n = 1000$. La distance $\tau$ est normalisée par $n(n - 1)/2$.</figcaption></figure>

# 4 Conclusion

Nous avons étudié des tris interruptibles générant un minimum de comparaisons. Nous avons proposé une méthode pour rendre tout tri interruptible, avec interruption possible après chaque comparaison. Nous avons introduit Corsort, une famille de tris à base d'estimateurs. Par simulation, nous avons montré qu'un tri Corsort bien configuré a un temps de terminaison (en nombre de comparaisons) quasi-optimal et possède un profil de performance meilleur que les meilleurs tris dont nous avons connaissance.

# Références

[ABdB$^{+14}]$ S. P. A. Alewijnse, T. M. Bagautdinov, M. de Berg, Q. W. Bouts, A. P. Ten Brink, K. Buchin, and M. A. Westenberg. Progressive geometric algorithms. In *SoCG 2014*, pages 50–59, 2014.

[BW91] G. Brightwell and P. Winkler. Counting linear extensions is #P-complete. In *STOC '91*, pages 175–181, 1991.

[CFJ$^{+10}$] J. Cardinal, S. Fiorini, G. Joret, R. M. Jungers, and J. I. Munro. Sorting under partial information (without the ellipsoid algorithm). In *STOC '10*, page 359–368, 2010.

[CLRS09] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein. *Introduction to Algorithms*, 3rd Edition. MIT Press, 2009.

[FJ59] L. R. Ford and S. M. Johnson. A tournament problem. *American Mathematical Monthly*, 66 :387–389, 1959.

[GSS09] J. Giesen, E. Schuberth, and M. Stojaković. Approximate sorting. *Fundamenta Informaticae*, 90(1-2) :67–72, 2009.

[GZ95] J. Grass and S. Zilberstein. Programming with anytime algorithms. In *IJCAI-95 Workshop on Anytime Algorithms and Deliberation Scheduling*, 1995.

[Hoa61] C. Hoare. Algorithm 65 : find. *Communications of the ACM*, 4(7) :321–322, 1961.

[Hor88] E. Horvitz. Reasoning under varying and uncertain resource constraints. In *AAAI*, volume 88, pages 111–116, 1988.

[Ken38] M. G. Kendall. A new measure of rank correlation. *Biometrika*, 30(1/2) :81–93, 1938.

[Pec04] M. Peczarski. New results in minimum-comparison sorting. *Algorithmica*, 40 :133–145, 2004.

[Zil96] S. Zilberstein. Using anytime algorithms in intelligent systems. *AI magazine*, 17(3) :73–83, 1996.