4/5/2015E. Giovannetti -- OI09.1 Olimpiadi di Informatica 2010 Giornate preparatorie Dipartimento di Informatica Università di Torino marzo 2010 6 – Algoritmi.

Slides:



Advertisements
Presentazioni simili
INFORMATICA Algoritmi fondamentali
Advertisements

Sottoprogrammi: funzioni e procedure
Ricorsione Procedure e funzioni ricorsive. Definizioni Un oggetto si dice ricorsivo se è definito totalmente o parzialmente in termini di sé stesso La.
Procedure e funzioni ricorsive
PROGRAMMARE IN PASCAL (le basi)
Lez. 11 (11/12) - PBElementi di Programmazione1 Lezione 11 Esercizi.
Algoritmi e Programmazione
Informatica Generale Marzia Buscemi
Problemi di soddisfacimento di vincoli Maria Simi a.a. 2005/2006.
Lez. 121 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Progettazione.
Lez. 91 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Alberi di ricerca.
Lez. 41 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Programmazione.
Programmazione Concorrente
TERNE PITAGORICHE Obiettivi dell’esercitazione
INFORMATICA Strutture iterative
Programmazione Procedurale in Linguaggio C++
Introduzione agli algoritmi. Definizione Sistema di regole e procedure di calcolo ben definite che portano alla soluzione di un problema con un numero.
PROGRAMMI DI RICERCA E ORDINAMENTO
Algebra di Boole ed elementi di logica
Informatica di base A.A. 2003/2004 Algoritmi e programmi
1 Esempi di consistenza sui limiti Non consistente sui limiti, considera Z=2, poi X-3Y=10 Ma il dominio qui sotto e consistente sui limiti: Confrontare.
1 Corso di Informatica (Programmazione) Lezione 10 (12 novembre 2008) Programmazione in Java: espressioni booleane e controllo del flusso (selezione)
Corso di Laurea in Biotecnologie Informatica (Programmazione)
CORSO DI PROGRAMMAZIONE II
Algoritmi e Strutture Dati Valutazione del tempo di esecuzione degli algoritmi.
Il linguaggio Fortran 90: 4. Array: Vettori e Matrici
Introduzione alla programmazione lll
APPUNTI SUL LINGUAGGIO C
1 Implementazione di Linguaggi 2 Implementazione di Linguaggi 2 Federico Bernardi Type checking 2° parte Type checking 2° parte - Equivalenza di type expressions.
Programmazione Corso di laurea in Informatica
Strutture di controllo in C -- Flow Chart --
Politecnico di Milano Esercizi Stringhe Ricerca binaria.
Esercizi Puntatori, struct con campi puntatore, puntatori a struct, rapporto tra array e puntatori. FUNZIONI Passaggio di parametri per indirizzo, passaggio.
Relatori: Emanuele e Denis Tornei Informatici. Introduzione In queste prime lezioni abbiamo affrontato linformatica procedendo a soluzioni di problemi,
Problema Ci sono 5 signore nel parco. Ognuna di loro ha 1 figlio. Ogni bambino ha 10 figurine di calciatori, per un totale quindi di 50 figurine. Questi.
Le funzioni.
Lezione 2 Programmare in ASP
Algoritmi e Strutture Dati
14 marzo 2002 Avvisi:.
ND-partizione (A) n   A  somma  0 M  1/2 (  a i ) for i  1 to n do S[i]  choice ({true, false}) if S[i] then somma  somma + a i if somma > M then.
Complessità di un algoritmo
Cammini minimi da un sorgente
Sessione live Testing. Esercizio Quesito 1 Soluzione 1.
11/21/2014E. Giovannetti -- OI09.1 Olimpiadi di Informatica 2010 Giornate preparatorie Dipartimento di Informatica Università di Torino marzo –
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 2 La ricorsione Corso di Informatica 2 a.a. 2003/04 Lezione 2.
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 1 Cicli ed asserzioni Corso di Informatica 2 a.a. 2003/04 Lezione 1.
Sistemi e Tecnologie Informatiche Ricorsione Umberto Ferraro Petrillo.
GLI ARRAY MONODIMENSIONALI. Utilizzando le nostre attuali conoscenze, proviamo a risolvere il seguente problema: Calcolare la media dei voti conseguiti.
1/11/2015E. Giovannetti -- OI09.1 Olimpiadi di Informatica 2010 Giornate preparatorie Dipartimento di Informatica Università di Torino marzo –
Il linguaggio Fortran 90: 3. Procedure e Funzioni
3/31/2015E. Giovannetti -- OI09.1 Olimpiadi di Informatica 2010 Giornate preparatorie Dipartimento di Informatica Università di Torino marzo – Algoritmi.
1 Un esempio con iteratore: le liste ordinate di interi.
4/4/2015E. Giovannetti -- OI09.1 Olimpiadi di Informatica 2010 Giornate preparatorie Dipartimento di Informatica Università di Torino marzo – Un.
ALGORITMI DI RICERCA Nella programmazione s’incontra spesso la necessità di ricercare un elemento (chiave) in un elenco, oppure di ordinare gli elementi.
Introduzione a Javascript
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
Capitolo 6 Iterazione Lucidi relativi al volume: Java – Guida alla programmazione James Cohoon, Jack Davidson Copyright © The McGraw-Hill Companies.
4/19/2015E. Giovannetti -- OI09.1 Olimpiadi di Informatica 2010 Giornate preparatorie Dipartimento di Informatica Università di Torino marzo –
PROVA INTERCORSO MOD.B a.a RICORSIONE ESERCIZI A1.1-A1.6.
Lez 4 (13/14)Elementi di Programmazione1 Strutture di controllo 2.
03/19/09E. Giovannetti -- OI09.1 Olimpiadi di Informatica 2009 Giornate preparatorie Dipartimento di Informatica Università di Torino marzo 2009 Codici.
4/25/2015E. Giovannetti -- OI09.1 Olimpiadi di Informatica 2010 Giornate preparatorie Dipartimento di Informatica Università di Torino marzo –
Ripasso su Java. Introduzione Per risolvere problemi complessi, i linguaggi di programmazione forniscono costrutti per realizzare nuove funzioni che trasformino.
Operatori di incremento e decremento
1 Capitolo 3: Vincoli a dominio finito. 2 Vincoli a dominio finito u Problemi di soddisfazione di vincoli u Un risolutore con backtracking u Consistenza.
Linguaggio C: Le basi Stefano Cagnoni e Monica Mordonini
1 Informatica Generale Marzia Buscemi Ricevimento: Giovedì ore , Dipartimento di Informatica, stanza 306-PS o per posta.
Algoritmi e Programmazione (in C) Stefano Cagnoni e Monica Mordonini
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
Luca Chichisola1 Dal problema al programma LUCA CHICHISOLA.
Transcript della presentazione:

