La programmation dynamique peut réduire le temps nécessaire pour exécuter un algorithme récursif. Je sais que la programmation dynamique peut aider à réduire la complexité temporelle des algorithmes. Les conditions générales sont-elles telles que si elles sont satisfaites par un algorithme récursif, cela impliquerait que l'utilisation de la programmation dynamique réduira la complexité temporelle de l'algorithme? Quand dois-je utiliser la programmation dynamique?
13
Réponses:
La programmation dynamique est utile si votre algorithme récursif se retrouve plusieurs fois dans les mêmes situations (paramètres d'entrée). Il y a une transformation générale des algorithmes récursifs à la programmation dynamique connue sous le nom de mémorisation , dans laquelle il y a un tableau stockant tous les résultats jamais calculés par votre procédure récursive. Lorsque la procédure récursive est appelée sur un ensemble d'entrées déjà utilisées, les résultats sont simplement extraits de la table. Cela réduit Fibonacci récursif à Fibonacci itératif.
La programmation dynamique peut être encore plus intelligente, en appliquant des optimisations plus spécifiques. Par exemple, il n'est parfois pas nécessaire de stocker la table entière en mémoire à un moment donné.
la source
Si vous cherchez simplement à accélérer votre algorithme récursif, la mémoisation pourrait être suffisante. Il s'agit de la technique de stockage des résultats des appels de fonction afin que les appels futurs avec les mêmes paramètres puissent simplement réutiliser le résultat. Ceci est applicable si (et seulement si) votre fonction
Cela vous fera gagner du temps si (et seulement si) la fonction est appelée avec les mêmes paramètres encore et encore. Des exemples populaires incluent la définition récursive des nombres de Fibonacci, c'est-à-dire
Lorsqu'il est évalué naïvement, est souvent appelé exponentiellement. Avec la mémoisation, a toujours été calculé par déjà, donc il ne reste qu'un nombre linéaire d'appels.f ( n ) f ( n + 1 )f f(n) f(n+1)
Notez que, en revanche, la mémoisation est presque inutile pour des algorithmes comme le tri par fusion: généralement peu (le cas échéant) de listes partielles sont identiques, et les contrôles d'égalité sont chers (le tri n'est que légèrement plus coûteux!).
Dans les implémentations pratiques, la façon dont vous stockez les résultats est d'une grande importance pour les performances. L'utilisation de tables de hachage peut être le choix évident, mais peut casser la localité. Si vos paramètres sont des entiers non négatifs, les tableaux sont un choix naturel mais peuvent entraîner une surcharge de mémoire énorme si vous n'utilisez que certaines entrées. Par conséquent, la mémoisation est un compromis entre effet et coût; son efficacité dépend de votre scénario spécifique.
La programmation dynamique est une bête complètement différente. Il est applicable aux problèmes avec la propriété qui
Ceci est généralement (implicitement) sous-entendu lorsque les gens invoquent le principe d'optimalité de Bellman .
Maintenant, cela ne décrit qu'une classe de problèmes qui peuvent être exprimés par un certain type de récursivité. Leur évaluation est (souvent) efficace, car la mémoisation peut être appliquée à bon escient (voir ci-dessus); généralement, des sous-problèmes plus petits surviennent en tant que parties de nombreux problèmes plus importants. Les exemples populaires incluent la distance d'édition et l' algorithme Bellman-Ford .
la source