Molto bella domanda!
Hai due volte ragione:
- La propagazione del numero di articoli nello zaino non porta a soluzioni ottimali.
- Una soluzione consiste nell'aggiunta di una terza dimensione. Questo è piuttosto semplice ma è necessario prendere in considerazione alcuni fatti nel farlo. Si noti tuttavia che non è l'unica alternativa
Di seguito, presumo che tu abbia familiarità con la soluzione basata sulla programmazione dinamica. In particolare, non discuterò come attraversare la tabella all'indietro per determinare la soluzione .
Concentriamoci prima sul caso tipico: il numero di articoli è illimitato . In questo caso, è sufficiente creare una tabella cui contenga il valore ottimale quando la capacità complessiva dello zaino è uguale a e vengono considerati solo i primi elementi. Da qui:T i , j i jTTi,jij
Ti,j=max{Ti,j−1,Ti−wj,j−1+vj}
dove e rappresentano rispettivamente il peso e il valore dell'elemento -esimo. Se è la capacità complessiva dello zaino e ci sono in totale articoli, la soluzione ottimale è data da . Questo algoritmo è noto per essere eseguito in tempi pseudo-polinomiali e una delle sue bellezze è che considera solo quelle combinazioni che si adattano alla massima capacità.wjvjjCNTC,N
Tuttavia, questo non è sufficiente quando si aggiunge il vincolo: un numero massimo di elementi . Il motivo è che la precedente formula di ricorrenza non tiene conto delle diverse combinazioni di elementi:p
- Innanzitutto, se quindi modo che l' elemento -esimo viene aggiunto allo zaino nonostante il numero massimo di elementi considerati, --- in modo che tu possa violare il tuo vincolo. Bene, potresti essere tentato qui di applicare la formula precedente tenendo traccia del numero di elementi inseriti in ogni passaggio e non aggiungerne altri se il numero di elementi attualmente nello zaino supera ma,Ti,j−1<(Ti−wj,j−1+vj)Ti,j=(Ti−wj,j−1+vj)jpp
- In secondo luogo, se quindi modo che questo elemento non venga aggiunto ma questo potrebbe essere un grosso errore nel caso in cui la soluzione ottimale consista già nel numero massimo di elementi da inserire nello zaino. Il motivo è che non stiamo confrontando correttamente: da un lato, per preservare la soluzione ottimale composta da elementi selezionati tra i precedenti ; d'altra parte, per inserire l' elemento -esimo e, inoltre, considerare il sottoinsieme migliore con elementi tra i precedenti .Ti,j−1>(Ti−wj,j−1+vj)Ti,j=Ti,j−1Ti,j−1p(j−1)j(p−1)(j−1)
In modo che una prima soluzione consiste nell'aggiungere una terza dimensione. Nel tuo caso, lascia che sia la soluzione ottimale quando la capacità dello zaino è , vengono considerati solo i primi articoli e non è consentito inserire più di articoli nello zaino. Adesso,Ti,j,kijk
- Se stai calcolando per un numero di elementi strettamente inferiore o uguale al numero di elementi che possono essere inseriti ( ), procedi come al solito ma usando lo stesso valore di :Ti,j,kj≤kkTi,j,k=max{Ti,j−1,k,Ti−wj,j−1,k+vj}
- Ora, se devi calcolare per un numero di elementi rigorosamente maggiore del numero di elementi che possono essere inseriti ( ), allora:Ti,j,kj>kTi,j,k=max{Ti,j−1,k,Ti−wj,j−1,k−1+vj}
La prima espressione dovrebbe essere chiara. Il secondo funziona poiché il -th strato della tabella tiene traccia della migliore combinazione di elementi tra i primi come richiesto sopra.(k−1)T(k−1)(j−1)
Un'implementazione efficiente di questo algoritmo non ha bisogno di calcolare per tutti i . Si noti che le precedenti relazioni di ricorrenza riguardano il livello con e quindi è possibile alternare tra due livelli successivi (ad esempio, se si è interessati alla soluzione ottimale con si usano solo due livelli consecutivi: 0 e 1, 1 e 2, 2 e 3, 3 e 4 e il gioco è fatto). In altre parole, questo algoritmo occupa il doppio della memoria richiesta dall'approccio tradizionale basato sulla programmazione dinamica e quindi può essere ancora eseguito in tempo pseudo-polinomiale.Ti,j,kkk(k−1)k=4
Tieni presente, tuttavia, che questa non è l'unica soluzione! E ce n'è un altro che potresti trovare più elegante. Nelle formule precedenti, abbiamo recuperato la soluzione ottimale che consisteva in non più di elementi tra i primi come . Tuttavia, dovrebbe essere chiaro che questo è esattamente uguale a solo usando la tabella originale !! cioè, la soluzione ottimale con non più di articoli può essere recuperata anche considerando le soluzioni ottimali con 1 articolo, 2 articoli, 3 articoli, ...(k−1)(j−1)Ti,j−1,k−1maxp=0,j−1{Ti,p}k(j−1)articoli ... Per far funzionare questa formulazione dovresti anche tenere traccia del numero di elementi considerati in ogni soluzione parziale in modo da avere bisogno di due numeri interi per cella. Questa occupazione di memoria comporta esattamente gli stessi requisiti di memoria dell'algoritmo mostrato sopra (usando una terza dimensione sotto forma di strati )k .
Spero che questo ti aiuti,