4/5/2015E. Giovannetti -- OI09.1 Olimpiadi di Informatica 2010 Giornate preparatorie Dipartimento di Informatica Università di Torino marzo – Algoritmi di backtracking: il problema delle regine. (versione 05/04/2015)

Il problema delle otto (o n) regine. Disporre 8 regine sulla scacchiera 8  8 in modo che nessuna regina ne attacchi un’altra secondo le regole del gioco degli scacchi; cioè in modo che nessuna si trovi nella stessa riga, o nella stessa colonna, o nelle stesse “diagonali” di un’altra. Il problema è generalizzabile in modo banale a n regine su una scacchiera n  n : per n  4 il problema non è risolubile, come si vede con ispezione diretta; per ciascun n  4 il problema ammette più soluzioni. 05/04/ E. Giovannetti - AlgELab Lez.462

Come rappresentare le soluzioni. Poiché non possono esserci due regine nella stessa riga, qualunque disposizione che risolva il problema deve avere una e una sola regina per riga. Allora possiamo disporre la prima regina nella prima riga, la seconda regina nella seconda riga, … la i-esima regina nella i-esima riga, ecc. Una soluzione è quindi semplicemente una permutazione di degli n numeri naturali da 1 a n o da 0 a n-1, rappresentabile per mezzo di un array. Esempio: per la scacchiera 5  5 l’array {0, 2, 4, 1, 3} è la disposizione delle regine nelle caselle: (0,0); (1,2); (2,4); (3,1); (4,3). Naturamente i ruoli delle righe e delle colonne sono perfettamente intercambiabili. 05/04/ E. Giovannetti - AlgELab Lez.463

