Formulario - dati e algoritmi
In questa pagina 11
Nozioni fondamentali
Note: Problemi computazionali e algoritmiProblema computazionale come insieme di coppie (istanza, soluzione); algoritmo e modello di calcolo RAM; pseudocodice; taglia di un'istanza; ADT e struttura dati concreta; esempio svolto con ricerca lineare e binaria in un array ordinato.Problemi computazionali e algoritmi → · Complessità in tempo e caso pessimoPerché lo studio sperimentale non basta; complessità al caso pessimo come massimo sul numero di operazioni tra le istanze di una data taglia; stima con limiti superiore e inferiore senza trovare l'istanza peggiore; esempi arrayMax, prefixAverages e InsertionSort; efficienza asintotica e limiti dell'analisi.Complessità in tempo e caso pessimo → · Notazione asintoticaDefinizioni di O, Omega, Theta e o piccolo con le costanti c ed n0; esempi con costanti esplicite; proprietà (polinomi, esponenziali, logaritmi, somme, implicazioni tra notazioni); sommatorie notevoli; terminologia (logaritmica, lineare, polinomiale, esponenziale).Notazione asintotica → · Dimostrazioni, induzione e invariantiTecniche di dimostrazione (esempio, controesempio, assurdo), induzione con casi base multipli, invarianti di ciclo (inizializzazione, conservazione, uso alla fine), schema generale per provare la correttezza; esempi svolti su arrayMax, sequenza di bit e numeri di Fibonacci.Dimostrazioni, induzione e invarianti → · Algoritmi ricorsiviAlgoritmi ricorsivi come induzione eseguita; albero della ricorsione e record di attivazione nello stack; esempi ReverseArray, LinearSum, Power in tempo logaritmico, Fibonacci ricorsivo (esponenziale) e con memoizzazione; analisi della complessità con l'albero della ricorsione e correttezza per induzione.Algoritmi ricorsivi →
- Caso pessimo nel modello RAMRandom Access Machine: ogni passo elementare costa Θ(1). : ogni istanza costa ; : esiste un'istanza che costa ; con tight e semplice.
- : con per ; : . Polinomio di grado ; (); ; ; e sono falsi.
- Sommatorie: , , . In 1 s con operazioni da 1 ns: (lineare), (), ().
Grafico interattivo: Crescita di n, n·log₂n, n² e 2ⁿ per n da 1 a 10 (numero di operazioni, asse verticale fino a 100): a n = 10 valgono 10, 33, 100 e 1024; l'esponenziale supera il quadrato già da n = 5 e esce dal grafico a n ≈ 6,6
- InsertionSort: confronti sull'array decrescente (caso pessimo), sull'ordinato;
prefixAverages1(doppio ciclo) controprefixAverages2(somma corrente) .
Grafico interattivo: Confronti di InsertionSort in funzione di n: n(n−1)/2 sull'array decrescente (caso pessimo, 45 per n = 10) e n−1 sull'array già ordinato (caso migliore): la complessità al caso pessimo è quadratica, ma su input ordinato l'algoritmo è lineare
- Ricerca lineare ; binaria con e al più iterazioni. Induzione: base , passo da per a . Invariante di ciclo: vale prima, si conserva, a fine ciclo implica la tesi (arrayMax: ).
- Ricorsione: costo = somma sui nodi dell'albero della ricorsione, spazio per profondità .
Power(x,n)con una sola chiamata: . Fibonacci ricorsivo: chiamate, esponenziale; con memoizzazione .
Il linguaggio C
Note: Puntatori, struct e memoria dinamica in CPuntatori e passaggio per riferimento in C, array e aritmetica dei puntatori, stringhe, struct e typedef con l'operatore ->, malloc e free, puntatore a puntatore per modificare una testa; compilazione con Makefile; errori tipici (puntatori pendenti, perdite di memoria, off-by-one).Puntatori, struct e memoria dinamica in C → · Liste concatenate in CLista singolarmente concatenata in C con nodo struct e testa passata per riferimento (Nodo **); addHead, addTail ricorsiva e iterativa, pop, inversione in loco, liberazione; coda con puntatori a testa e coda; ricorsione sulle liste; costi.Liste concatenate in C →
| Elemento | Sintassi essenziale |
|---|---|
| Puntatore | int *p = &x; *p valore, NULL nessun oggetto; passaggio per valore: per modificare si passa &x |
| Array | v[i] *(v+i); negli argomenti decade a puntatore (lunghezza a parte), nessun controllo dei limiti |
| Stringa | char[] terminato da '\0'; strcpy, strcmp (mai ==) |
| Struct | typedef struct nodo { int val; struct nodo *next; } Nodo; . su struct, -> su puntatore |
| Memoria dinamica | malloc(n * sizeof(T)) (controllare NULL), un free per ogni malloc; stack = locali, heap = malloc |
| Puntatore a puntatore | Nodo **l per cambiare testa o radice dal chiamante |
| Compilazione | gcc -std=c99 -Wall -Wextra -o p p.c (-lm per la matematica) |
- Lista in C:
addHead:aux->next = *l; *l = aux;;addTailricorsiva su&(*l)->next;pop: salvarevalenext, poifree; inversione in loco conprec,cur,succ. Coda contestaecoda:enqueueedequeue, aggiornando entrambi quando si svuota.
ADT elementari
| Struttura | Operazioni e costi |
|---|---|
| Lista index-based su array | get, set ; add(i,e), remove(i) ; inserimento in fondo ammortizzato (raddoppio) |
| Lista position-based (doppia, 2 sentinelle) | tutte , scansione solo sequenziale |
| Pila (LIFO) | push, top, pop |
| Coda (FIFO) | enqueue, first, dequeue con lista e puntatore alla coda o array circolare: enqueue in , dequeue |
Alberi
Note: AlberiAlbero radicato (definizione per padre e ricorsiva), terminologia (antenati, discendenti, nodi interni ed esterni, sottoalbero, albero ordinato), profondità, livello, altezza; altezza = massima profondità delle foglie; algoritmi depth e height con costo; somma dei figli = n-1; esempio di algoritmo Omega(n^2) (heightBad).Alberi → · Visite di alberiVisite in preorder e postorder come schemi generali (template) da adattare; complessità Theta(n + somma dei costi di visita) perché la somma dei figli è n-1; esempi (indice di un libro, spazio occupato in un file system); profondità con il preorder, altezza con il postorder; antenato comune più basso.Visite di alberi → · Alberi binariAlbero binario e albero binario proprio; interfaccia; relazioni tra nodi, foglie e altezza (m = n-m+1, h+1 <= m <= 2^h, 2h+1 <= n <= 2^(h+1)-1) con dimostrazioni; visita inorder; parse tree e valutazione di espressioni; heightSum come esempio di calcolo di un'informazione più ricca.Alberi binari →
- , ; , ; .
heightin postorder ;heightBad(depth da ogni foglia) . - Visite: preorder (nodo, poi figli), postorder (figli, poi nodo); costo perché . LCA in . Albero binario proprio ( nodi, foglie, altezza ): , , , . Inorder in un ABR dà le chiavi crescenti.
Grafico interattivo: Altezza h di un albero binario proprio con n nodi: per ogni n sta tra log₂(n + 1) − 1 (albero perfetto, minimo) e (n − 1)/2 (albero a pettine, massimo); con n = 15 vale tra 3 e 7
Code con priorità e heap
Note: Code con prioritàEntry chiave-valore; ADT coda con priorità (insert, min, removeMin) con chiave minima = priorità massima; esempio di esecuzione; applicazioni; implementazioni con lista non ordinata e ordinata e relativi costi; ordinamento tramite coda con priorità.Code con priorità → · HeapAlbero binario completo e sua altezza floor(log2 n); heap = albero completo con heap-order property; proprietà (radice minima, cammini non decrescenti); rappresentazione su array con level numbering; insert con up-heap bubbling, removeMin con down-heap bubbling, rimozione di una entry qualsiasi; invarianti e costi Theta(log n); esempio svolto.Heap → · Costruzione di uno heapCostruire uno heap da un array di n entry: approccio top-down con n-1 insert, Theta(n log n); approccio bottom-up con down-heap dalle foglie verso la radice, Theta(n), con dimostrazione della somma; esempi svolti, in loco; unione di due alberi con heap-order.Costruzione di uno heap →
| Implementazione | insert |
min |
removeMin |
Ordinamento |
|---|---|---|---|---|
| Lista non ordinata | selection sort | |||
| Lista ordinata | insertion sort | |||
| Heap | heap sort |
- Heap = albero completo con ; . Array : figli , padre , .
insertin poi up-heap;removeMin: , , down-heap col figlio minore;removeEntry: up-heap o down-heap. - Costruzione: top-down (up-heap per ) ; bottom-up (down-heap per ) perché .
Grafico interattivo: Scambi al caso peggiore nella costruzione di uno heap con n elementi: top-down su array decrescente, (n+1)·⌊log₂n⌋ − 2^(⌊log₂n⌋+1) + 2 (34 per n = 15, 258 per n = 63, 1538 per n = 255), bottom-up al più n − 1 (somma delle altezze dei nodi: 11, 57 e 247 se n = 2^k − 1)
Mappe e tabelle hash
Note: Mappe e dizionariADT mappa (chiavi distinte) con get, put, remove, keySet/values/entrySet; famiglia mappa/mappa ordinata/dizionario (multimappa); applicazioni; implementazioni semplici ma poco efficienti (lista, array indicizzato dalle chiavi); dizionario realizzato con una mappa di liste.Mappe e dizionari → · Tabelle hashTabella hash per implementare una mappa: funzione hash = hash code + compression function, bucket array, separate chaining; hash code per numeri e stringhe (polynomial, cyclic shift), division e MAD; load factor, complessità al caso pessimo Theta(n) e medio O(1+lambda), rehashing; esempio svolto con inserimenti e collisioni.Tabelle hash →
- Mappa:
get(k),put(k,v)(restituisce il vecchio valore onull),remove(k); lista non ordinata , array indicizzato dalle chiavi ma spazio . Dizionario: chiavi ripetute,remove(k,v)costa in più. - Hash: = hash code + compressione. Divisione ( primo); MAD con primo; stringhe: polinomiale (). Concatenamento separato con : caso pessimo , medio sotto uniform hashing; rehashing se supera una soglia (es. ): , nuova , reinserimento in ammortizzato.
Grafico interattivo: Costo atteso di get, put e remove in una tabella hash con concatenamento separato sotto uniform hashing, O(1 + λ) in funzione del fattore di carico λ = n/N: il rehashing scatta oltre una soglia, per esempio 0,75
Alberi di ricerca
Note: Alberi binari di ricercaAlbero binario di ricerca come albero binario proprio con entry nei nodi interni e foglie vuote; inorder crescente; TreeSearch; get, put e remove (due casi, con predecessore inorder) in Theta(h); altezza fino a n-1; esempi di inserimenti; alberi aumentati con campi size e max e algoritmi di conteggio e interrogazione in O(h).Alberi binari di ricerca → · Multi-way search tree e alberi (2,4)Multi-way search tree (nodi con più entry, d figli e d-1 chiavi ordinate), ricerca in O(d_max h), un MWS tree con n entry ha n+1 foglie; albero (2,4): nodi con 2-4 figli e tutte le foglie alla stessa profondità, altezza Theta(log n) con dimostrazione, operazioni in Theta(log n); idea di overflow e underflow; tabella di confronto con gli alberi binari di ricerca.Multi-way search tree e alberi (2,4) →
| Struttura | get, put, remove |
Altezza |
|---|---|---|
| ABR | , al caso pessimo | |
| Albero (2,4) | ||
| Tabella hash | in media, al caso pessimo | non ordinata |
- ABR: sinistra chiave destra; entry nodi interni e foglie.
removecon due figli interni: si copia l'entry del predecessore inorder (massimo del sottoalbero sinistro) e si elimina quel nodo. Multi-way: -nodo con chiavi,MWTreeSearch. (2,4): 2-4 figli e foglie tutte alla stessa profondità; overflow (5-nodo) si spezza e la terza chiave sale.
Grafico interattivo: Altezza di un albero (2,4) con n entry: tra ½·log₂(n + 1) e log₂(n + 1), quindi Θ(log n); un albero binario di ricerca sbilanciato può invece arrivare a n − 1 (qui fuori scala per n grande)
Alberi e heap in C
- Nodo
struct nodo { int val; struct nodo *left, *right; };altezzaconNULLe1 + max(altezza(left), altezza(right));liberaAlberoin postorder;addBST(Nodo **r, v). Heap su array da indice 1 conlastpassato per puntatore:insert(while (i > 1 && h[i/2] > h[i])scambia) ,downHeap(while (2*i <= last)),bottomUpdalast/2a 1 in .
Algoritmi di ordinamento
| Algoritmo | Pessimo | Migliore / atteso | Note |
|---|---|---|---|
| Selection sort | sempre, | invariante: = i minimi ordinati | |
| Insertion sort | (già ordinato) | ordinato | |
| Merge sort | spazio | ||
| Quick sort | (pivot minimo o massimo) | atteso | partizione in loco |
| Heap sort | spazio | ||
| Conteggio (interi in ) | senza confronti |
- Limite inferiore per i confronti: albero di decisione con foglie, altezza , quindi ; merge sort e heap sort sono ottimi.
Grafico interattivo: Confronti al caso pessimo in funzione di n: selection sort e insertion sort fanno n(n−1)/2, il merge sort n·log₂n − n + 1 (esatto per n potenza di 2); a n = 64 sono 2016 contro 321, mentre l'insertion sort su un array già ordinato ne fa solo n − 1 = 63
Grafi: definizioni e visite
Note: Grafi - definizioni e proprietàGrafo G=(V,E) diretto e non diretto, grafo semplice e pesato; incidenza, adiacenza, grado; cammini, cicli, sottografi, grafi connessi e componenti connesse; alberi liberi, foreste, spanning tree e spanning forest; proprietà con dimostrazioni (somma dei gradi = 2m, m <= n(n-1)/2, alberi m = n-1, connessi m >= n-1, foreste m <= n-1).Grafi - definizioni e proprietà → · Rappresentazione dei grafiStrutture di base (lista dei vertici LV, lista degli archi LE), liste di adiacenza, matrice di adiacenza; operazioni incidentEdges, opposite, areAdjacent; spazio e tempi a confronto; esempio con un grafo di 5 vertici.Rappresentazione dei grafi → · Visite di grafi - BFS e DFSVisite in ampiezza (BFS) e in profondità (DFS) come design pattern; etichette discovery, cross e back edge; BFS tree e distanze; complessità Theta(n+m) con liste di adiacenza; applicazioni (connettività, componenti, spanning tree, cammini minimi non pesati, cicli, vertici a distanza al più d); esempio svolto su un grafo di 7 vertici.Visite di grafi - BFS e DFS →
- , , (semplice non diretto). P1 ; P2 ; P3 albero ; P4 connesso ; P5 foresta . Spanning forest con componenti: archi.
Grafico interattivo: Numero di archi m di un grafo semplice non diretto connesso con n vertici: almeno n − 1 (albero, P4) e al più n(n − 1)/2 (grafo completo, P2); un albero ha esattamente n − 1 archi (P3)
| Operazione | Solo lista archi | Liste di adiacenza | Matrice di adiacenza |
|---|---|---|---|
| Spazio | |||
incidentEdges(v) |
|||
areAdjacent(u,v) |
- BFS: livelli = nuovi vicini di , archi
DISCOVERY/CROSS; . DFS: archiDISCOVERY/BACK, cammini non minimi. Costo con liste di adiacenza (ogni arco visto due volte); per grafi non connessi si rilancia da ogni vertice conID = 0. Con la BFS: connettività, componenti, spanning tree, cammino minimo conparent.
Cammini minimi, alberi di copertura e ordinamento topologico
Note: Cammini minimi e algoritmo di DijkstraGrafi pesati, lunghezza di un cammino e distanza; sottocammini di un cammino minimo; problema SSSP; algoritmo di Dijkstra con cloud e priority queue, rilassamento degli archi, esempio svolto; correttezza (due lemmi) e complessità O(min(n^2, (n+m) log n)) con lista non ordinata o heap; pesi non negativi.Cammini minimi e algoritmo di Dijkstra → · Minimum spanning treeMinimum spanning tree di un grafo pesato connesso; proprietà del taglio (cut property) con dimostrazione; algoritmo di Kruskal con partizioni (union-find) e algoritmo di Prim con coda con priorità; esempio svolto sullo stesso grafo di Dijkstra; complessità O(m log n).Minimum spanning tree → · Grafi diretti e ordinamento topologicoGrafi diretti (archi orientati, grado entrante e uscente, cammini e cicli diretti), visite su grafi diretti e tipi di archi; DAG; ordinamento topologico con l'algoritmo basato sui gradi entranti e con la DFS (reverse postorder), correttezza e costo Theta(n+m); esempio svolto.Grafi diretti e ordinamento topologico →
| Algoritmo | Idea | Costo |
|---|---|---|
| Dijkstra (pesi ) | removeMin di da (chiave v.D) e rilassamento: se u.D + w(u,v) < v.D aggiorna v.D e v.parent |
con heap, con lista non ordinata, |
| Prim | come Dijkstra con v.D <- w(u,v) |
con heap, con lista |
| Kruskal | archi per peso crescente, si aggiunge se collega due componenti diverse (union-find) | |
| Ordine topologico | coda dei vertici con grado entrante 0 oppure reverse postorder della DFS |
- MST: spanning tree di peso minimo, archi; proprietà del taglio: l'arco minimo che attraversa un taglio non attraversato da MST può essere aggiunto. Cammini minimi: sottocammini di cammini minimi sono minimi; pesi tutti 1 BFS. Ordine topologico: per ogni , prima di ; esiste DAG nessun back edge; con
ordinedi meno di vertici c'è un ciclo.
Versione ripasso
- Asintotica: se per ; ; : (Notazione asintoticaDefinizioni di O, Omega, Theta e o piccolo con le costanti c ed n0; esempi con costanti esplicite; proprietà (polinomi, esponenziali, logaritmi, somme, implicazioni tra notazioni); sommatorie notevoli; terminologia (logaritmica, lineare, polinomiale, esponenziale).Notazione asintotica →).
- Sommatorie: , , (Notazione asintoticaDefinizioni di O, Omega, Theta e o piccolo con le costanti c ed n0; esempi con costanti esplicite; proprietà (polinomi, esponenziali, logaritmi, somme, implicazioni tra notazioni); sommatorie notevoli; terminologia (logaritmica, lineare, polinomiale, esponenziale).Notazione asintotica →).
- Ricerca binaria: al più iterazioni (Problemi computazionali e algoritmiProblema computazionale come insieme di coppie (istanza, soluzione); algoritmo e modello di calcolo RAM; pseudocodice; taglia di un'istanza; ADT e struttura dati concreta; esempio svolto con ricerca lineare e binaria in un array ordinato.Problemi computazionali e algoritmi →).
- Fibonacci ricorsivo: chiamate; memoizzazione (Algoritmi ricorsiviAlgoritmi ricorsivi come induzione eseguita; albero della ricorsione e record di attivazione nello stack; esempi ReverseArray, LinearSum, Power in tempo logaritmico, Fibonacci ricorsivo (esponenziale) e con memoizzazione; analisi della complessità con l'albero della ricorsione e correttezza per induzione.Algoritmi ricorsivi →).
- Lista in C:
addHead,addTail,Nodo **per cambiare la testa (Liste concatenate in CLista singolarmente concatenata in C con nodo struct e testa passata per riferimento (Nodo **); addHead, addTail ricorsiva e iterativa, pop, inversione in loco, liberazione; coda con puntatori a testa e coda; ricorsione sulle liste; costi.Liste concatenate in C →). - Alberi: ; visita (Visite di alberiVisite in preorder e postorder come schemi generali (template) da adattare; complessità Theta(n + somma dei costi di visita) perché la somma dei figli è n-1; esempi (indice di un libro, spazio occupato in un file system); profondità con il preorder, altezza con il postorder; antenato comune più basso.Visite di alberi →).
- Binari propri: , , (Alberi binariAlbero binario e albero binario proprio; interfaccia; relazioni tra nodi, foglie e altezza (m = n-m+1, h+1 <= m <= 2^h, 2h+1 <= n <= 2^(h+1)-1) con dimostrazioni; visita inorder; parse tree e valutazione di espressioni; heightSum come esempio di calcolo di un'informazione più ricca.Alberi binari →).
- Heap: figli , padre ;
insert,removeMin; bottom-up (Costruzione di uno heapCostruire uno heap da un array di n entry: approccio top-down con n-1 insert, Theta(n log n); approccio bottom-up con down-heap dalle foglie verso la radice, Theta(n), con dimostrazione della somma; esempi svolti, in loco; unione di due alberi con heap-order.Costruzione di uno heap →). - Hash: , medio , pessimo (Tabelle hashTabella hash per implementare una mappa: funzione hash = hash code + compression function, bucket array, separate chaining; hash code per numeri e stringhe (polynomial, cyclic shift), division e MAD; load factor, complessità al caso pessimo Theta(n) e medio O(1+lambda), rehashing; esempio svolto con inserimenti e collisioni.Tabelle hash →).
- ABR e (2,4): contro ; entry foglie (Multi-way search tree e alberi (2,4)Multi-way search tree (nodi con più entry, d figli e d-1 chiavi ordinate), ricerca in O(d_max h), un MWS tree con n entry ha n+1 foglie; albero (2,4): nodi con 2-4 figli e tutte le foglie alla stessa profondità, altezza Theta(log n) con dimostrazione, operazioni in Theta(log n); idea di overflow e underflow; tabella di confronto con gli alberi binari di ricerca.Multi-way search tree e alberi (2,4) →).
- Ordinamento: selection ; merge e heap ; quick pessimo ; limite (Algoritmi di ordinamentoSelection sort e insertion sort (quadratici, con invarianti), merge sort (divide et impera, Theta(n log n)), quick sort (caso pessimo quadratico, medio n log n), heap sort (in loco, Theta(n log n)), ordinamento senza confronti per chiavi intere in un intervallo piccolo, limite inferiore Omega(n log n) per gli algoritmi basati su confronti.Algoritmi di ordinamento →).
- Grafi: , se connesso (Grafi - definizioni e proprietàGrafo G=(V,E) diretto e non diretto, grafo semplice e pesato; incidenza, adiacenza, grado; cammini, cicli, sottografi, grafi connessi e componenti connesse; alberi liberi, foreste, spanning tree e spanning forest; proprietà con dimostrazioni (somma dei gradi = 2m, m <= n(n-1)/2, alberi m = n-1, connessi m >= n-1, foreste m <= n-1).Grafi - definizioni e proprietà →).
- Visite: BFS e DFS con liste di adiacenza (Visite di grafi - BFS e DFSVisite in ampiezza (BFS) e in profondità (DFS) come design pattern; etichette discovery, cross e back edge; BFS tree e distanze; complessità Theta(n+m) con liste di adiacenza; applicazioni (connettività, componenti, spanning tree, cammini minimi non pesati, cicli, vertici a distanza al più d); esempio svolto su un grafo di 7 vertici.Visite di grafi - BFS e DFS →).
- Dijkstra: con heap, con lista (Cammini minimi e algoritmo di DijkstraGrafi pesati, lunghezza di un cammino e distanza; sottocammini di un cammino minimo; problema SSSP; algoritmo di Dijkstra con cloud e priority queue, rilassamento degli archi, esempio svolto; correttezza (due lemmi) e complessità O(min(n^2, (n+m) log n)) con lista non ordinata o heap; pesi non negativi.Cammini minimi e algoritmo di Dijkstra →).
- MST e topologico: Kruskal ; ordine topologico (Minimum spanning treeMinimum spanning tree di un grafo pesato connesso; proprietà del taglio (cut property) con dimostrazione; algoritmo di Kruskal con partizioni (union-find) e algoritmo di Prim con coda con priorità; esempio svolto sullo stesso grafo di Dijkstra; complessità O(m log n).Minimum spanning tree →).