Algorithmes du livre.


358

Paul Erdos a parlé du "livre" où Dieu conserve la preuve la plus élégante de chaque théorème mathématique. Cela a même inspiré un livre (qui, à mon avis, en est à sa quatrième édition): Proofs from the Book .

Si Dieu avait un livre similaire pour les algorithmes, quel (s) algorithme (s) pensez-vous être candidat (s)?

Si possible, veuillez également fournir une référence cliquable et les informations clés qui le permettent.

Un seul algorithme par réponse, s'il vous plaît.


11
Bonne question! [Edit:} Une question. Où est la limite entre algorithmes et infrastructures de données? Que se passe-t-il si la clé d'un algorithme est intimement liée à une structure de données (par exemple, UNION FIND dans la fonction inverse d'Ackermann)?
Ross Snider

4
une grande source et peut - être un candidat pour un tel livre est « Encyclopédie des algorithmes » springer.com/computer/theoretical+computer+science/book/...
Marcos Villagra

21
Je suis un peu surpris que les algorithmes que je considère assez difficiles (KMP, tableaux de suffixes linéaires) soient considérés par d'autres comme "tirés du livre". Pour moi, "du livre" signifie simple et évident, mais seulement avec le recul. Je suis curieux de voir comment les autres interprètent "élégant".
Radu GRIGore

49
@supercooldave Vous n'avez pas à croire en Dieu, mais vous devriez croire en son livre. ;-)
Ross Snider

10
Lors d'une conférence en 1985, Erdős a déclaré: "Vous n'avez pas besoin de croire en Dieu, mais vous devriez croire en Le Livre."
Robert Massaioli

Réponses:


116

Union-find est un beau problème dont le meilleur algorithme / structure de données (Disjoint Set Forest ) est basé sur une pile de spaghettis. Bien que très simple et suffisamment intuitif pour expliquer à un enfant intelligent, il a fallu plusieurs années pour obtenir une limite d'exécution. En fin de compte, il a été découvert que son comportement était lié à la fonction inverse d’Ackermann, une fonction dont la découverte marquait un changement de perspective du calcul (et qui était en fait incluse dans On the Infinite de Hilbert ).

Wikipedia fournit une bonne introduction aux forêts disjointes .


109

Correspondance de chaîne Knuth-Morris-Pratt . Les huit lignes de code les plus lisses que vous puissiez voir.


4
C'est un peu ahurissant de réaliser que c'était quelque chose qui n'était pas évident à un moment donné et qui ne l'est que maintenant parce qu'ils l'ont inventé et que nous l'avons appris ... Je pense que nous devrions appliquer la théorie de l'histoire de Carr à la mathématique et à l'informatique. .
Ritwik Bose le

1
D'après la description, je dirais que cela est lié à la recherche rapide de sous-chaîne de Boyer-Moore.
Bart

2
@Mechko Le fait que cet algorithme ait été découvert simultanément et indépendamment par des personnes différentes indique qu'il est évident dans une certaine mesure. Le caractère "évident" de quelque chose dépend des contraintes du projet et de l'environnement de programmation plus large. Si vous avez besoin (1) d'une recherche rapide de texte et (2) vous êtes conscient de l'importance des algorithmes véritablement O (n), et (3) vous avez rencontré du texte avec des correspondances partielles auparavant, et (4) vous avez le temps pour faire les choses "bien", alors cet algorithme est probablement évident.
Matt Gallagher

Dans une interview, Knuth a déclaré que l'idée de cet algorithme venait de l'étude de l' automate fini à deux voies de Stephen Cook pour les palindromes.
Kaveh

@Kaveh Veuillez lire la section 7 (Remarques historiques) du document original de KMP. Il a de bonnes remarques. Morris a écrit un éditeur de texte qui "était trop compliqué à comprendre pour les autres développeurs du système". À propos de Knuth "La première fois dans l'expérience de Knuth que la théorie des automates lui avait appris à résoudre un vrai problème de programmation mieux qu'il ne pouvait le résoudre auparavant". Et "Knuth a été chagriné d'apprendre que Morris avait déjà découvert l'algorithme, sans connaître le théorème de Cook;". AMUSEMENT.
Hendrik

93

