Dividir e conquistar
Divide and Conquer funciona dividindo o problema em subproblemas, conquiste cada subproblema recursivamente e combine essas soluções.
Programaçao dinamica
A programação dinâmica é uma técnica para resolver problemas com subproblemas sobrepostos. Cada subproblema é resolvido apenas uma vez e o resultado de cada subproblema é armazenado em uma tabela (geralmente implementada como uma matriz ou tabela de hash) para futuras referências. Essas sub-soluções podem ser usadas para obter a solução original e a técnica de armazenamento das soluções do sub-problema é conhecida como memorização.
Você pode pensar em DP = recursion + re-use
Um exemplo clássico para entender a diferença seria ver essas duas abordagens para obter o enésimo número de fibonacci. Verifique este material do MIT.
Abordagem de dividir e conquistar
Abordagem de programação dinâmica
A outra diferença entre dividir e conquistar e a programação dinâmica pode ser:
Dividir e conquistar:
Programaçao dinamica:
fonte
às vezes, ao programar recursivamente, você chama a função com os mesmos parâmetros várias vezes, o que não é necessário.
O famoso exemplo de números de Fibonacci:
Vamos executar o F (5):
Então chamamos: 1 vezes F (4) 2 vezes F (3) 3 vezes F (2) 2 vezes F (1)
Abordagem de programação dinâmica: se você chamar uma função com o mesmo parâmetro mais de uma vez, salve o resultado em uma variável para acessá-lo diretamente na próxima vez. A maneira iterativa:
Vamos chamar F (5) novamente:
Como você pode ver, sempre que precisar da chamada múltipla, basta acessar a variável correspondente para obter o valor em vez de recalculá-lo.
A propósito, programação dinâmica não significa converter um código recursivo em um código iterativo. Você também pode salvar os sub-resultados em uma variável se desejar um código recursivo. Nesse caso, a técnica é chamada de memorização. Para o nosso exemplo, fica assim:
Portanto, o relacionamento com o Divide and Conquer é que os algoritmos de D&D dependem de recursão. E algumas versões deles têm essa "chamada de função múltipla com o mesmo problema de parâmetro". Procure por "multiplicação da cadeia da matriz" e "subsequência comum mais longa" para exemplos onde DP é necessário para melhorar o T (n) de algo de D&D.
fonte
Programação dinâmica e semelhanças de dividir e conquistar
Pelo que vejo por enquanto, posso dizer que a programação dinâmica é uma extensão do paradigma de dividir e conquistar .
Eu não os trataria como algo completamente diferente. Como ambos trabalham dividindo recursivamente um problema em dois ou mais subproblemas do mesmo tipo ou relacionados, até que se tornem simples o suficiente para serem resolvidos diretamente. As soluções para os subproblemas são então combinadas para fornecer uma solução para o problema original.
Então, por que ainda temos nomes de paradigmas diferentes e por que chamei a programação dinâmica de extensão? Isso ocorre porque a abordagem de programação dinâmica pode ser aplicada ao problema apenas se o problema tiver certas restrições ou pré-requisitos . Depois disso, a programação dinâmica amplia a abordagem de dividir e conquistar com a técnica de memorização ou tabulação .
Vamos passo a passo ...
Pré-requisitos / restrições de programação dinâmica
Como acabamos de descobrir, existem dois atributos principais que os problemas de divisão e conquista devem ter para que a programação dinâmica seja aplicável:
Subestrutura ideal - a solução ideal pode ser construída a partir de soluções ideais de seus subproblemas
Subproblemas sobrepostos - o problema pode ser dividido em subproblemas que são reutilizados várias vezes ou um algoritmo recursivo para o problema resolve o mesmo subproblema repetidamente, em vez de sempre gerar novos subproblemas
Uma vez atendidas essas duas condições, podemos dizer que esse problema de divisão e conquista pode ser resolvido usando a abordagem de programação dinâmica.
Extensão de programação dinâmica para dividir e conquistar
A abordagem de programação dinâmica estende a abordagem de dividir e conquistar com duas técnicas ( memorização e tabulação ), ambas com o objetivo de armazenar e reutilizar soluções de subproblemas que podem melhorar drasticamente o desempenho. Por exemplo, a implementação recursiva ingênua da função Fibonacci possui complexidade de tempo em
O(2^n)
que a solução DP faz o mesmo com apenasO(n)
tempo.Memoização (preenchimento de cache de cima para baixo) refere-se à técnica de armazenamento em cache e reutilização de resultados calculados anteriormente. A
fib
função memorizada ficaria assim:A tabulação (preenchimento de cache de baixo para cima) é semelhante, mas se concentra no preenchimento das entradas do cache. A computação dos valores no cache é mais fácil de forma iterativa. A versão de tabulação
fib
seria assim:Você pode ler mais sobre memorização e comparação de tabulação aqui .
A idéia principal que você deve entender aqui é que, como nosso problema de divisão e conquista tem subproblemas sobrepostos, o armazenamento em cache de soluções de subproblemas se torna possível e, assim, a memorização / tabulação entra em cena.
Então qual é a diferença entre DP e DC?
Como agora estamos familiarizados com os pré-requisitos de DP e suas metodologias, estamos prontos para colocar tudo o que foi mencionado acima em uma imagem.
Se você quiser ver exemplos de código, pode dar uma olhada em explicações mais detalhadas aqui, onde encontrará dois exemplos de algoritmos: Pesquisa binária e distância mínima de edição (distância de Levenshtein) que ilustram a diferença entre DP e DC.
fonte
Suponho que você já tenha lido a Wikipedia e outros recursos acadêmicos sobre isso, então não reciclarei nenhuma dessas informações. Também devo ressaltar que não sou especialista em ciência da computação, mas vou compartilhar meus dois centavos na minha compreensão desses tópicos ...
Programaçao dinamica
Divide o problema em subproblemas discretos. O algoritmo recursivo para a sequência de Fibonacci é um exemplo de Programação Dinâmica, porque resolve para fib (n) resolvendo primeiro para fib (n-1). Para resolver o problema original, ele resolve um problema diferente .
Dividir e conquistar
Esses algoritmos geralmente resolvem partes semelhantes do problema e, em seguida, as colocam juntas no final. Mergesort é um exemplo clássico de dividir e conquistar. A principal diferença entre este exemplo e o exemplo de Fibonacci é que, em uma fusão, a divisão pode (teoricamente) ser arbitrária e, não importa como você a divide, você ainda está mesclando e classificando. A mesma quantidade de trabalho deve ser feita para mesclar a matriz, não importa como você a divide. A resolução da fib (52) requer mais etapas do que a resolução da fib (2).
fonte
Penso
Divide & Conquer
como uma abordagem recursiva eDynamic Programming
como preenchimento de tabelas.Por exemplo,
Merge Sort
é umDivide & Conquer
algoritmo, pois em cada etapa, você divide a matriz em duas metades, invoca recursivamenteMerge Sort
as duas metades e as mescla.Knapsack
é umDynamic Programming
algoritmo, pois você está preenchendo uma tabela que representa as melhores soluções para os subproblemas da mochila em geral. Cada entrada na tabela corresponde ao valor máximo que você pode carregar em uma bolsa de peso com os itens 1-j.fonte
Divide and Conquer envolve três etapas em cada nível de recursão:
A programação dinâmica envolve as quatro etapas a seguir:
1. Caracterize a estrutura das soluções ideais.
2. Defina recursivamente os valores das soluções ideais.
3. Calcule o valor das soluções ideais.
4. Construa uma solução ideal a partir de informações computadas .
Para um entendimento mais fácil, vamos ver dividir e conquistar como uma solução de força bruta e sua otimização como programação dinâmica.
Os algoritmos de divisão e conquista de notas com subproblemas sobrepostos só podem ser otimizados com dp.
fonte
Como podemos ver acima, nenhum fato (x) é repetido, de modo que o fatorial tem problemas não sobrepostos.
Como podemos ver acima, fib (4) e fib (3) usam ambos fib (2). Da mesma forma, muitos fib (x) são repetidos. é por isso que Fibonacci tem subproblemas sobrepostos.
fonte