L’algoritmo ricorsivo: descrizione molto informale. Per posizionare le regine dall’i-esima riga in avanti: se i è la riga successiva all’ultima, termina con successo; altrimenti cerca una colonna j tale che siano prive di regine la colonna j stessa, la diagonale ascendente passante per la casella (i,j), la diagonale discendente passante per la casella (i,j); posiziona la i-esima regina nella casella (i,j); posiziona le regine dall’ i+1-esima riga in avanti; se tale posizionamento ha successo, termina con successo; altrimenti backtrack: rimuovi la i-esima regina e poi cerca un’altra colonna j che soddisfi alle condizioni di cui sopra, e così via finché non ci sono più colonne da esaminare: in tal caso termina con fallimento. 05/04/ E. Giovannetti - AlgELab Lez.464

L’algoritmo ricorsivo: descrizione più precisa n = dimensione della tastiera; array indiciati da 0 a n-1 boolean posizionaDallaRiga(int i) { if(i == n) return true; else { for(int j = 0; j < n; j++) { if(colonna j è libera da regine && diagonale ascendente per (i,j) è libera da regine && diagonale discendente per (i,j) è libera da regine) { posiziona l’i-esima regina nella colonna j; if(posizionaDallaRiga(i+1)) return true; else rimuovi l’i-esima regina; continua il ciclo } } fine ciclo for return false; se si sono provate senza successo tutte } le colonne j, si fallisce } 05/04/ E. Giovannetti - AlgELab Lez.465

La chiamata iniziale Naturalmente la funzione ricorsiva deve essere inizialmente invocata con il valore del primo indice (1 in Pascal, 0 in C): boolean problemaRegine() { return posizionaDallaRiga(0); } La soluzione è rappresentata da una struttura-dati globale; se si definisce una procedura che visualizza la soluzione, il main avrà la forma … problemaRegine(); visualizzaSoluzione(); … 05/04/ E. Giovannetti - AlgELab Lez.466

Strutture dati convenienti. Per poter effettuare in tempo costante i test sulla presenza di regine nella colonna e nelle due diagonali, conviene tenere tre array di booleani, indiciati rispettivamente dal numero di colonna e dal “numero di diagonale”, dove il k-esimo elemento di ognuno degli array ha il significato: la k-esima colonna, o diagonale in su, o in giù, è senza regine. In una scacchiera n  n vi sono: n colonne; 2n diagonali ascendenti; 2n diagonali discendenti. Osserva: le caselle (i, j) di una data diagonale ascendente sono quelle per cui i+j = costante dipendente dalla diagonale; le caselle di una data diagonale discendente sono quelle per cui i-j = costante dipendente dalla diagonale; 05/04/ E. Giovannetti - AlgELab Lez.467

Strutture dati convenienti: Pascal. Indiciamo, come naturale, righe e colonne da 1 a 8: const n = …; var q: array[1..n] of integer; // posizioni delle regine freeCol: array[1..n] of boolean; Allora: la somma i+j varia da 1+1 a n+n, cioè da 2 a 2n; la differenza i-j varia da 1-n a n-1 (ad es., per n = 8, varia da -7 a +7). Quindi, poiché in Pascal gli array si possono indiciare con un range qualunque: freeDiagRise: array[2..2*n] of boolean; freeDiagFall: array[-n+1..n-1] of boolean; 05/04/ E. Giovannetti - AlgELab Lez.468