L'algorithme de Blum, Floyd, Pratt, Rivest et Tarjan pour trouver le k ème élément d'une liste non triée en temps linéaire est un bel algorithme, qui ne fonctionne que parce que les nombres sont parfaitement adaptés au théorème principal. Cela va comme suit:

  1. Triez chaque séquence de cinq éléments.
  2. Choisissez la médiane dans chacun.
  3. Revenez à trouver la médiane de cette liste.
  4. Pivot sur la médiane des médianes (comme dans Quicksort)
  5. Sélectionnez le bon côté de la liste et la position dans cette liste, et répétez.

3
C'est l'un de mes algorithmes préférés. J'aime cette intuition que j'ai apprise dans le livre de divergences de Chazelle: l'ensemble des médianes de groupes d' éléments est comme un ϵ- réseau pour des intervalles dans la liste ordonnée des nombres entrés. Ainsi , l'algorithme suit un paradigme général: calculer une ε -net rapide, résoudre le problème sur le net, récursion sur une partie de l'entrée pour affiner la solution, jusqu'à ce que vous avez la solution exacte. c'est une technique très utile1/εεε
Sasho Nikolov

5
BTW une fois que vous avez paramétré la taille des groupes, les constantes ne sont pas si magiques. ils sont bien sûr optimisés pour donner la bonne chose dans le théorème principal
Sasho Nikolov

Ruby implementation, gist.github.com/chadbrewbaker/7202412 Existe-t-il une version de l'algorithme utilisant de l'espace (constant, journal) ou devez-vous utiliser un espace de travail linéaire pour conserver les médianes?
Chad Brewbaker

2
L'affirmation selon laquelle "cela ne fonctionne que parce que les nombres sont parfaitement adaptés au théorème principal" n'est pas vraiment vraie. Si vous remplacez le numéro avec un plus grand nombre n , il est facile de voir que les deux chiffres qui doivent résumer à moins de 1 convergent vers à 3 / 4 et 0 , de sorte que tous suffisamment grand n travail. 5 n'est que le premier numéro qui fonctionne, ce n'est pas le seul. 5n13/40n5
Will Sawin

88

La recherche binaire est l'algorithme le plus simple, le plus beau et le plus utile que j'ai jamais rencontré.


Je remplacerais élégant par intuitif. Il n’ya rien d’élégant à ce sujet; sa simplicité est sa vraie beauté.
Robert Massaioli

@ Robert Massaili: J'ai remplacé élégante par belle. Tu avais raison à ce sujet.
Michalmocny

2
Et incroyablement difficile à écrire voir correctement - « Êtes - vous l' un des 10% des programmeurs qui peuvent écrire une recherche binaire? »
jon

Dans mon premier cours d'algorithmes pour diplômés, nous avions des questionnaires de 15 minutes dans lesquels nous devions résoudre 2 à 3 problèmes à la main. Le premier quiz de ce type comprenait un arbre de recherche binaire et deux questions sur les tas. J'étais gêné et consterné d'apprendre que le problème de recherche binaire était mal réglé avant de me faire dire que dans une classe d'environ 30 personnes, il y avait deux bonnes réponses. Mais même en sachant cela, il a été renversant de constater que la communauté professionnelle a mis 15 ans à réussir.
Stella Biderman

84

Je suis surpris de ne pas voir l' algorithme de Floyd-Warshall pour les chemins les plus courts pour toutes les paires ici:

d[]: 2D array. d[i,j] is the cost of edge ij, or inf if there is no such edge.

for k from 1 to n:
  for i from 1 to n:
    for j from 1 to n:
      d[i,j] = min(d[i,j], d[i,k] + d[k,j])

L'un des algorithmes non triviaux les plus courts et les plus clairs, et les performances de sont très rapides si vous considérez qu'il pourrait y avoir des arêtes O ( n 2 ) . Ce serait mon enfant d'affiche pour la programmation dynamique!O(n3)O(n2)


2
Cet algorithme peut également être généralisé de manière très soignée. Voir, par exemple, r6.ca/blog/20110808T035622Z.html et cl.cam.ac.uk/~sd601/papers/semirings.pdf
Mikhail Glushenkov


73

