Esercitazione 10 Algorithmi e Strutture Dati (Informatica) A.A 2015/2016

Documenti analoghi
Esercizi Capitolo 11 - Strutture di dati e progettazione di algoritmi

Esercizi Capitolo 10 - Code con priorità e insiemi disgiunti

Esercizi vari. Alberto Montresor. 19 Agosto, 2014

Esercizi Capitolo 10 - Code con priorità e insiemi disgiunti

Problemi, istanze, soluzioni

Algoritmo basato su cancellazione di cicli

Esercitazione 5 Algorithmi e Strutture Dati (Informatica) A.A 2015/2016

Ottimizza la somma. Supponete di avere in input un vettore di n interi positivi distinti V [1... n] e un valore W. Scrivere un algoritmo che:

11.4 Chiusura transitiva

Fondamenti di Informatica 6. Algoritmi e pseudocodifica

Studio degli algoritmi

Fondamenti di Informatica T-1 Modulo 2

Cognome e Nome : Corso e Anno di Immatricolazione: Modalità di Laboratorio (Progetto/Prova) :

Rappresentazione degli algoritmi

Note per la Lezione 4 Ugo Vaccaro

Esercizi Capitolo 6 - Alberi binari di ricerca

Esercizi Capitolo 7 - Hash

Algoritmi greedy. Gli algoritmi che risolvono problemi di ottimizzazione devono in genere operare una sequenza di scelte per arrivare alla soluzione

Algoritmi, Strutture Dati e Programmi. UD 2.b: Programmazione in Pascal

UNIVERSITÀ DEGLI STUDI DI PAVIA FACOLTÀ DI INGEGNERIA. Matlab: esempi ed esercizi

Un algoritmo realizza una relazione funzionale tra i valori di input e quelli di output

Esercizi di Algoritmi e Strutture Dati

Dati e Algoritmi I (Pietracaprina) Esercizi sulle Nozioni di Base

Il problema dello zaino

Esercizi su alberi binari

Esercizi Capitolo 12 - Divide-et-Impera

Algoritmi e strutture di dati 2

Politecnico di Torino Sede di Alessandria Corso di informatica Programmazione in c: introduzione. e mail: sito: users.iol.

Algoritmi e Strutture di Dati (3 a Ed.) String matching. Alan Bertossi, Alberto Montresor

Sommario. Caratterizzazione alternativa di NP: il verificatore polinomiale esempi di problemi in NP

ALGORITMI DI OTTIMIZZAZIONE M Esercizi Parte I

Programmazione dinamica

COMPLESSITÀ COMPUTAZIONALE DEGLI ALGORITMI

PROVETTE D ESAME. Algoritmi e Strutture Dati

Esercizi Capitolo 14 - Algoritmi Greedy

PROGRAMMAZIONE: Le strutture di controllo

Algoritmi e Strutture di Dati (3 a Ed.) Algoritmo dei tre indiani. Alan Bertossi, Alberto Montresor

Programmazione logica e PROLOG. Esercitazione 1. AI - Carlucci Aiello & Nardi, 2007 Esercitazione 1 0

Complementi ed Esercizi di Informatica Teorica II

Algoritmi Greedy. Tecniche Algoritmiche: tecnica greedy (o golosa) Un esempio

Note per la Lezione 6 Ugo Vaccaro

in termini informali: un algoritmo è una sequenza ordinata di operazioni che risolve un problema specifico

Esercitazione 3. Espressioni booleane I comandi if-else e while

Cammini minimi fra tutte le coppie

Problema del cammino minimo

Programmazione a Oggetti e JAVA. Prof. B.Buttarazzi A.A. 2012/2013

Diagramma a blocchi per la selezione, in un mazzo di chiavi, di quella che apre un lucchetto

Algoritmi e Strutture di Dati (3 a Ed.) Errata corrige. Alan Bertossi, Alberto Montresor

PROGRAMMAZIONE STRUTTURATA

Progettazione di Algoritmi

Grafi pesati Minimo albero ricoprente

Laboratorio di Python

Programmazione a blocchi. Algobuild Prof. Sergio Roselli

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 1

Capitolo 3: Gli alberi. Alberi n-ari

Progettazione di Algoritmi

Parte III: Algoritmo di Branch-and-Bound

osservazione: 1 MCD(m,n) min(m,n) = si provano i numeri compresi tra 1 e min(m,n) conviene iniziare da min(m,n) e scendere verso 1

