Como você abordaria o problema da mochila em uma situação de programação dinâmica se agora precisa limitar o número de itens na mochila por um constante ? Esse é o mesmo problema (peso máximo de , cada item tem um valor peso ), mas você só pode adicionar item (s) à mochila e, obviamente, precisa otimizar o valor da mochila.W v w p
Precisamos de uma terceira dimensão ou poderíamos encontrar uma outra abordagem sem ela. Tentei simplesmente adicionar o número de item na mochila na célula e pegar o valor máximo no final com o número de item <= mas não é a melhor solução.
Respostas:
Muito boa pergunta!
Você está duas vezes certo:
A seguir, presumo que você esteja familiarizado com a solução baseada em programação dinâmica. Em particular, não discutirei como reverter a tabela para determinar a solução .
Vamos primeiro focar no caso típico: o número de itens é irrestrito . Nesse caso, você apenas cria uma tabela que T i , j contém o valor ideal quando a capacidade geral da mochila é igual a ie apenas os primeiros itens j são considerados. Daqui:T Ti,j i j
onde e representam o peso e o valor do ésimo item, respectivamente. Se é a capacidade geral da sua mochila e há um total de itens, a solução ideal é dada por . Sabe-se que esse algoritmo é executado em tempo pseudo-polinomial e uma de suas belezas é que ele considera apenas as combinações que atendem à capacidade máxima.v j j C N T C , Nwj vj j C N TC, N
No entanto, isso não é suficiente ao adicionar sua restrição: um número máximo de itens . O motivo é que a fórmula de recorrência anterior não leva em conta diferentes combinações de itens:p
De modo que uma primeira solução consiste em adicionar uma terceira dimensão. No seu caso, seja a solução ideal quando a capacidade da mochila for , apenas os primeiros itens são considerados e não é permitido colocar mais de itens na mochila. Agora, i j kTi,j,k i j k
A primeira expressão deve estar clara. O segundo funciona desde que a camada -ésima da tabela acompanha a melhor combinação de itens entre os primeiros conforme exigido acima.(k−1) T (k−1) (j−1)
Uma implementação eficiente desse algoritmo não precisa calcular para todos os . Observe que os relacionamentos de recorrência anteriores relacionam a camada com e, portanto, é possível alternar entre duas camadas sucessivas (por exemplo, se você estiver interessado na solução ideal com basta usar duas camadas consecutivas: 0 e 1, 1 e 2, 2 e 3, 3 e 4 e pronto). Em outras palavras, esse algoritmo ocupa o dobro da memória exigida pela abordagem tradicional com base na programação dinâmica e, portanto, ainda pode ser executado em tempo pseudo-polinomial. k k ( k - 1 ) k = 4Ti,j,k k k (k−1) k=4
Esteja ciente, no entanto, de que esta não é a única solução! E há outro que você pode achar mais elegante. Nas fórmulas anteriores, recuperamos a solução ótima que consistia em não mais que itens entre os primeiros como . No entanto, deve ficar claro que isso é exatamente igual a apenas usando a tabela original !! ou seja, a solução ideal com não mais que itens também pode ser recuperada considerando-se as soluções ótimas com 1 item, 2 itens, 3 itens, ...( j - 1 ) T i , j - 1 , k - 1 max p = 0 , j - 1 { T i , p } k ( j - 1 ) k(k−1) (j−1) Ti,j−1,k−1 maxp=0,j−1{Ti,p} k (j−1) itens ... Para que essa formulação funcione, você também deve acompanhar o número de itens considerados em cada solução parcial, para precisar de dois números inteiros por célula. Essa ocupação de memória resulta exatamente nos mesmos requisitos de memória do algoritmo mostrado acima (usando uma terceira dimensão na forma de camadas )k .
Espero que isto ajude,
fonte