Cela peut sembler un peu trivial (surtout en comparaison avec les autres réponses), mais je pense que Quicksort est vraiment élégant. Je me souviens que lorsque je l’ai vu pour la première fois, j’ai pensé que c’était vraiment compliqué, mais maintenant cela semble trop simple.


10
Quicksort soulève également des questions intéressantes sur ce qu'est l'essence d'un algorithme. Par exemple, l'implémentation élégante et standard de Haskell ressemble exactement à la définition standard du pseudo-code, mais sa complexité asymptotique est différente. Alors, est-ce que Quicksort est sur le point de diviser et de conquérir ou est-ce que l'intelligent jeu de pointeur in situ est un élément essentiel de Quicksort? Quicksort peut-il même être implémenté dans un cadre purement fonctionnel ou nécessite-t-il une mutabilité?
Jörg W Mittag

2
L’idée de «l’essence» ou de la «morale» d’un algorithme vient bien sûr du très beau papier The Genuine Sieve of Eratosthenes de Melissa E. O'Neill ( cs.hmc.edu/~oneill/papers/Sieve-JFP. pdf ) et la discussion rapide provient de la discussion de ce document par le LtU ( lambda-the-ultimate.org/node/3127 ), plus précisément à partir de ce commentaire: lambda-the-ultimate.org/node/3127/#comment-45549
Jörg W Mittag

8
@ Jörg: L'implémentation du tri rapide sur les listes chaînées est tout à fait judicieuse et a le même temps d'exécution asymptotique que son implémentation en place sur les tableaux (diable, même l'implémentation naïve hors emplacement sur les tableaux a le même temps d'exécution) - les deux sur moyenne et dans le pire des cas. En ce qui concerne l'utilisation de l'espace, il en va autrement, mais il faut dire que même la version «en place» requiert un espace supplémentaire non constant (pile d'appels!), Un fait facilement négligé.
Konrad Rudolph

Il convient également de mentionner le double rapport de rotation Quicksort de Vladimir Yaroslavskiy. Cela devrait être d' au moins 20% plus rapide quicksort d' origine permalink.gmane.org/gmane.comp.java.openjdk.core-libs.devel/...
SaveTheRbtz

Quicksort en théorie est simple (peut être décrit en 4 étapes) et pourrait être hautement optimisé, mais en pratique, il est très difficile de coder correctement. C'est pourquoi il n'obtient pas mon vote.
Dennis


50

Le test de primalité de Miller-Rabin (et des tests similaires) devrait figurer dans le livre. L'idée est de tirer parti des propriétés des nombres premiers (c'est-à-dire en utilisant le petit théorème de Fermat) pour rechercher de manière probabiliste un témoin du nombre non premier. Si aucun témoin n'est trouvé après suffisamment de tests aléatoires, le nombre est considéré comme premier.

Sur cette note, le test de primalité AKS qui a montré que PRIMES est en P devrait certainement figurer dans The Book!


49

Test d'identité polynomiale avec le lemme de Schwartz-Zippel :

Si quelqu'un vous réveillait au milieu de la nuit et vous demandait de tester l'identité de deux expressions polynomiales univariées, vous les réduiriez probablement à la forme normale de la somme des produits et compareriez l'identité structurelle. Malheureusement, la réduction peut prendre un temps exponentiel. c'est analogue à la réduction des expressions booléennes à une forme normale disjonctive.

En supposant que vous soyez du genre à aimer les algorithmes aléatoires, votre prochaine tentative consisterait probablement à évaluer les polynômes à des points choisis au hasard à la recherche de contre-exemples, en déclarant que les polynômes sont très probablement identiques s'ils passent suffisamment de tests. Le lemme de Schwartz-Zippel montre qu’à mesure que le nombre de points augmente, le risque de faux positif diminue très rapidement.

On ne connaît aucun algorithme déterministe pour le problème qui s'exécute en temps polynomial.


Cela aurait dû être suggéré il y a longtemps! Merci!
arnab

1
Il existe plusieurs autres algorithmes randomisés qui méritent une place de choix dans le livre. Pour ceux-ci, le contraste entre les alternatives déterministes et probabilistes est moins frappant: un algorithme déterministe existe généralement mais est beaucoup plus compliqué.
Per Vognsen

