CAPITOLO 1 NP-completezza 1. La classe P Iniziamo con le seguenti semplici definizioni. Definizione 1.1. Un linguaggio sull’alfabeto Σ è un sottoinsieme di Σ∗ (l’insieme delle stringhe di lunghezza finita su Σ). Tipicamente, l’alfabeto Σ coincide con l’insieme {0, 1}. La teoria dell’NP-completezza e le definizioni delle classi P e NP sono invarianti rispetto alla scelta dell’alfabeto purché questi contenga almeno due simboli. Definizione 1.2. Un algoritmo A decide il linguaggio L se A(x) = 1 se e solo se x ∈ L. Definizione 1.3. Il linguaggio L appartiene alla classe P (in simboli L ∈ P) se esiste un algoritmo A tale che (1) A decide L; (2) esistono una costante n0 ed una una costante c tali che per ogni x ∈ {0, 1}∗ di lunghezza almeno n0 , A si ferma dopo al più |x|c passi. 1.1. (1) (2) (3) Esempi. È facile verificare che ciascuno dei seguenti linguaggi appartiene a P. L = {x|x ha un numero pari di 0}; L = {x|x è la rappresentazione binaria di una potenza di 2}; Il linguaggio L di tutte le quadruple (G, u, v, k) tali che • G è la rappresentazione di un grafo (ad esempio, G è la matrice di adiacenza di un grafo). Per comodità, e con un piccolo abuso di notazione, indicheremo con G sia il grafo che la sua rappresentazione. • u e v sono due vertici di G che si trovano a distanza al più k. 2. La classe NP In questa sezione definiamo la classe di linguaggi NP. Informalmente un linguaggio L appartiene alla classe NP, se è possibile verificare in tempo polinomiale l’appartenenza di una stringa x ad L. Formalmente abbiamo la seguente definizione. Definizione 1.4. Un linguaggio L appartiene alla classe NP se esiste un algoritmo A(·, ·) tale che (1) esistono costanti n0 e c tale che per ogni x, y ∈ {0, 1}∗ con |x| ≥ n0 , A(x, y) si ferma in al più |x|c passi; (2) per ogni stringa x ∈ L esiste una stringa y ∈ {0, 1}? tale che A(x, y) = 1; 1 2 1. NP-COMPLETEZZA (3) per ogni x 6∈ L e per ogni y ∈ {0, 1}? , A(x, y) = 0. In altre parole se L ∈ NP allora per ogni x ∈ L esiste un certificato y di lunghezza polinomiale nella lunghezza di x che è “verificato” da A in tempo polinomiale e se x 6∈ L non esiste alcun certificato y. L’algoritmo A è anche chiamato algoritmo polinomiale di verifica. Nota che, poiché il tempo di esecuzione di A è polinomiale nella lunghezza del primo input, y ha a sua volta lunghezza polinomiale. Consideriamo ad esempio il seguente linguaggio Clique= {(G, k)|G è un grafo che ha un sottografo completo di taglia k}. Per provare che Clique∈ NP dobbiamo esibire un algoritmo polinomiale A che soddisfa la Definizione 1.4. Consideriamo il seguente algoritmo. A((G, k), (v1 , · · · , vl )) 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 10. if l 6= k then return 0; for i = 1 to k for j = i + 1 to k if vi = vj then return 0; for i = 1 to k for j = i + 1 to k if (vi , vj ) non appartiene all’insieme degli archi di G then return 0; return 1; L’algoritmo riceve una coppia (G, k) ed un certificato (v1 , · · · , vl ) per l’appartenenza di (G, k) al linguaggio Clique. L’algoritmo A verifica che il certificato consiste di k vertici (righe 0102), che tutti i k vertici del certificato sono differenti (righe 03-06) e che i vertici del certificato costituiscono un sottografo completo di G (righe 07-10). Se tutte le verifiche hanno successo l’algoritmo restituisce 1; altrimenti l’algoritmo restituisce 0. Osserviamo che se G ha un sottografo completo di taglia k costituito dai vertici (v1 , · · · , vk ) allora l’algoritmo A con input (G, k) e (v1 , · · · , vk ) restituisce 1. Quindi la condizione 2 della Definizione 1.4 è soddisfatta. Se invece G non ha nessun sottografo completo di taglia k allora per ogni sequenza di vertici (v1 , · · · , vl ) almeno una delle seguenti tre condizioni deve essere soddisfatta: (1) l 6= k; in questo caso A restituisce 0 alla riga 02; (2) qualche vertice di G appare due volte nella lista; in questo caso A restituisce 0 alla riga 06; (3) i k vertici sono distinti ma per qualche coppia (i, j) l’arco (vi , vj ) non è un arco di G; in questo caso A restituisce 0 alla riga 10. Quindi se (G, k) 6∈Clique, non esiste nessun certificato per cui A restituisce in output il valore 1. La condizione 3 della Definizione 1.4 è pertanto soddisfatta. Nel prossimo teorema proviamo che L ∈ P allora L ∈ NP. 3. LA CLASSE NP − COMPLETE 3 Teorema 1.5. P ⊆ NP. Dimostrazione. Sia L ∈ P. Allora esiste un algoritmo deterministico A che, su input x, restituisce 1 se e solo se x ∈ L. Si consideri il seguente algoritmo B. B(x, y) 01. return (A(x)); Osserviamo che se x ∈ L allora B(x, 0) = A(x) = 1 e quindi 0 è un certificato. Se invece x 6∈ L allora per ogni possibile certificato y abbiamo che B(x, y) = A(x) = 0. Non è noto se P 6= NP. Sebbene la maggior parte degli studiosi creda che P 6= NP non abbiamo ancora una prova. La Teoria dell’NP-completezza (che verrà discussa nella prossima sezione) identifica i linguaggi più difficili di NP. Se almeno uno di essi ha un algoritmo polinomiale che lo decide allora P = NP. 3. La classe NP − COMPLETE Abbiamo le seguenti definizioni. Definizione 1.6 (Riduzione). Sia L1 e L2 due linguaggi. Diciamo che L1 si riduce a L2 (in simboli L1 ≤p L2 ) se esiste un algoritmo polinomiale R tale che R(x) ∈ L2 se e solo se x ∈ L1 . Definizione 1.7 (NP-completo). Un linguaggio L è NP-completo se (1) L ∈ NP; (2) per ogni linguaggio L0 ∈ NP abbiamo che L0 ≤p L. Denotiamo con NP − COMPLETE la classe dei linguaggi NP-completi. Si noti la similarità della definizione di linguaggio NP-completo con la definizione di massimo di un insieme I definito come quell’elemento x ∈ I tale che, per ogni y ∈ I, vale y ≤ x. La nozione di linguaggio NP-completo esprime formalmente il concetto di linguaggio più difficile di NP. Il seguente teorema rafforza la nostra intuizione dicendoci che se un linguaggio NP-completo appartiene a P allora tutti i linguaggi in NP possono essere decisi in tempo polinomiale. Teorema 1.8. Sia L un linguaggio NP-completo. Se L ∈ P allora P = NP. Dimostrazione. Sia L0 un linguaggio in NP. Mostriamo un algoritmo polinomiale A0 che decide L0 . Poiché L ∈ P allora esiste un algoritmo polinomiale A che decide L. Inoltre, siccome L è NPcompleto e L0 ∈ NP allora esiste un algoritmo polinomiale R che riduce L0 a L. Consideriamo ora il seguente algoritmo A0 A0 (x) 01. y ← R(x); 02. return (A(y)); 4 1. NP-COMPLETEZZA Chiaramente l’algoritmo A0 è polinomiale. Supponiamo che x ∈ L0 . Allora, per le proprietà della riduzione R, y ∈ L e quindi A(y) = 1. Supponiamo ora che x 6∈ L0 . Allora y 6∈ L e quindi A(y) = 0. Possiamo quindi concludere che A0 è polinomiale e decide L0 e quindi L0 ∈ P. Un altro modo di leggere il teorema precedente è che se un linguaggio L è NP-completo allora L è da considerarsi “difficile”. Infatti se P 6= NP, allora non esiste alcuna algoritmo polinomiale che decide L. Il prossimo teorema è particolarmente utile per provare che un linguaggio è NP-completo. Infatti, seguendo la definizione, per provare che un linguaggio L è NP-completo dobbiamo provare che ogni linguaggio in NP si riduce ad esso il che può essere particolarmente difficile. Invece grazie al prossimo teorema basterà mostrare che un linguaggio NP-completo si riduce a L. Iniziamo con il provare il seguente lemma. Lemma 1.9 (Transitività della relazione ≤p .). Sia L, L1 e L2 tre linguaggi tali che L2 ≤p L1 e L1 ≤p L. Allora L2 ≤p L. Dimostrazione. Per ipotesi esistono due riduzioni polinomiali R1 e R2 tali che • x ∈ L2 se e solo se R2 (x) ∈ L1 ; • x ∈ L1 se e solo se R1 (x) ∈ L. Consideriamo il seguente algoritmo. R(x) 01. y1 ← R2 (x); 02. y ← R1 (y1 ); 03. return (y); Per le proprietà degli algoritmi R1 e R2 abbiamo che se x ∈ L2 allora y1 ∈ L1 e quindi y ∈ L; inoltre se x 6∈ L2 allora y1 6∈ L1 e quindi y 6∈ L. Pertanto per l’algoritmo R vale la proprietà x ∈ L2 se e solo se R(x) ∈ L. Inoltre l’algoritmo R è polinomiale e quindi abbiamo che L2 ≤p L. Abbiamo quindi il seguente teorema. Teorema 1.10. Sia L un linguaggio NP e sia L1 un linguaggio NP-completo tale che L1 ≤p L. Allora L è NP-completo. Dimostrazione. Sia L2 un qualsiasi linguaggio NP. Allora L2 ≤p L1 . Applicando il Lemma 1.9 abbiamo che L2 ≤p L. Inoltre per ipotesi abbiamo che L ∈ NP e quindi L è NP-completo. Grazie al Teorema 1.10, per provare che un linguaggio è NP-completo basta provare che un altro linguaggio (che già sappiamo essere NP-completo) si riduce ad esso. Abbiamo però bisogno di un primo linguaggio NP-completo da cui partire. 4. Il linguaggio CNFSAT Una formula booleana Φ sulle variabili (x1 , · · · , xn ) è una formula che contiene i connettivi logici ∧ (AND), ∨ (OR) e ¬ (NOT) e le variabili x1 , · · · , xn . Indichiamo invece con il termine di letterale le variabili in forma negata e forma non negata. Ad esempio Φ = (((x1 ∧ x2 ) ∨ (x1 ∧ ¬x3 )) ∧ (x1 ∨ x4 )) è una formula booleana sulle variabili (x1 , · · · , x4 ). Un assegnamento di 5. IL LINGUAGGIO 3SAT 5 verità t assegna ad ogni variabile della formula Φ un valore booleano ed induce naturalmente un valore booleano t(Φ) della formula Φ. Ad esempio, l’assegnamento t tale che t(x1 ) = 0, t(x2 ) = 1, t(x3 ) = 1 e t(x4 ) = 0 rende la formula formula Φ falsa (cioé t(Φ) = 0). Una formula Φ si dice soddisfattibile se esiste un assegnamento di verità t tale che t(Φ) = 1; in questo caso diciamo che t rende Φ vera. Definiamo il linguaggio SAT come il linguaggio che consiste delle formule booleane Φ che sono soddifacibili. Indichiamo invece con CNFSAT il linguaggio delle formule booleane in forma congiuntiva normale (AND di OR) che sono soddifacibili. Ad esempio la formula Φ = (x1 ∨ x2 ∨ x3 ) ∧ (¬x1 ∨ x2 ∨ x4 ) ∧ (x2 ∨ ¬x4 ) ∧ (x2 ∨ x3 ∨ ¬x4 ∨ x5 ) è in formula congiuntiva normale e consiste di 4 clausole. La prima e la seconda clausola contengono 3 letterali, la terza clausola contiene 2 letterali mentre la quarta clausola contiene 4 letterali. Teorema 1.11. [Cook-Levin] Il linguaggio CNFSATè NP-completo. 5. Il linguaggio 3SAT In questa sezione proviamo che il linguaggio 3SAT consistente di tutte le formule in forma congiuntiva normale ove ogni clausola contiene esattamente 3 letterali è NP-completo. Teorema 1.12. 3SAT∈ NP − COMPLETE. Dimostrazione. Riduciamo CNFSAT a 3SAT e quindi, grazie al Teorema 1.10, otteniamo il teorema. Sia Φ una formula in forma CNF. Costruiamo in tempo polinomiale una formula Φ0 in forma 3CNF (cioè in forma CNF ove ogni clausola contiene esattamente 3 letterali) tale che Φ0 è soddisfattibile se e solo se Φ è soddisfattibile. La costruzione considera ogni clausola C di Φ separatamente e per ognuna di esse costruisce una sequenza S di clausole. La sequenza S di clausole ha la proprietà che un assegnamento di verità soddisfa C se e solo soddisfa S. La formula Φ0 è ottenuta legando insieme con l’operatore ∧ tutte le clausole ottenute. Pertanto abbiamo che Φ0 è soddisfattibile se e solo se Φ è soddisfattibile. La costruzione distingue i seguenti casi. (1) La clausola C contiene un solo letterale a. In questo caso l’insieme S consiste delle seguenti clausole (a∨y1 ∨y2 ) (a∨¬y1 ∨y2 ) (a ∨ y1 ∨ ¬y2 ) (a ∨ y¬1 ∨ ¬y2 ). (2) La clausola C contiene due letterali (a1 ∨ a2 ). In questo caso l’insieme S consiste delle seguenti clausole (a1 ∨a2 ∨y1 ) (a1 ∨a2 ∨¬y1 ) (3) La clausola C contiene tre letterali (a1 ∨ a2 ∨ a3 ). In questo caso l’insieme S consiste della sola clausola C. (4) La clausola C contiene k > 3 letterali (a1 ∨ a2 ∨ a3 ∨ · · · ∨ ak ). In questo caso l’insieme S consiste delle clausole (a1 ∨ a2 ∨ y1 ), (¬y1 ∨ a3 ∨ y2 ), . . . , (¬yk−3 ∨ ak−1 ∨ ak ). Consideriamo per esempio la formula Φ = (x1 ∨ x2 ∨ x3 ) ∧ (¬x1 ∨ x2 ∨ x4 ) ∧ (x2 ∨ ¬x4 ) ∧ (x2 ∨ x3 ∨ ¬x4 ∨ x5 ). La formula Φ0 ottenuta è la seguente Φ0 = (x1 ∨x2 ∨x3 )∧(¬x1 ∨x2 ∨x4 )∧(x2 ∨¬x4 ∨y1 )∧(x2 ∨¬x4 ∨¬y1 )∧(x2 ∨x3 ∨y2 )∧(¬y2 ∨¬x4 ∨x5 ). 6 1. NP-COMPLETEZZA 6. Il linguaggio Clique In questa sezione mostriamo che il linguaggio Clique è NP-completo mostrando una riduzione da 3SAT. Teorema 1.13. Clique∈ NP − COMPLETE. Dimostrazione. Sia Φ una formula in forma CNF ove ogni clausola contiene esattamente 3 letterali. Sia inoltre k il numero di clausole di Φ. La riduzione restituisce la coppia (G, k) ove il grafo G è costruito nel modo seguente. Il grafo G ha un vertice per ogni occorrenza di un letterale: Se il letterale xi appartiene alla j-esima clausola di Φ, il grafo G conterrà il vertice v(i, j); diremo in questo caso che il vertice v(i, j) appartiene alla j-esima clausola. Se il letterale ¬xi appartiene alla j-esima clausola di φ allora il grafo G conterrà il vertice n(i, j); diremo in questo caso che il vertice n(i, j) appartiene alla j-esima clausola di φ. Ogni vertice di G ha un arco verso ogni altro vertice di G con le seguenti eccezioni: (1) non ci sono archi tra vertici della stessa clausola; (2) non ci sono archi tra vertici corrispondenti ad un letterale ed al suo negato, anche se appartengono a clausole differenti. Dimostriamo che Φ ∈ 3SAT se e solo se (G, k) ∈ Clique. (1) Supponiamo che Φ ∈ 3SAT. Allora esiste un assegnamento di verità t tale che per ogni clausola esiste almeno un letterale vero. Consideriamo quindi k vertici (uno per clausola) di G corrispondenti a letterali di Φ veri per l’assegnamento t e mostriamo che constituiscono una clique in G. Infatti, questi k vertici appartengono a clausole differenti e non abbiamo tra questi vertici v(i, j) e n(i, j 0 ) cossipondenti ad una variabile xi ed al suo negato ¬xi (altrimenti t non sarebbe un buon assegnamento di verità). Pertanto i k vertici costituiscono un sottografo completo di taglia k e quindi (G, k) ∈ Clique. (2) Supponiamo che (G, k) ∈ Clique. Allora esiste un sottografo completo C di k vertici in G. Per costruzione di G abbiamo che (a) ogni vertice di C appartiene ad una differente clausola di Φ ed ogni clausola di Φ contiene un vertice di C; (b) se v(i, j) appartiene a C allora certamente n(i, j 0 ) non appartiene a C. Consideriamo quindi l’assegnamento di verità t che pone a vero tutti letterali corrispondenti a vertici di C. L’assegnamento t è certamente legale per la proprietà (2b) e, per la proprietà (2a), soddisfa tutte le clausole di Φ. Quindi Φ ∈ 3SAT. 7. Il linguaggio 3Col Il linguaggio 3Col consiste di tutti i grafi i cui vertici possono essere colorati usando 3 colori in modo tale che due vertici adiacenti sono colorati con colori diversi. È facile verificare che 3Col ∈ NP. Riduciamo 3SAT a 3Col usando i tre gadget descritti dalla Figura 1. In particolare la riduzione per la formula Φ sulle variabile x1 , · · · , xn costruisce un grafo che contiene: (1) un gadget per il vero e falso; 8. ESERCIZI ~ ~ ......... ..X ..... ......... ..... ..... ..... ..... . . . . ..... ..... ..... ..... ..... . . . . ..... .... . ..... . . ... ..... . . . . ..... ... . . . ..... . ... V F ~ 7 ......... ..X ..... ......... ..... ..... ..... ..... . . . . ..... ..... ..... ..... ..... . . . . ..... .... . ..... . . ... ..... . . . . ..... ... . . . ..... . a... ¬a ~ ~ Il gadget per il vero ed il falso ~ Il gadget per la variable a ~ V ......... ..... ......... ..... ..... ..... ..... ..... ..... . . . . . ..... ..... ..... ..... ..... . . . . ..... .... . . . ..... . ... . ..... . . . ..... .... . . . ... . .. ~ ~ ~ ...... ... ..... ... ... ... ... . . ... ... ... ... ... . . ... .. . . ... .. . ... . .. ... . . .. ... ~ ~ ~ b a ~ Il gadget per la clausola (a ∨ b ∨ c) ~ c Figura 1. I tre gadget per la riduzione di 3SAT a 3Col. (2) un gadget per ciascuno delle variabile; nota che i gadget delle variabili condividono il vertice X con il gadget per il vero e il falso; (3) un gadget per ogni clausola; nota che il gadget per la clausola (a ∨ b ∨ c) condivide il vertice a con il gadget della variabile a, il vertice b con il gadget della variabile b, il vertice c con il gadget della variabile c ed il vertice V con il gadget per il vero e falso. Notiamo che il gadget per le variabili impone che i vertici a e ¬a devono essere colorati uno con V ed uno con F. Possiamo inoltre verificare che se i tre vertici dei letterali di una clausola C sono colorati con F allora non è possibile colorare i restanti vertici del gadget di C. Se invece almeno uno di essi è colorato con V allora è possibile completare la colorazione del gadget di C. Abbiamo quindi il seguente Teorema 1.14. 3Col ∈ NP − COMPLETE. 8. Esercizi Esercizio 1. Se L è un linguaggio, definiamo L̄ (il complemento di L) come la differenza simmetrica L̄ = Σ∗ \ L. Provare che se L ∈ P allora L̄ ∈ P . 8 1. NP-COMPLETEZZA Esercizio 2. Denotiamo con co-NP la classe dei linguaggi L tali che L̄ ∈ NP. Provare che se NP 6= co-NP allora P 6= NP. Esercizio 3. Sia L1 , L2 ∈ NP. Provare che L1 ∪ L2 e L1 ∩ L2 sono entrambi in NP. Esercizio 4. Sia L un linguaggio. Definiamo il linguaggio L? come il linguaggio di tutte le stringhe w tali che esistono w1 , · · · , wk per cui (1) w = w1 ◦ · · · ◦ wk (“◦” denota la concatenazione di stringhe); (2) w1 , · · · , wk ∈ L; Provare che se L ∈ NP allora L? ∈ NP. L? Esercizio 5. Usando la notazione dell’esercizio precedente, provare che se L ∈ P allora ∈ P. Esercizio 6. Si consideri il linguaggio Hamilton dei grafi hamiltoniani. Un grafo è detto hamiltoniano se esiste un cammino che visita tutti i vertici una sola volta. Provare che Hamilton∈ NP. Esercizio 7. Provare l’equivalenza tra il problema decisionale e il problema di ricerca per il linguaggio Clique. Esercizio 8. Supponiamo che esista un oracolo O per decidere il linguaggio NP-completo L. Provare che esiste un algoritmo polinomiale che usa O come oracolo, effettua un numero polinomiale di chiamate ad O e risolve il problema di ricerca associato ad L. Esercizio 9. Abbiamo un trasmettitore che vuole inviare un messaggio ad un insieme D = {d1 , · · · , dm } di m destinazioni. Il trasmettitore è collegato ad n coppie di ripetitori (ai , bi ), i = 1, · · · , n ed ogni ripetitore ai (rispettivamente bi ) è collegato ad un sottoinsieme Ai (rispettivamente Bi ) di destinazioni. Per evitare interferenze per ogni coppia di ripetitori (ai , bi ) possiamo avere esattamente un solo ripetitore attivo. Diciamo che è possibile trasmettere il messaggio se esiste un modo di attivare i ripetitori in modo tale che per ogni coppia solo un ripetitore è attivo ed ogni destinazione è adiacente ad almeno un ripetitore attivo. Provare che decidere se una trasmisisone è possibile è NP-completo. Esercizio 10. Provare che il problema di determinare se una formula Φ in forma congiuntiva normale con esattamente 3 letterali per clausola ammette un assegnamento di verità tale che per ogni clausola esistono almeno due letterali veri è decidibile in tempo polinomiale. Esercizio 11. Provare che il problema di determinare se una formula Φ in forma congiuntiva normale con esattamente 3 letterali per clausola e dove ogni letterale compare esattamente 3 volte ammette un assegnamento di verità che la soddisfa è decidibile in tempo polinomiale. Esercizio 12. Abbiamo provato che Max2SAT è completo. Questo non significa che Max2SAT è difficile per tutte le classi di input. Provare che è possibile decidere in tempo polinomiale se (Φ, m − 1) ∈ Max2SAT, dove m è il numero di clausole di Φ. Estendere questo risultato al caso (Φ, m − c) per ogni costante c > 0. Esercizio 13. Un monomio è un AND di letterali. Una formula è in forma disgiuntiva normale (DNF in breve) se è un OR di monomi. Ad esempio la seguente formula è in forma DNF Φ = (x1 ∧ x2 ∧ x3 ) ∨ (¬x1 ∧ ¬x2 ∧ x4 ). NOTE BIBLIOGRAFICHE 9 Definiamo il linguaggio DNFSAT come il linguaggio delle formule in DNF che sono soddisfattibili. Provare che DNFSAT ∈ P. Esercizio 14. Data una formula in 3CNF possiamo usare la legge distributiva per construire una formula equivalente in DNF. Ad esempio abbiamo che (x1 ∨ x2 ∨ ¬x3 ) ∧ (¬x1 ∨ ¬x2 ) ≡ (x1 ∧ ¬x1 ) ∨ (x1 ∧ ¬x2 ) ∨ (x2 ∧ ¬x1 ) ∨ (¬x3 ∧ ¬x1 ) ∨ (¬x3 ∧ ¬x2 ). Poiché abbiamo visto che DNFSAT∈ P (Esercizio 13) abbiamo che P = NP. Dove è l’errore? Note bibliografiche La teoria dell’NP-completezza è stata introdotta da S. Cook in [2] (che ha provato che il linguaggio delle formule in forma disgiuntiva normale che non sono una tautologia è completo) e da L. Levin in [6] (che ha provato la completezza di diversi linguaggi). La prova dell’NPcompletezza di Clique e dei Grafi di Hamilton è stata data da Karp [5]. Il libro di Garey e Johnson [4] è un’ottima guida alla teoria dell’NP-completezza. Versione: 1.38 del 18 novembre 2005. Capitolo tratto dagli appunti del corso avanzato di Algoritmi e Strutture Dati di G. Persiano. Versione corrente disponibile all’URL http://libeccio.dia.unisa.it/ASDII/2005/Appunti/PNP.pdf. Bibliografia [1] Stephen A. Cook. The complexity of theorem-proving procedures. In Proceedings of the third annual ACM symposium on Theory of computing, pages 151–158. ACM Press, 1971. [2] M.R. Garey and D.S. Johnson. Computers and Intractability. Freeman, 1979. [3] R. M. Karp. Reducibility among combinatorial problems. Complexity of Computer Computations, pages 85–103, 1972. [4] L. Levin. Universal sequential search problems. Problemy Peredachi Informatsii, 9(3):265–266, 1973. 11