Quels sont les problèmes du monde réel où une approche récursive est la solution naturelle en plus de la recherche en profondeur d'abord (DFS)?
(Je ne considère pas la tour de Hanoi , le nombre de Fibonacci ou les problèmes factoriels du monde réel. Ils sont un peu artificiels dans mon esprit.)
Réponses:
Il y a beaucoup d'exemples mathématiques ici, mais vous vouliez un exemple du monde réel , donc avec un peu de réflexion, c'est peut-être le meilleur que je puisse offrir:
Vous trouvez une personne qui a contracté une infection contagieuse donnée, qui n'est pas mortelle, et se corrige rapidement (type A), sauf pour une personne sur 5 (nous les appellerons de type B) qui en devient définitivement infectée et ne montre aucun symptômes et agit simplement comme un épandeur.
Cela crée des vagues de ravages assez ennuyeux chaque fois que le type B infecte une multitude de types A.
Votre tâche est de retrouver tous les types B et de les vacciner pour arrêter l'épine dorsale de la maladie. Malheureusement, vous ne pouvez pas administrer un remède national à tous, car les personnes de type A sont également allergiques mortelles au remède qui fonctionne pour le type B.
La façon dont vous le feriez serait la découverte sociale, étant donné qu'une personne infectée (type A), choisit tous ses contacts la semaine dernière, en marquant chaque contact sur un tas. Lorsque vous testez qu'une personne est infectée, ajoutez-la à la file d'attente de «suivi». Lorsqu'une personne est de type B, ajoutez-la au «suivi» en tête (car vous voulez arrêter ce jeûne).
Après avoir traité une personne donnée, sélectionnez la personne en tête de la file d'attente et appliquez la vaccination si nécessaire. Obtenez tous leurs contacts précédemment non consultés, puis testez pour voir s'ils sont infectés.
Répétez jusqu'à ce que la file d'attente des personnes infectées devienne 0, puis attendez une autre épidémie.
(Ok, c'est un peu itératif, mais c'est une façon itérative de résoudre un problème récursif, dans ce cas, une première traversée d'une population en essayant de découvrir des chemins probables vers des problèmes, et en plus, les solutions itératives sont souvent plus rapides et plus efficaces , et j'enlève de manière compulsive la récursion partout à tel point qu'elle devient instinctive. .... bon sang!)
la source
Un exemple réel de récursivité
la source
Que diriez-vous de tout ce qui concerne une structure de répertoires dans le système de fichiers. Recherche récursive de fichiers, suppression de fichiers, création de répertoires, etc.
Voici une implémentation Java qui imprime de manière récursive le contenu d'un répertoire et de ses sous-répertoires.
la source
Tri rapide , tri par fusion et la plupart des autres tris N-log N.
la source
L'exemple de Matt Dillard est bon. Plus généralement, toute marche dans un arbre peut généralement être gérée par récursivité très facilement. Par exemple, compiler des arbres d'analyse, parcourir XML ou HTML, etc.
la source
La récursivité est souvent utilisée dans les implémentations de l' algorithme Backtracking . Pour une application "réelle" de ceci, que diriez-vous d'un solveur de Sudoku ?
la source
La récursivité est appropriée chaque fois qu'un problème peut être résolu en le divisant en sous-problèmes, qui peuvent utiliser le même algorithme pour les résoudre. Les algorithmes sur les arbres et les listes triées sont un ajustement naturel. De nombreux problèmes de géométrie informatique (et de jeux 3D) peuvent être résolus de manière récursive en utilisant des arbres de partitionnement d'espace binaire (BSP), des subdivisions grasses ou d'autres moyens de diviser le monde en sous-parties.
La récursivité est également appropriée lorsque vous essayez de garantir l'exactitude d'un algorithme. Étant donné une fonction qui prend des entrées immuables et renvoie un résultat qui est une combinaison d'appels récursifs et non récursifs sur les entrées, il est généralement facile de prouver que la fonction est correcte (ou non) en utilisant une induction mathématique. Il est souvent impossible de faire cela avec une fonction itérative ou avec des entrées qui peuvent muter. Cela peut être utile lorsqu'il s'agit de calculs financiers et d'autres applications où l'exactitude est très importante.
la source
Sûrement que de nombreux compilateurs utilisent fortement la récursivité. Les langages informatiques sont eux-mêmes intrinsèquement récursifs (c'est-à-dire que vous pouvez incorporer des instructions «if» dans d'autres instructions «if», etc.).
la source
Désactivation / définition de la lecture seule pour tous les contrôles enfants dans un contrôle conteneur. J'avais besoin de le faire parce que certains des contrôles enfants étaient eux-mêmes des conteneurs.
la source
Célèbre cycle d' évaluation / application du SICP
(source: mit.edu )
Voici la définition de eval:
Voici la définition de appliquer:
Voici la définition de eval-sequence:
eval
->apply
->eval-sequence
->eval
la source
La récursivité est utilisée dans des choses comme les arbres BSP pour la détection de collision dans le développement de jeux (et dans d'autres domaines similaires).
la source
Les gens trient souvent des piles de documents en utilisant une méthode récursive. Par exemple, imaginez que vous triez 100 documents avec des noms dessus. Placez d'abord les documents en piles par la première lettre, puis triez chaque pile.
La recherche de mots dans le dictionnaire est souvent effectuée par une technique de type recherche binaire, qui est récursive.
Dans les organisations, les patrons donnent souvent des commandes aux chefs de service, qui à leur tour donnent des commandes aux gestionnaires, etc.
la source
Exigence du monde réel que j'ai récemment reçue:
Condition A: implémentez cette fonctionnalité après avoir bien compris l'exigence A.
la source
Les analyseurs et compilateurs peuvent être écrits dans une méthode de descente récursive. Ce n'est pas la meilleure façon de le faire, car des outils comme lex / yacc génèrent des analyseurs plus rapides et plus efficaces, mais conceptuellement simples et faciles à implémenter, ils restent donc courants.
la source
La récursivité est appliquée aux problèmes (situations) où vous pouvez le diviser (le réduire) en parties plus petites, et chaque partie ressemble au problème d'origine.
De bons exemples de choses qui contiennent des parties plus petites similaires à lui-même sont:
La récursivité est une technique pour continuer à décomposer le problème en morceaux de plus en plus petits, jusqu'à ce que l'un de ces morceaux devienne suffisamment petit pour être un morceau de gâteau. Bien sûr, après les avoir décomposés, vous devez ensuite «assembler» les résultats dans le bon ordre pour former une solution totale à votre problème initial.
Certains algorithmes de tri récursifs, algorithmes de marche dans les arbres, algorithmes de cartographie / réduction, division-pour-conquérir sont tous des exemples de cette technique.
En programmation informatique, la plupart des langages de type retour d'appel basés sur la pile ont déjà les capacités intégrées pour la récursivité: ie
la source
J'ai un système qui utilise la récursivité de queue pure à quelques endroits pour simuler une machine à états.
la source
Quelques bons exemples de récursivité se trouvent dans les langages de programmation fonctionnels . Dans les langages de programmation fonctionnels ( Erlang , Haskell , ML / OCaml / F # , etc.), il est très courant que tout traitement de liste utilise la récursivité.
Lorsqu'il s'agit de listes dans des langages de style OOP impératifs typiques, il est très courant de voir des listes implémentées sous forme de listes liées ([item1 -> item2 -> item3 -> item4]). Cependant, dans certains langages de programmation fonctionnelle, vous constatez que les listes elles-mêmes sont implémentées de manière récursive, où la "tête" de la liste pointe vers le premier élément de la liste, et la "queue" pointe vers une liste contenant le reste des éléments ( [élément1 -> [élément2 -> [élément3 -> [élément4 -> []]]]]). C'est assez créatif à mon avis.
Cette gestion des listes, lorsqu'elle est combinée avec la correspondance de modèles, est TRÈS puissante. Disons que je veux additionner une liste de nombres:
Cela dit essentiellement "si nous avons été appelés avec une liste vide, retournez 0" (nous permettant de casser la récursivité), sinon retournez la valeur de head + la valeur de Sum appelée avec les éléments restants (d'où notre récursivité).
Par exemple, je pourrais avoir une liste d' URL , je pense séparer toutes les URL vers lesquelles chaque URL renvoie, puis je réduis le nombre total de liens vers / depuis toutes les URL pour générer des "valeurs" pour une page (une approche que Google prend avec PageRank et que vous pouvez trouver défini dans l'article original de MapReduce ). Vous pouvez également le faire pour générer le nombre de mots dans un document. Et beaucoup, beaucoup, beaucoup d'autres choses aussi.
Vous pouvez étendre ce modèle fonctionnel à n'importe quel type de code MapReduce où vous pouvez prendre une liste de quelque chose, le transformer et renvoyer quelque chose d'autre (que ce soit une autre liste ou une commande zip sur la liste).
la source
XML, ou traversant tout ce qui est un arbre. Bien que, pour être honnête, je n'utilise pratiquement jamais la récursivité dans mon travail.
la source
Boucles de rétroaction dans une organisation hiérarchique.
Le supérieur hiérarchique demande aux dirigeants de recueillir les commentaires de tous les membres de l'entreprise.
Chaque cadre rassemble ses subordonnés directs et leur dit de recueillir les commentaires de leurs subordonnés directs.
Et sur toute la ligne.
Les personnes sans rapport direct - les nœuds feuilles de l'arborescence - donnent leur avis.
Les commentaires remontent dans l'arborescence, chaque gestionnaire ajoutant ses propres commentaires.
Finalement, tous les commentaires reviennent au boss supérieur.
C'est la solution naturelle car la méthode récursive permet un filtrage à chaque niveau - le classement des doublons et la suppression des retours offensants. Le supérieur hiérarchique pourrait envoyer un e-mail global et demander à chaque employé de lui faire rapport directement, mais il y a les problèmes «vous ne pouvez pas gérer la vérité» et «vous êtes viré», donc la récursivité fonctionne mieux ici.
la source
Supposons que vous construisez un CMS pour un site Web, où vos pages sont dans une structure arborescente, la racine étant par exemple la page d'accueil.
Supposons également que votre {utilisateur | client | client | patron} vous demande de placer un fil d'Ariane sur chaque page pour montrer où vous vous trouvez dans l'arborescence.
Pour n'importe quelle page n donnée, vous voudrez peut-être marcher jusqu'au parent de n, et à son parent, et ainsi de suite, de manière récursive pour construire une liste de nœuds jusqu'à la racine de l'arborescence des pages.
Bien sûr, vous frappez la base de données plusieurs fois par page dans cet exemple, vous voudrez peut-être utiliser un alias SQL où vous recherchez page-table comme a, et page-table à nouveau comme b, et joignez a.id avec b.parent pour que la base de données effectue les jointures récursives. Cela fait un moment, donc ma syntaxe n'est probablement pas utile.
Là encore, vous souhaiterez peut-être ne calculer cela qu'une seule fois et le stocker avec l'enregistrement de page, en le mettant à jour uniquement si vous déplacez la page. Ce serait probablement plus efficace.
Bref, c'est mon 0,02 $
la source
Vous avez une arborescence d'organisation de N niveaux de profondeur. Plusieurs nœuds sont vérifiés et vous souhaitez étendre uniquement les nœuds qui ont été vérifiés.
C'est quelque chose que j'ai réellement codé. C'est agréable et facile avec la récursivité.
la source
Dans mon travail, nous avons un système avec une structure de données générique qui peut être décrite comme un arbre. Cela signifie que la récursivité est une technique très efficace pour travailler avec les données.
Le résoudre sans récursivité nécessiterait beaucoup de code inutile. Le problème avec la récursivité est qu'il n'est pas facile de suivre ce qui se passe. Vous devez vraiment vous concentrer lorsque vous suivez le déroulement de l'exécution. Mais quand cela fonctionne, le code est élégant et efficace.
la source
Calculs pour la finance / physique, tels que les moyennes composées.
la source
la source
Analyse d'une arborescence de contrôles dans Windows Forms ou WebForms (.NET Windows Forms / ASP.NET ).
la source
Le meilleur exemple que je connaisse est le tri rapide , c'est beaucoup plus simple avec la récursivité. Jeter un coup d'œil à:
shop.oreilly.com/product/9780596510046.do
www.amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047
(Cliquez sur le premier sous-titre sous le chapitre 3: "Le plus beau code que j'aie jamais écrit").
la source
Les entreprises de téléphonie et de câble maintiennent un modèle de leur topologie de câblage, qui est en fait un grand réseau ou un graphique. La récursivité est un moyen de parcourir ce modèle lorsque vous souhaitez rechercher tous les éléments parents ou tous les éléments enfants.
Étant donné que la récursivité est coûteuse du point de vue du traitement et de la mémoire, cette étape n'est généralement effectuée que lorsque la topologie est modifiée et le résultat est stocké dans un format de liste pré-ordonné modifié.
la source
Le raisonnement inductif, le processus de formation de concept, est de nature récursive. Votre cerveau le fait tout le temps, dans le monde réel.
la source
Idem le commentaire sur les compilateurs. Les nœuds de l'arborescence de syntaxe abstraite se prêtent naturellement à la récursivité. Toutes les structures de données récursives (listes chaînées, arbres, graphiques, etc.) sont également plus faciles à gérer avec la récursivité. Je pense que la plupart d'entre nous n'utilisons pas beaucoup la récursivité une fois que nous sommes sortis de l'école à cause des types de problèmes du monde réel, mais il est bon d'en être conscient comme une option.
la source
La multiplication des nombres naturels est un exemple réel de récursivité:
la source