J'ai indépendamment inventé le même algorithme alors que je travaillais sur un papier il y a quelques années, jusqu'à ce que quelqu'un me pose la question, n'est-ce pas le lemme de Schwartz-Zippel? Et j'ai dit, qu'est-ce que c'est? :)
Hélium

46

Recherche approfondie en profondeur . C'est la base de nombreux autres algorithmes. Il est également trompeusement simple: Par exemple, si vous remplacez la file d' attente dans une implémentation BFS par une pile, vous obtenez DFS?


1
C'est aussi la base de l'exécution de Prolog!
muad

1
Quel est l'intérêt de BFS avec une pile qui me manque? J'aurais pensé que la réponse est "oui, vous obtenez DFS".
Omar Antolín-Camarena

1
Eh bien, tout le monde semble penser que ce problème est trivial. En outre, tout le monde semble penser que la réponse est "oui", ce qui est faux. La réponse est en fait "dépend de quelle implémentation BFS vous commencez". Voir cs.stackexchange.com/questions/329/… (C’est une question que j’ai posée pour vous aider lors de la phase bêta de CS.SE)
Radu GRIGore

C'est aussi brièvement discuté ici: ics.uci.edu//~eppstein/161/960215.html
Radu GRIGore

42

Algorithme de Dijkstra : problème du chemin le plus court avec une source unique pour un graphe avec des coûts de chemin de bord non négatifs. Il est utilisé partout et est l'un des plus beaux algorithmes du marché. Internet ne pourrait pas être routé sans elle - c'est une partie essentielle des protocoles de routage IS-IS et OSPF (Open Shortest Path First).

  1. Attribuez à chaque nœud une valeur de distance. Réglez-le à zéro pour notre nœud initial et à l'infini pour tous les autres nœuds.
  2. Marquez tous les nœuds comme non visités. Définir le noeud initial comme courant.
  3. Pour le nœud actuel, considérez tous ses voisins non visités et calculez leur distance provisoire (à partir du nœud initial). Par exemple, si le noeud actuel (A) a une distance de 6 et qu'un bord le reliant à un autre noeud (B) vaut 2, la distance entre B et A sera de 6 + 2 = 8. Si cette distance est inférieure à la distance précédemment enregistrée (infini au début, zéro pour le nœud initial), écrasez la distance.
  4. Lorsque nous avons terminé d’envisager tous les voisins du nœud actuel, marquez-le comme visité. Un nœud visité ne sera plus vérifié; sa distance enregistrée maintenant est finale et minimale.
  5. Si tous les nœuds ont été visités, terminez. Sinon, définissez le nœud non visité avec la plus petite distance (à partir du nœud initial) comme "prochain nœud" et continuez à partir de l'étape 3.


40

Le schéma de cryptage entièrement homomorphique de Gentry (sur des réseaux idéaux ou sur des entiers) est terriblement beau. Il permet à un tiers d'effectuer des calculs arbitraires sur des données chiffrées sans accès à une clé privée.

Le schéma de chiffrement est dû à plusieurs observations attentives.

  • Pour obtenir un schéma de chiffrement entièrement homomorphique, il suffit d'avoir un schéma homomorphique sur l'addition et la multiplication. En effet, l'addition et la multiplication (mod 2) suffisent pour obtenir les portes AND, OR et NOT (et donc la complétude de Turing).
  • Que si un tel système devait être eu, mais en raison de certaines limitations ne pouvaient être exécutées pour les circuits d' une certaine profondeur finie, alors on peut homomorphically évaluer la procédure de décryptage et reencyption pour réinitialiser la limitation de la profondeur de circuit sans sacrifier la vie privée clé.
  • En "écrasant" la profondeur de la version de circuit de la fonction de déchiffrement pour le schéma, on pourrait activer un schéma initialement limité aux circuits finis peu profonds à un nombre arbitraire de calculs.

Dans sa thèse, Craig Gentry a résolu un problème de longue date (et magnifique) en matière de cryptographie. Le fait qu'il existe un schéma totalement homomorphique exige que nous reconnaissions qu'il existe une structure inhérente à la calculabilité que nous aurions pu autrement ignorer.

