Problema dello zaino: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
mNessun oggetto della modifica
Riga 1:
{{NN|matematica|febbraio 2013}}
[[Immagine:Knapsack.svg|thumb|In questo caso, la soluzione è di mettere nello zaino tre scatole gialle e tre grigie]]
Il '''Problemaproblema dello zaino''', detto anche '''''Knapsack problem''''', è un problema di ottimizzazione combinatoria posto nel modo seguente:.
 
:siaSia dato uno [[zaino]] che possa sopportare un determinato peso. Siano dati inoltre ''<math>N''</math> oggetti, ognuno dei quali caratterizzato da un ''peso'' e un ''valore''. Il problema si propone di scegliere quali di questi oggetti mettere nello zaino per ottenere il maggiore valore senza eccedere il peso sostenibile dallo zaino stesso.
 
== Introduzione ==
Riga 9:
Il problema espresso in maniera più formale diventa:
 
:* ognuno degli ''<math>N''</math> oggetti possiede un peso <math>w_i</math> e un valore <math>c_i</math>;
:* si indica con ''<math>W''</math> il peso massimo sopportabile dallo zaino;
:* la possibilità che un oggetto venga inserito o meno nello zaino è espressa dalle variabili intere <math>x_i</math>.
 
La funzione obiettivo è:
: <math>\max Z = \sum_{i=1}^N c_i\cdot x_i.</math>
 
I vincoli:
: <math>\sum_{i=1}^N w_i\cdot x_i\leq W.</math>
 
In base al tipo di variabili <math>x_i</math> si ha poi la distinzione in:
 
:* '''problema dello zaino 0-1''':
 
:: <math>x_i=\left\{0,1\right\} \quad \forall i=1,...\ldots,N,</math>
: ogni oggetto può esserci o non esserci senza ripetizioni;
 
:* '''problema dello zaino con limiti'''
 
:: <math>x_i \leq b_i \quad \forall i=1,...\ldots,N,</math>
: ogni oggetto non può apparire nello zaino più di un certo numero di volte;
 
:* '''problema dello zaino senza limiti'''
 
:: <math>x_i \in \N \quad \forall i=1,...\ldots,N,</math>
: ogni oggetto può apparire nello zaino un numero arbitrario di volte.
 
Il problema dello zaino è risolto spesso usando la [[programmazione dinamica]], anche se è noto che tale metodo abbia un tempo di risoluzione non lineare per questo genere di problema. Il problema generale dello zaino è un problema [[NP-difficile]], e questo ha indirizzato la ricerca verso il problema [[Subset-sum]] come base per il sistema di [[Public key infrastructure|crittografia a chiave pubblica]], come [[Merkle-Hellman]]. Questi tentativi usavano tipicamente alcuni [[Gruppo (matematica)|gruppi]] oltre agli interi. [[Merkle-Hellman]] e altri algoritmi simili vennero presto abbandonati, in quanto i sottoproblemi di somma che producevano erano risolvibili da algoritmi lineari.
 
La versione decisionale di questo problema è [[NP-completo|NP-completa]] e infatti è uno dei [[21 problemi NP-completi di Karp]].
Riga 46:
Viene descritta di seguito la soluzione per il ''problema dello zaino senza limiti''.
 
Si indichino con <math>c_1,\dotsldots,c_N</math> i guadagni offerti dagli oggetti, e con <math>w_1,\dotsldots,w_N</math> i pesi di ogni oggetto. Si desidera massimizzare il guadagno complessivo rispettando il vincolo che il peso complessivo sia inferiore o uguale al peso massimo consentito <math>W</math>. Ora, si indichi con <math>A(k)</math> il valore massimo di guadagno che si può ottenere rispettando il vincolo che il peso complessivo sia minore od uguale ad <math>k</math>. Ovviamente <math>k\leq W</math>, e <math>A(W)</math> sarà la soluzione del nostro problema.
 
Si definiscono gli <math>A(k)</math> ricorsivamente come di seguito:
 
* <math>A(0) = 0;</math>,
* <math>A(k)=\max \lbrace c_j + A(k - w_j) | w_j \le k \rbrace. </math>.
 
Qui si considera zero il massimo dell'insieme vuoto. Se si tabulano i risultati a partire da <math>A(0)</math> fino a <math>A(W)</math> si ottiene la soluzione. Dato che il calcolo di ogni <math>A(k)</math> implica l'esame di <math>N</math> oggetti (che sono tutti stati calcolati in precedenza), e visto che ci sono <math>W</math> valori di <math>A(k)</math> da calcolare, il tempo impiegato per trovare la soluzione è <math>O(NW)</math>.
Riga 63:
Si può definire <math>A(i,j)</math> ricorsivamente come segue:
 
* <math>A(0, j) = 0,</math>,
* <math>A(i, 0) = 0,</math>,
* <math>A(i,j) = A(i - 1, j)</math> se <math>w_i > j,</math>,
* <math>A(i,j) = \max \lbrace A(i - 1, j), A(i - 1, j - w_i) + c_i \rbrace </math> se <math>w_i\le j.</math>.
 
La soluzione può essere allora trovata calcolando <math>A(n,W)</math>. Per farlo in modo efficiente si può usare una tabella che memorizzi i calcoli fatti precedentemente. Questa soluzione impiegherà quindi un tempo proporzionale a <math>O(nW)</math> e uno spazio anch'esso proporzionale a <math>O(nW)</math>, anche se con alcune piccole modifiche si può ridurre lo spazio utilizzato a <math>O(W)</math>.
Riga 76:
 
== Rilassamento continuo ==
Si dimostra che il rilassamento continuo del problema dello zaino è equivalente all'euristica CUD quando si permettono valori in <math>[0, 1]</math> delle variabili <math>x_i</math> (in particolare una sola variabile avrà valore non binario). In questo modo euristica e rilassamento possono essere risolti simultaneamente in maniera efficiente.
 
== Bibliografia ==