Je n'arrive pas à comprendre les principes de la programmation dynamique et je le veux vraiment. DP est très puissant, il peut résoudre des problèmes comme celui-ci:
Obtenir la somme la plus basse possible de la différence des nombres
Alors, pouvez-vous me suggérer de bons livres ou articles (avec de préférence des exemples avec du code réel) qui m'expliqueraient ce qu'est la programmation dynamique? Je veux vraiment d’abord des exemples simples, puis je passerai à autre chose.
Programmation dynamique est un type d’algorithme utile qui permet d’optimiser des problèmes difficiles en les décomposant en sous-problèmes plus petits. En stockant et en réutilisant des solutions partielles, il parvient à éviter les pièges d'un algorithme glouton. Il existe deux types de programmation dynamique, de bas en haut et de haut en bas.
Pour qu'un problème puisse être résolu à l'aide de la programmation dynamique, il doit posséder la propriété de ce que l'on appelle une sous-structure optimale . Cela signifie que, si le problème était divisé en une série de sous-problèmes et que la solution optimale était trouvée pour chaque sous-problème, la solution résultante serait alors réalisée grâce à la solution de ces sous-problèmes. Un problème qui n'a pas cette structure ne peut pas être résolu avec une programmation dynamique.
Le top-down est mieux connu sous le nom de memoization . C'est l'idée de stocker les calculs antérieurs afin d'éviter de les recalculer à chaque fois.
Étant donné une fonction récursive, disons:
fib(n) = 0 if n = 0
1 if n = 1
fib(n - 1) + fib(n - 2) if n >= 2
Nous pouvons facilement écrire ceci récursivement à partir de sa forme mathématique sous la forme:
function fib(n)
if(n == 0 || n == 1)
n
else
fib(n-1) + fib(n-2)
Maintenant, quiconque a programmé pendant un certain temps ou en sait quelque chose sur l'efficacité algorithmique vous dira que c'est une idée terrible. La raison en est qu’à chaque étape, vous devez recalculer la valeur de fib (i), où i est 2..n-2.
Un exemple plus efficace consiste à stocker ces valeurs et à créer un algorithme de programmation dynamique de haut en bas.
m = map(int, int)
m[0] = 0
m[1] = 1
function fib(n)
if(m[n] does not exist)
m[n] = fib(n-1) + fib(n-2)
En faisant cela, nous calculons fib (i) au plus une fois.
La méthode ascendante utilise la même technique de mémorisation que celle utilisée dans la méthode descendante. La différence, cependant, est que la méthode ascendante utilise des sous-problèmes comparatifs, appelés récurrences, pour optimiser votre résultat final.
Dans la plupart des problèmes de programmation dynamique ascendants, vous essayez souvent de minimiser ou de maximiser une décision. On vous donne deux (ou plus) options à un moment donné et vous devez décider laquelle est la plus optimale pour le problème que vous essayez de résoudre. Ces décisions, cependant, sont basées sur les choix précédents que vous avez faits.
En prenant la décision la plus optimale à chaque étape (chaque sous-problème), vous vous assurez que votre résultat global est le plus optimal possible.
La partie la plus difficile de ces problèmes consiste à trouver les relations de récurrence permettant de résoudre votre problème.
Pour payer un tas de manuels d’algorithmes, vous envisagez de voler un magasin qui contient n éléments. Le problème est que votre minuscule sac à dos ne peut contenir plus de W kg. Connaissant le poids (w [i]) et la valeur (v [i]) de chaque article, vous voulez maximiser la valeur de vos biens volés qui pèsent tous au plus W. Pour chaque article, vous devez faire un choix binaire - à prendre ou a laisser.
Maintenant, vous devez trouver quel est le sous-problème. En tant que voleur très brillant, vous réalisez que la valeur maximale d'un élément donné, i, avec un poids maximal, w, peut être représentée par m [i, w]. De plus, m [0, w] (0 éléments au maximum poids w) et m [i, 0] (i éléments au poids maximal 0) sera toujours égal à 0.
alors,
m[i, w] = 0 if i = 0 or w = 0
Avec votre masque intégral pensant, vous remarquerez que si vous avez rempli votre sac avec le plus de poids possible, un nouvel élément ne peut être pris en compte que si son poids est inférieur ou égal à la différence entre votre poids maximal et votre poids. le poids actuel du sac. Un autre cas dans lequel vous voudrez peut-être envisager un article est s'il a un poids inférieur ou égal à un article dans le sac, mais une valeur supérieure.
m[i, w] = 0 if i = 0 or w = 0
m[i - 1, w] if w[i] > w
max(m[i - 1, w], m[i - 1, w - w[i]] + v[i]) if w[i] <= w
Ce sont les relations de récurrence décrites ci-dessus. Une fois que vous avez ces relations, l'écriture de l'algorithme est très facile (et courte!).
v = values from item1..itemn
w = weights from item1..itemn
n = number of items
W = maximum weight of knapsack
m[n, n] = array(int, int)
function knapsack
for w=0..W
m[0, w] = 0
for i=1 to n
m[i, 0] = 0
for w=1..W
if w[i] <= w
if v[i] + m[i-1, w - w[i]] > m[i-1, w]
m[i, w] = v[i] + m[i-1, w - w[i]]
else
m[i, w] = m[i-1, w]
else
m[i, w] = c[i-1, w]
return m[n, n]
Heureusement, la programmation dynamique est devenue vraiment in lorsqu'il s'agit de programmation compétitive. Consultez Programmation dynamique sur UVAJudge pour certains problèmes pratiques qui testeront votre capacité à implémenter et à trouver des récurrences pour des problèmes de programmation dynamiques.
En bref, la programmation dynamique est une méthode pour résoudre des problèmes complexes en les décomposant en étapes simples, c'est-à-dire en résolvant un problème étape par étape.
J'espère que ces liens aideront au moins un peu.
Commencer avec
Si vous voulez tester vous-même mes choix concernant les juges en ligne sont
et bien sur
Vous pouvez également vérifier les bons cours d'algorithmes des universités
Après tout, si vous ne pouvez pas résoudre les problèmes, demandez à SO qu'il existe ici de nombreux algorithmes addict
Je pense Programmation dynamique algébrique Mérite d'être mentionné. C'est une présentation assez inspirante de la technique de DP et elle est largement utilisée dans la communauté de la bioinformatique ..__ En outre, le principe d'optimalité de Bellman est énoncé de manière très compréhensible.
Traditionnellement, DP est enseigné par exemple: les algorithmes sont exprimés en termes De récurrences entre les entrées de table qui stockent des solutions aux problèmes intermédiaires, À partir de ce tableau, la solution globale est construite via une analyse de cas.
ADP organise l'algorithme DP de sorte que la décomposition du problème en sous-problèmes Et l'analyse de cas soient complètement séparés de l'optimisation prévue Objectif. Cela permet de réutiliser et de combiner différentes parties des algorithmes DP Pour des problèmes similaires.
Il existe trois parties faiblement couplées dans l'algorithme ADP:
Toutes ces parties sont ensuite automatiquement fusionnées pour donner un algorithme efficace.
Cet article de USACO est un bon point de départ pour comprendre les bases du DP et comment il peut donner des accélérations considérables. Regardez ensuite cet article de TopCoder qui couvre également les bases, mais n’est pas très bien écrit. Ce tutoriel de CMU est également très bon. Une fois que vous aurez compris cela, vous devrez passer au DP 2D pour résoudre le problème auquel vous faites référence. Parcourez cet article de Topcoder } jusqu'à la question des pommes incluse (appelée intermédiaire).
Vous pouvez également trouver utile de regarder cette conférence vidéo MIT }, en fonction de la qualité avec laquelle vous récupérez des vidéos.
Sachez également que vous devez maîtriser parfaitement la récursivité avant de pouvoir capter DP. DP est dur! Mais la vraie difficulté consiste à trouver la solution. Une fois que vous avez compris le concept de PD (auquel vous devriez vous intéresser ci-dessus) et que vous avez présenté l’esquisse d’une solution (par exemple, ma réponse à votre question }, alors ce n’est vraiment pas difficile à appliquer, puisque les solutions de DP sont généralement très concises et pas trop éloignées des versions itératives d’une solution récursive plus facile à comprendre.
Vous devriez également jeter un œil à memoization , que certaines personnes trouvent plus facile à comprendre, mais qui est souvent tout aussi efficace que DP. Pour expliquer brièvement, la mémorisation prend une fonction récursive et met en cache ses résultats pour éviter de les recalculer pour les mêmes arguments à l'avenir.
Presque tous les livres d'introduction aux algorithmes comportent des chapitres consacrés à la programmation dynamique. Je recommanderais:
Si vous voulez en savoir plus sur les algorithmes, j'ai trouvé que MIT disposait d'excellentes vidéos de conférences.
Par exemple, 6.046J/18.410J Introduction aux algorithmes (SMA 5503) semble être un très bon pari.
Le cours couvre la programmation dynamique, parmi beaucoup d'autres techniques algorithmiques utiles. Le livre utilisé est également, à mon avis, tout à fait excellent et très digne d’être un achat pour ceux qui sont sérieux dans l’apprentissage des algorithmes.
En outre, le cours comprend une liste de travaux, etc. Vous aurez ainsi la possibilité d’exercer votre théorie dans la pratique.
Si vous essayez la programmation dynamique pour résoudre un problème, je pense que vous en apprécierez le concept. Dans Google codejam, une fois que les participants ont reçu un programme appelé " Bienvenue dans CodeJam ", il a révélé une excellente utilisation de la programmation dynamique.
MIT Opencourseware 6.00 Introduction à l'informatique et à la programmation
Dans le cadre d’une correspondance, nous avons suivi un cours sur le livre http://www.Amazon.co.uk/Introduction-Programming-International-mathematics-computer/dp/0080250645/ref=sr_1_4?ie=UTF8&qid = 1290713580 & sr = 8-4 Il s’agit vraiment d’un angle mathématique que d’un angle de programmation, mais si vous pouvez économiser du temps et des efforts, c’est une introduction très complète, qui me paraissait être un cours couru plutôt bien. beaucoup hors du livre.
J'ai aussi une première version du livre "Algorithms" de Sedgewick et un court chapitre très lisible sur la programmation dynamique. Il semble maintenant vendre une variété ahurissante de livres coûteux. Sur Amazon, il semble y avoir un chapitre du même nom sur http://www.Amazon.co.uk/gp/product/toc/0201361205/ref=dp_toc?ie=UTF8&n=266239
Planning Algorithms, de Steven LaValle a une section sur la programmation dynamique:
Voir par exemple la section 2.3.1.