Fondamenti di Informatica

Esercizio 1. E vero che in un AVL il minimo si trova in una foglia o nel penultimo livello? FB = -1. livello 0 FB = -1. livello 1 FB = -1.

Problemi di ordinamento

INFORMATICA DI BASE Linguaggio C Prof. Andrea Borghesan

Grafi (orientati): cammini minimi

Note per la Lezione 7 Ugo Vaccaro

Dati e Algoritmi I (Pietracaprina) Esercizi svolti sui Grafi

Esercizi di Algoritmi e Strutture Dati

Algoritmi e strutture dati

Ottimizzazione nella Gestione dei Progetti - Esercitazione 1: calcolo degli schedule ottimi

Introduzione agli Algoritmi

L algoritmo AKS. L algoritmo AKS. Seminario per il corso di Elementi di Algebra Computazionale. Oscar Papini. 22 luglio 2013

Il problema dello zaino

Array in Fortran 90. Ing. Luca De Santis. Anno accademico 2006/2007. DIS - Dipartimento di informatica e sistemistica

Iterazione. Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 1. Dispensa E07. C. Limongelli Novembre 2007

public static boolean occorre (int[] a, int n) { int i = 0; boolean trovato = false;

Alberi n-ari: specifiche sintattiche e semantiche. Realizzazioni. Visita di alberi n-ari.

Transcript:

Esercitazione 10 Algorithmi e Strutture Dati (Informatica) A.A 2015/2016 Tong Liu May 10, 2016 Elementi fondamentali Un algoritmo non deterministico è un algoritmo che posto di fronte alla necessità di effettuare una decisione, sceglie sempre la trada giusta. L algoritmo pur di interesse teorico, non sono ovviamente utilizzabili in pratica. Tre istruzioni elementari dell algoritmo non deterministico, ciascuna delle quali richieda O(1) tempo di computazione. choice(c): sceglie arbitrariamente un elemento dell insieme finito C failure: blocca la computazione in uno stato di fallimento. success: blocca la computazione in uno stato di successo. La struttura generale di un algoritmo non deterministico si vede lo Pseudocodice 1 Interpretazione del choice(c): Ci sono 2 interpretazioni del choice: 1) choice è un operatore magico, che porta in tempo O(1) la miglior scelta. 2) choice replica il problema di dimensione n in n copie di scelte diverse in tempo O(1), esegue tutto in parallelo e sicuramente non manca mai la scelta migliore. 1

Algorithm 1 Algoritmo non deterministico 1: procedure ALGORITMO-NON-DETERMINISTICO({ opportuni paramteri }) 2: Integer[] S new Integers[1...n] 3: for i = 1 to n do 4: SET C choices(s, n, i,...) prepara le alternative(options) 5: if C = then 6: failure 7: else 8: S[i ] choice(c) choice magico 9: if S[1...i ] è una soluzione then 10: success 11: end if 12: end if 13: end for 14: end procedure Esercizi Programmi non deterministici Esercizio 1 [10/02/2016] Dato un insieme A di n interi, si vuole decidere se esistono tre sottoinsiemi non vuoti S, T e U di A tali che il prodotto degli elementi di S sia uguale alla differenza tra la somma degli elementi di T e la somma degli elementi di U. Si scriva lo pseudocodice di un algoritmo non deterministico di complessità polinomiale. La soluzione è descritta nello Pseudocodice 2. In pratica, l algoritmo scorre su tutti gli elementi di A, la funzione choice() decide per ciascun elemento se farne una copia nell sottoinsieme (S, T,U ) in modo indipendemente, se sì, aggiorna la variabile di verifica corripondente al sottoinsieme (tra s, t, u). In fine, controlla se le condizioni sono soddisfate. L operazione choice() ha un costo O(1) quindi il costo della procedura è O(n). Esercizio 2 [27/01/2015] Dato un insieme A di n interi distinti, si vuole decidere se esistono tre sottoinsiemi S,T e U disgiunti e non vuoti, tali che S abbia cardinalità uguale a 3 ed il prodotto degli elementi in T sia uguale al doppio della somma degli elementi in U. Scrivere lo pseudocodice di un algoritmo non deterministico che richieda tempo polinomiale. Essendo che la choice O(1) la procedura è O(n), la choice decide il valore u scelto da A se è opportuno inserirlo in S o in T, o in U oppure non inserirlo proprio. Una volta creati S, T e 2

