Muito boa pergunta!
Você está duas vezes certo:
- Propagar o número de itens na mochila não leva a soluções ideais.
- Uma solução consiste em adicionar uma terceira dimensão. Isso é bastante simples, mas é necessário levar em consideração alguns fatos ao fazê-lo. Note, no entanto, que não é a única alternativa
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:TTi,jij
Ti,j=max{Ti,j−1,Ti−wj,j−1+vj}
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 , NwjvjjCNTC, 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
- Primeiro, se então para que o ésimo item é adicionado à mochila, apesar do número máximo de itens considerados, --- para que você possa estar violando sua restrição. Bem, você pode ser tentado aqui a aplicar a fórmula anterior, acompanhando o número de itens inseridos em cada etapa e não adicionar outros se o número de itens atualmente na mochila exceder , mas,t i , j = ( T i - w j , j - 1 + v j ) j p pTeu , j - 1< ( Ti - wj, j - 1+ vj)Ti , j= ( Ti - wj, j - 1+ vj)jpp
- Segundo, se então para que este item não seja adicionado, mas isso pode ser um grande erro, caso a solução ideal já consista no número máximo de itens a serem inseridos na mochila. O motivo é que não estamos comparando adequadamente: por um lado, preservar a solução ótima que consiste em itens selecionados entre os anteriores ; por outro lado, para inserir o ésimo item e, adicionalmente, considere o melhor subconjunto com itens entre os itens anteriores .T i , j = T i , j - 1 T i , j - 1 p ( j - 1 ) j ( p - 1 ) ( j - 1 )Teu , j - 1> ( Ti - wj, j - 1+ vj)Ti , j= Teu , j - 1Teu , j - 1p( j - 1 )j( p - 1 )(j−1)
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,kijk
- Se você estiver calculando para um número de itens estritamente menor ou igual ao número de itens que podem ser inseridos ( ), continue como de costume, mas usando o mesmo valor de :Ti,j,kj≤kkTi,j,k=max{Ti,j−1,k,Ti−wj,j−1,k+vj}
- Agora, se você precisar calcular para um número de itens estritamente maior que o número de itens que podem ser inseridos ( ), então:Ti,j,kj>kTi,j,k=max{Ti,j−1,k,Ti−wj,j−1,k−1+vj}
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,kkk(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−1maxp=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,