Strutture-dati convenienti: C++ Gli array sono indiciabili solo a partire da 0, quindi: int q[n]; bool freeCol[n]; Poiché gl’indici di riga e di colonna vanno da 0 a n-1: la somma i+j varia da 0 a 2n-2, cioè ha 2n-1 possibili valori, la somma i-j varia da –n+1 a n-1, cioè ha 2n-1 possibili valori. Quindi: bool freeDiagRise[2*n - 1]; bool freeDiagFall[2*n - 1]; Nel codice, per l’accesso all’array delle diagonali discendenti occorrerà “traslare” il range –n+1..n-1 nel range 0..2n-1, sommando n-1 al valore di i-j. 05/04/ E. Giovannetti - AlgELab Lez.469

Strutture-dati convenienti: nomi corti. Per ragioni di spazio nelle slides successive (o eventualmente per velocità di codifica) usiamo nomi più corti per gli array. In C++: int q[n]; bool c[n]; // colonne libere bool a[2*n - 1]; // diagonali ascendenti libere bool b[2*n - 1]; // diagonali discendenti libere In Pascal: var q: array[1..n] of integer; c: array[1..n] of boolean; a: array[2..2*n] of boolean; b: array[-n+1..n-1] of boolean; 05/04/ E. Giovannetti - AlgELab Lez.4610

La funzione ricorsiva (C++) bool placeQueens(int i) { if(i == n) return true; for(int j = 0; j < n; j++) { if(c[j] && a[i+j] && b[i-j+n-1]) { q[i] = j; c[j] = a[i+j] = b[i-j+n-1] = false; if(placeQueens(i+1)) return true; else c[j] = a[i+j] = b[i-j+n-1] = true; } return false; } 05/04/ E. Giovannetti - AlgELab Lez.4611

La funzione top-level void queens() { for(int i = 0; i < n; i++) c[i] = true; for(int i = 0; i < 2*n-1; i++) a[i] = true; for(int i = 0; i < 2*n-1; i++) b[i] = true; placeQueens(0); } 05/04/ E. Giovannetti - AlgELab Lez.4612

Il ciclo for in Pascal In Pascal l’indiciamento degli array è più immediato:... for j:= 1 to n do begin if (c[j] and a[i+j] and b[i-j]) then begin q[i]:= j; c[j]:= false; a[i+j]:= false; b[i-j]:=false; if placeQueens(i+1) then begin result:= true; exit end else begin c[j]:= true; a[i+j]:= true; b[i-j]:= true end end;... 05/04/ E. Giovannetti - AlgELab Lez.4613

Il problema delle n regine: tutte le soluzioni. Con una lieve modifica dell’algoritmo si possono generare tutte le soluzioni, cioè tutte le disposizioni di n regine sulla scacchiera n  n che soddisfano alle condizioni del problema. Per ottenere ciò, basta non fermarsi quando si trova una soluzione, bensì continuare il backtracking. Non è quindi più necessario che la procedura restituisca un booleano: ogni volta che si trova una soluzione si può sempli- cemente stamparla, oppure aggiungerla ad una struttura-dati (ad es. una matrice) che rappresenta l’insieme delle soluzioni. Se si è interessati anche o solo al numero delle soluzioni, si può introdurre un contatore che conti il numero di soluzioni, da incrementarsi ogni volta che se trova una. 05/04/ E. Giovannetti - AlgELab Lez.4614

Il problema delle n regine: tutte le soluzioni. void placeQueens(int i) { for(int j = 0; j < n; j++) { if(c[j] && a[i+j] && b[i-j+n-1]) { q[i] = j; c[j] = a[i+j] = b[i-j+n-1] = false; if(i == n-1) { writeSolution(); numSolutions++; } else placeQueens(i+1); c[j] = a[i+j] = b[i-j+n-1] = true; } 05/04/ E. Giovannetti - AlgELab Lez.4615