Algorithm 2 nd tre sottoinsiemi 1: procedure ND-TRE-SOTTOINSIEMI(Set A) 2: SET S, T,U SET() 3: Boolean vuotos,vuotot,vuotou true 4: Integer s 1 5: Integer t,u 0 6: for i = 1 to n do 7: S[i ] choice{true, false} 8: T [i ] choice{true, false} 9: U [i ] choice{true, false} 10: if S[i ] = true then 11: s s A[i ] 12: vuotos false 13: end if 14: if T [i ] = true then 15: t t + A[i ] 16: vuotot false 17: end if 18: if U [i ] = true then 19: u u + A[i ] 20: vuotou false 21: end if 22: end for 23: if not vuotos and not vuotot and not vuotou and s = t u then 24: success 25: else 26: failure 27: end if 28: end procedure 3

U, il certificato verifica se la cardinalità di S, e la uguaglianza tra il prodotto degli elementi in T e il doppio della somma degli elementi in U. Se è vero, restituisce true, false altrimenti. Pseudocodice 3 Algorithm 3 nd insiemi disgiunti 1: procedure ND-INSIEMI-DISGIUNTI(Set A) 2: SET S, T,U SET() 3: for all a A do 4: Integer scelta choice({1,2,3,4}) 5: if scelta = 1 then 6: S.insert(a) 7: else if scelta = 2 then 8: T.insert(a) 9: else if scelta = 3 then 10: U.insert(a) 11: end if 12: end for 13: if certificato(s, T,U ) then 14: success 15: else 16: failure 17: end if 18: end procedure 19: procedure CERTIFICATO(Set S, Set T, Set U ) 20: Integer t 1 21: Integer u 0 22: for all e T do 23: t t e 24: end for 25: for all e U do 26: u u + e 27: end for 28: if t = 2 u and S = 3 and T > 0 and U > 0 then S è la cardinalià di S 29: return true 30: end if 31: return false 32: end procedure Esercizio 3 [25/06/2014] In un grafo non orientato, un insieme coprente è un sottoinsieme S di nodi tale che, per ogni arco del grafo, almeno uno dei due nodi estremi dell arco è incluso in S. Si scriva un algoritmo non deterministico di complessità polinomiale che, dati in input un intero k ed 4

un grafo G, decide se esiste un insieme coprente di cardinalità minore o uguale a k. Sia S un insieme di n elementi interi che identifica i nodi, con n uguale al numero di nodi del grafo G = (V, E). Un algoritmo non deterministico per calcolare l insieme coprente è illustrato nello Pseudocodice 4. Nel primo ciclio for, vengono effettuate le scelte dei nodi. Dopodichè viene effettuato il certificato per verificare se l insieme S così generato soddisfi i requisiti. Algorithm 4 Insieme Coprente 1: procedure ND-INSIEME-COPRENTE(Graph G(V,E), Integer k) 2: SET S Set() 3: for all i = 1 G.V do 4: if choice({true,false}) then 5: S.insert(i ) 6: end if 7: end for 8: if certificatocoprentek(g, S, k) then 9: success 10: else 11: failure 12: end if 13: end procedure 14: procedure CERTIFICATOCOPRENTEK(G, S, k) 15: if S.size() > k then 16: return false 17: end if 18: for all (p, q) G.E do 19: if p S and q S then 20: return false 21: end if 22: end for 23: return true 24: end procedure Esercizi esami su Programmazione Dinamica [19/6/2015] Per comprarvi l ultimo gadget tecnologico, avete risparmiato inserendo monete in un salvadanaio. Purtroppo non avete tenuto i conti, e non sapete quanti soldi ci sono dentro. È facile ottenere il valore totale rompendo il salvadanaio, ma sarebbe un peccato romperlo senza essere sicuri che ci siano abbastanza soldi per il vostro gadget. Fortunatamente, avete a disposizione le seguenti informazioni: il peso totale T delle monete contenute nel salvadanaio, il vettore dei pesi p[1...n] e quello dei valori v[1...n], dove p[i ] è il peso in 5