http://crypto.stanford.edu/craig/craig-thesis.pdf

http://eprint.iacr.org/2009/616.pdf

http://portal.acm.org/citation.cfm?id=1666420.1666445



38

Algorithme de Strassen pour la multiplication matricielle.


J'attendrais probablement jusqu'à ce que nous sachions si c'est optimal.
Thomas Ahle

Ce n'est pas optimal, du moins, asymptotiquement ... Je pense qu'inclure l'algorithme de Strassen vous oblige à inclure d'abord l'algorithme de Karatsuba.
Timothy Sun


34

L'algorithme temporel linéaire pour la construction de tableaux de suffixes est vraiment magnifique, bien qu'il n'ait pas reçu la reconnaissance qu'il méritait http://www.cs.helsinki.fi/u/tpkarkka/publications/icalp03.pdf


Je ne pense qu'il a reçu la reconnaissance qu'elle mérite - ce qui vous fait penser autrement? Par exemple, il est implémenté dans la bibliothèque d'analyse de séquence C ++ SeqAn.
Konrad Rudolph

Il convient de mentionner qu’il existe à présent un certain nombre d’autres algorithmes de construction de matrices de suffixes temporels linéaires et non linéaires qui, bien que loin d’être aussi jolis, pourraient être bien plus rapides en pratique. "Une approche efficace et polyvalente du tri par suffixes", Journal of Experimental Algorithmics (JEA), Volume 12, juin 2008 présente quelques résultats expérimentaux dans ce sens.
Raphaël

@Raphael: Je suis un peu méfiant du fait que sur p. 3 de ce papier JEA, ils ne donnent que ce qu'ils croient "être une relâche" de O (n ^ 2 log n) ... Connaissez-vous des papiers avec des algorithmes à temps linéaire prouvables qui sont plus rapides en pratique que les Skew Algorithm?
user651

32

Élimination gaussienne. Il complète la séquence de généralisation de l'algorithme Euclidean GCD à Knuth-Bendix.


BTW, quelle est la séquence de généralisation et quelle est la place de l'algorithme de Buchberger pour la base de Grobner? (Cela semble analogue à Knuth-Bendix, mais j'ai déjà vu quelque part le fait qu'il généralisait en quelque sorte l'élimination gaussienne…)
ShreevatsaR