grammi e v[i ] è il valore in centesimi dell i-esimo tipo di moneta fra gli n tipi di monete prodotti nel vostro stato. Scrivere in pseudocodice un algoritmo che restituisca il minimo valore in centesimi che può essere contenuto nel salvadanaio, e valutarne la complessità. Per esempio, supponete che il peso totale sia 50 grammi, e le monete a disposizione siano quella da 200 centesimi, che pesa 50 grammi, e quella da 50 centesimi, che pesa 10 grammi. È possibile ottenere i 50 grammi del peso totale con una singola moneta da 200 centesimi, o con 5 da 50 centesimi per un totale di 250 centesimi. Quindi il valore da restituire è 200, che è il minimo fra i due totali. Per risolvere il problema, utilizziamo memoization. Sia M(i, t) il minimo numero di soldi utilizzando le primi i monete e dovendo pesare t grammi. M(i, t) può essere calcolato ricorsivamente come segue: 0 t = 0 + t < 0 M(i, t) = (1.1) + i = 0 t > 0 min{m(i, t p[i ]) + v[i ], M(i 1, t)} t > 0 i > 0 I quattro casi corrispondono alle situazioni seguenti: Se t = 0, allora 0 grammi sono sufficienti. Se siamo nei casi particolari generati dal quarto caso in cui uno dei due parametri è minore di zero, ritorna + ad indicare che questo caso non può essere considerato. Se non abbiamo più monete ma abbiamo ancora grammi da pesare, ritorna + ad indicare che questo caso non può essere considerato. Altrimenti, considera due possibilità: scegliere l i -esima moneta e continuare ad utilizzarla, o non sceglierla e smettere di utilizzarla. Nel primo caso il peso totale diminuisce di p[i ] e il valore ottenuto aumenta di v[i ]; nel secondo caso diminuisce l indice i. Il costo della procedura è pari a O(nT ), dovuto all inizializzazione del vettore M (al fuori della chiamata ricorsiva). Pseudocodice 5 Esercizio Batteria [25/6/2014] State viaggiando con una modernissima auto elettrica su un autostrada lunga K km; prima che la vostra batteria si esaurisca (dopo r km), dovete fermarvi in un area di servizio e cambiarla con una nuova batteria. Siano D[1,...,n] e C [1,...,n] due vettori di interi, dove D[i ] è la distanza dell area di servizio i-esima dall inizio dell autostrada, e C [i ] è il costo di una nuova batteria nell area di servizio i-esima. Progettare un algoritmo basato su programmazione dinamica che minimizzi il costo totale del viaggio, dimostrandone la correttezza e calcolandone la complessità. 6

Algorithm 5 Pseudocodice salvadanaio 1: procedure SALVADANAIO(integer[] p, integer[] v, integer t, integer i, integer[][] M) 2: if t < 0 then 3: return + 4: end if 5: if i = 0 and t > 0 then 6: return + 7: end if 8: if t = 0 then 9: return 0 10: end if 11: if M[i, t] = nil then 12: M[i, t] min(salvadanaio(p, v, t p[i ],i, M)+v[i ], salvadanaio(p, v, t,i 1, M)) 13: end if 14: return M[i, t] 15: end procedure La sottostruttura ottima è facile da dimostrare, facendo notare che se viene effettuata una ricarica alla stazione i, ci si riduce al problema D[i...n] con una lunghezza della strada pari a K D[i ]; qualunque soluzione ottima per questo problema fa parte della soluzione ottima del problema originale. È possibile definire ricorsivamente il problema come segue. Aggiungiamo le stazioni fittizie D[0] e D[n + 1], al km 0 e K, con costo C [0] = C [n + 1] = 0. Il problema consiste nell individuare il costo minimo M[i ] da pagare nel caso si acquisti la batteria alla stazione i e l importo minimo si deve preparare per arrivare alle stazioni future(include anche la stazione n + 1) può essere definito ricorsivamente come segue: M(i ) = { 0 i = n + 1 C [i ] + min{m[j ] j : j > i D[j ] D[i ] + r } altrimenti (1.2) Inviduare l indice j per cui D[j ] D[i ]+r può richiedere O(n); quindi il costo pessimo di tale algoritmo è O(n 2 ). Il codice è il seguente: Credits: Prof. Alberto Montresor 7

Algorithm 6 Pseudocodice Batteria 1: procedure BATTERIA(integer[] D, integer[] C, integer n) 2: integer[] M new integer[0...n + 1] 3: M[n + 1] 0 4: for i n downto 0 do 5: Integer j i + 1 6: Integer M[i ] = + 7: while j n + 1 and D[j ] D[i ] + r do 8: M[i ] min (M[i ], M[j ]) 9: j j + 1 10: end while 11: M[i ] M[i ] +C [i ] 12: end for 13: return M[0] 14: end procedure Credits: Prof. Alberto Montresor 8