6
la séquence est la suivante: GCD euclidienne -> élimination gaussienne -> Buchberger -> Knuth-Bendix. On peut aussi insérer (au lieu d'élimination gaussienne) une division polynomiale univariée et un modulo (dans l'ordre de généralisation, il est «à part» de l'élimination gaussienne, GE est multivarié degré 1, anneau polynomial est degré univarié illimité, la méthode de Buchberger est multivariée degré. le saut de généralisation est le plus important entre EGCD ​​et GE ou l'anneau polynomial en raison de l'ajout de variables, puis également élevé de Buchberger à KB en raison de la signature illimitée
Mitch

+1: l'algorithme euclidien résout l'équation la plus célèbre ax-by = 1 en maths. Pourquoi cela n'apparaît-il pas plus souvent dans CS est un mystère.
Tegiri Nenashi

32

J'ai été impressionné quand j'ai vu pour la première fois l'algorithme d' échantillonnage de réservoir et sa preuve. C’est le casse-tête typique du type "casse-tête" avec une solution extrêmement simple. Je pense que cela appartient définitivement au livre, celui des algorithmes ainsi que celui des théorèmes mathématiques.

En ce qui concerne le livre, on raconte que quand Erdös est mort et est allé au paradis, il a demandé à rencontrer Dieu. La demande fut acceptée et Erdös n'avait qu'une question pour la réunion. "Puis-je regarder dans le livre?" Dieu a dit oui et a conduit Erdös à cela. Naturellement très excité, Erdös ouvre le livre uniquement pour voir ce qui suit.

Théorème 1: ...
Preuve: Évident.

Théorème 2: ...
Preuve: Évident.

Théorème 3: ...
Preuve: Évident.


4
Théorème 4:… Preuve: exercice pour le lecteur.
jon

31

L' algorithme Tortue et lièvre . J'aime ça parce que je suis sûr que même si je perdais toute ma vie à essayer de la trouver, il était impossible que je trouve une telle idée.


6
Connaissez-vous l’algorithme stupide qui résout le problème avec les mêmes asymptotiques et qui suit un modèle de conception algorithmique? Je parle d'approfondissement itératif. Dans la énième itération, vous commencez par le deuxième et le suivant successeur de la racine et vous regardez deux successeurs à la recherche d’une récurrence. Même si vous retracez certaines de vos étapes à chaque itération, le taux de croissance géométrique du rayon de recherche signifie qu'il n'affecte pas les asymptotiques.
Per Vognsen

30

Un exemple aussi fondamental et "trivial" que la preuve par Euclide d'une infinité de nombres premiers:

2 approximations pour MAX-CUT - Indépendamment pour chaque sommet, affectez-le à l'une des deux partitions avec une probabilité égale.


6
Oui, un très bel algorithme. Moins trivialement, au prix d'un facteur 2, cet algorithme fonctionne également pour maximiser toute fonction sous-modulaire, pas seulement la fonction de coupe de graphe. C'est le résultat de Feige, Mirrokni et Vondrak de FOCS 07
Aaron Roth

30

J'ai toujours été partisan de l'algorithme de Christofides qui donne une approximation (3/2) du TSP métrique. En fait, appelez-moi facile à satisfaire, mais j’ai même aimé l’algorithme à 2 approximations qui l’a précédé . L'astuce de Christofides consistant à créer un arbre de poids minimal Eulerian en ajoutant une correspondance à ses sommets de degré impair (au lieu de dupliquer toutes les arêtes) est simple et élégante, et il suffit de peu pour convaincre une personne que cette correspondance n'a pas plus de la moitié du poids. d'un tour optimum.


En effet, il existe également de nombreux autres algorithmes d’approximation simples et élégants offrant des garanties d’approximation décentes.
Janne H. Korhonen


27

O(N) . Il est prouvé de manière optimale et surpasse de manière prouvée tout algorithme classique. Pour un bonus, il est très facile à comprendre et intuitif.


25

Algorithmes de programmation linéaire : méthodes simplex, ellipsoïde et ponctuelle.

http://en.wikipedia.org/wiki/Linear_programming#Algorithms


Et en effet, plusieurs prix Nobel ont été attribués pour avoir permis de mieux comprendre ces problèmes.
Ross Snider

@Ross Kantorovich a remporté le prix Nobel d'économie pour avoir inventé le LP et l'a appliqué à la répartition des ressources. Quels autres prix pensiez-vous?
Mark Reitblatt

@Mark Koopermans a reçu le prix Nobel avec Kantorovich, mais il était toujours inexact de ma part de dire "plusieurs".
Ross Snider

22

Algorithme Robin Moser pour résoudre une certaine classe d'instances SAT. Ces cas peuvent être résolus par Lovasz Local Lemma. L'algorithme de Moser est en effet une désaléotisation de l'énoncé du lemme.

Je pense que cela fait quelques années que son algorithme (et la technique pour la preuve de son exactitude) sera bien digéré et peaufiné au point d’être un candidat viable pour un algorithme tiré du livre .

Cette version est une extension de son papier original, écrit avec Gábor Tardos.



21

L'algorithme X de Knuth trouve toutes les solutions au problème exact de la couverture . Ce qui est vraiment magique, c’est la technique qu’il a proposée pour l’appliquer efficacement: Dancing Links .


20

Je pense que nous devons inclure Schieber-Vishkin , qui répond requêtes des ancêtres communs les plus basses en temps constant, en prétraitant la forêt en temps linéaire.

J'aime l’exposition de Knuth dans le volume 4, fascicule 1, et sa rêverie . Il a dit que cela lui avait pris deux jours entiers pour bien le comprendre, et je me souviens de ses mots:

Je pense que c'est assez beau, mais étonnamment, il a une mauvaise presse dans la littérature (..) C'est basé sur les mathématiques qui m'excite.


10
Attendez, ça peut être beau, mais s'il a fallu deux jours entiers à Knuth pour bien le comprendre, est-ce vraiment «tiré du livre»?
ShreevatsaR

@ShreevatsaR Le livre est bien imprimé dans les notes de bas de page :)
hsmyers
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.