1.27k likes | 1.47k Views
TEMA 3: Disseny recursiu. Tema 3: Disseny recursiu Introducció a la recursivitat Inducció noetheriana Disseny i verificació de programes recursius Anàlisi per casos i composició Cost i correctesa de programes recursius Tècniques de recursió Algoritmes recursius finals i no finals
E N D
TEMA 3: Disseny recursiu
Tema 3: Disseny recursiu • Introducció a la recursivitat • Inducció noetheriana • Disseny i verificació de programes recursius • Anàlisi per casos i composició • Cost i correctesa de programes recursius • Tècniques de recursió • Algoritmes recursius finals i no finals • Raons d’eficiència • Tècniques de desplegament i plegament • Transformació de recursiu a iteratiu • Problemes per a resoldre
Anàlisi del cost computacional • Introducció a la recursivitat • Recursivitat és quan un procediment o funció fa referència a sí mateix dins de la seva definició • Exemple: una persona que amb un mirall de ma mira la seva imatge a un mirall de peu • És a dir, a la pràctica es quan un procediment o funció produeix crides successives fins arribar a un estat de no generació de més crides successives
Anàlisi del cost computacional • Introducció a la recursivitat • Històricament la programació ha estat més donada a oferir primerament la programació iterativa • Les definicions naturals de fenòmens mitjançant la recursió són tan velles com les iteratives • L’esforç del raonament és menor quan treballem en recursiu que quan ho fem en iteratiu
Anàlisi del cost computacional sobre sobre P D P D sobre sobre (p d) * n P D’ • Introducció a la recursivitat • Un programa recursiu pot convertir-se en iteratiu sense perdre correcció ni eficiència (invariants gratuïts) • Plantejaments iteratiu i recursiu: • Exemple: an
Anàlisi del cost computacional • Introducció a la recursivitat • Un disseny recursiu presenta: • Condicionals que separen el tractament dels casos trivials dels no trivials • El tractament d’un cas trivial te aspecte de procés iteratiu • El d’un cas no trivial està format per: • Una descomposició recursiva de les dades de D. Direm que obtenim un sub-probleme D’ més senzill • Fem una crida recursiva per calcular la solució de D’ • Operem sobre la solució de D’ per obtenir la solució de D
Anàlisi del cost computacional • Introducció a la recursivitat • De vegades hi pot haver vàries crides recursives i la situació es pot complicar (ús de resultats combinats) int potencia(int a, int n) { int res = 0; switch (n): { case 0: res = 1; break; others: res = a * potencia(a, n-1); break; } return (res); }
Anàlisi del cost computacional • Introducció a la recursivitat • Si una funció genera un crida recursiva interna per cada crida externa en direm d’ella que és una funció recursiva lineal • Quan genera dos o més crides internes per una externa en direm d’ella que és una recursiva múltiple (o no lineal) • Aquesta distinció és dinàmica pot o no canviar en el context
Anàlisi del cost computacional • Introducció a la recursivitat • Exemple de recursivitat múltiple: (primera versió) int suma (int a[ ], int i, int j) { if (i > j) return(0); else if (i == j) return(a[i]); else if (i < j) { int m = (i + j) / 2; return( suma(a,i,m) + suma(a,m+1,j)); } }
Anàlisi del cost computacional • Introducció a la recursivitat • Exemple de recursivitat múltiple: int suma (int a[ ], int i, int j) { int res = 0; if (i == j) res = a[i]; else if (i < j) { int m = (i + j) / 2; res = suma(a,i,m) + suma(a,m+1,j); } return(res); }
Anàlisi del cost computacional • Introducció a la recursivitat • Quan a una funció recursiva en el cas no trivial f(x) = f(s(x)) direm que és una funció recursiva final (eficiència) int MCD (int a , int b) { int res = 0; if (a== b) res = a; else if (a > b) res = MCD(a-b,b); else res = MCD(a,b-a); return(res); }
Anàlisi del cost computacional • Inducció Noetheriana • Principi de correcció d’una funció recursiva: Donada la següent especificació formal: Verificar la correcció de f equival a demostrar la validesa del següent predicat
Anàlisi del cost computacional • Inducció Noetheriana • Com el domini serà o infinit o molt gran no podem estudiar tots els casos • Mètode finit de dur a terme la demostració • Com f és recursiva la correcció d’aquesta ha de ser vàlida per altres estats del domini • Per això necessitem una inducció sobre dominis que són pre-ordres ben fundats, per a conjunts de valors de dit domini
Anàlisi del cost computacional • Inducció Noetheriana • Definició: Donat un conjunt D, una relació binària a D, a les hores s’anomena un pre-ordre sobre D, si és reflexiva i transitiva. Es a dir, • Si és un pre-ordre a D, també li direm pre-ordre al parell
Anàlisi del cost computacional • Inducció Noetheriana • Definició: Donat un pre-ordre , definim a partir de una relació , que anomenem pre-ordre estricte • Definició: Donat un pre-ordre , es diu que un element és minimal a D, si no te predecessors estrictes
Anàlisi del cost computacional • Inducció Noetheriana • Definició: Donat un pre-ordre es diu que és tracta d’un pre-ordre ben format (pbf), si no hi ha a D successions finites estrictament decreixents.
Anàlisi del cost computacional • Inducció Noetheriana
Anàlisi del cost computacional • Inducció Noetheriana
Anàlisi del cost computacional • Inducció Noetheriana
Anàlisi del cost computacional • Disseny i verificació de programes recursius • La seqüència a seguir en el desenvolupament d’un problema recursiu serà: • Especificació formal de l’algoritme • Anàlisi per casos • Composició • Verificació formal de la correcció • Estudi de l’eficiència
Anàlisi del cost computacional • Correcció i cost de programes recursius
Anàlisi del cost computacional • Exemple an:
Anàlisi del cost computacional • Exemple an:
Anàlisi del cost computacional • Exemple an:
Anàlisi del cost computacional • Exemples de recursivitat: • Si reconsideram l’algoritme de la potència dins l’anàlisi recursiu podem trobar fàcilment un algoritme de cost O(log n). • La tècnica consisteix en descomposar el problema d’una forma més intel·ligent • En lloc de • Podem fer
Anàlisi del cost computacional • Exemples de recursivitat: • Si reconsideram l’algoritme de la potència dins l’anàlisi recursiu podem trobar fàcilment un algoritme de cost O(log n). public int logn(int a, int n) { int x; if (n == 0) return(1); else { x = logn(a, n/2); if (n%2 == 0) // n parell return(x*x); else return(a*x*x); } }
Anàlisi del cost computacional • Exemples de recursivitat. Cerca dicotòmica: • Es tracta de cercar un element dins un vector ordenat creixentment. Crida inicial: cerca(a, 1, N, valor a cercar) • Si ho troba torna l’índex, si no torna -1 public int cerca(vector a, int n, int m, int v) { int c = (m+n)/2; if (m > n) return(-1); // no hi és else if (v < a[c]) return(cerca(a,n,c-1,v)); else if (v == a[c]) return(c); else if (v > a[c]) return(cerca(a,c+1,m,v)); }
Anàlisi del cost computacional • Recursivitat. Corbes de Hilbert H3 H2 H1 A: D A A B B: C B B A C: B C C D D: A D D C
Anàlisi del cost computacional A: D A A B B: C B B A C: B C C D D: A D D C • Recursivitat. Corbes de Hilbert public void A(int i) { if (i>0) { D(i-1); x:=x-h; plot; A(i-1); y:=y-h; plot; A(i-1); x:=x+h; plot; B(i-1); } }
Anàlisi del cost computacional • Recursivitat. Corbes de Hilbert. Resultat fins a profunditat 5
Anàlisi del cost computacional • Recursivitat. Backtracking. Mètode general • Tècnica de propòsit general (desfer el camí) • Realitza una cerca sistemàtica dins l’espai de solucions (sovint no eficient) • Es proven casos fins que se troba la solució final i si en el camí arribem a un estat sense sortida tornem a l’estat anterior
Anàlisi del cost computacional • Recursivitat. Backtracking. Mètode general • Considerem solució a la tupla (x1, x2,..., xn ) • A cada instant l’algoritme es troba en un estat k amb una solució parcial (x1, x2,..., xk ) • Si es pot afegir un nou element a la solució i avançar a l’estat k+1, es fa • Si no se proven altres elements per xk • Si no queden elements per provar tornem a l’estat k-1 • Això es fa fins que la solució parcial és la del problema cercat o fins que no queden solucions parcials per provar
Anàlisi del cost computacional buit Nivell k X1 = 0 X1 = 1 X1 = 0 X1 = 0 X1 = 1 X1 = 1 X2 = 0 X2 = 1 X2 = 0 X2 = 1 • Recursivitat. Backtracking. Mètode general • En definitiva es fa un recorregut en profunditat de l’arbre de solucions
Anàlisi del cost computacional • Recursivitat. Backtracking. Anàlisi de temps d’execució • Sovint la complexitat de l’algoritme ve donat pel producte del nombre d’elements de l’arbre i del temps de solució de cada element • Existeix una tècnica de poda però queda fora de l’àmbit d’aquest curs (branch and bound) • En general aquests algoritmes donen temps d’execució factorial o exponencial
Anàlisi del cost computacional • Recursivitat. Backtracking. Exemple de la motxilla • Hem d’omplir una motxilla d’una col·lecció d’elements disponibles. Posar-hi el màxim nombre d’elements obtenint el màxim benefici • Dades del problema: • n: quantitat d’objectes disponibles • M: capacitat de la motxilla • p = (p1 , p2 , ... , pn) ; pesos dels objectes • c = (c1 , c2 , ... , cn) ; preu (cost) dels objectes
Anàlisi del cost computacional • Recursivitat. Backtracking. Exemple de la motxilla • Formulació:
Anàlisi del cost computacional • Recursivitat. Backtracking. Exemple de la motxilla • Complexitat de l’algorisme:
Anàlisi del cost computacional • Recursivitat. Backtracking. Assignació de tasques • Hem d’assignar una sèrie de tasques a una plantilla de treballadors de forma que el rendiment sigui el millor possible • Dades del problema: • Tenim n persones i n tasques • Cada persona i pot realitzar una tasca j amb més o menys rendiment B[i,j]
Anàlisi del cost computacional • Recursivitat. Backtracking. Assignació de tasques • Dades: • Exemple 1: (p1, t1), (p2, t3), (p3, t2) 4+3+3=10 • Exemple 2: (p1, t2), (p2, t1), (p3, t3) 9+7+5=21
Anàlisi del cost computacional • Recursivitat. Backtracking. Assignació de tasques • Formulació:
Anàlisi del cost computacional • Recursivitat. Backtracking. Assignació de tasques • Complexitat de l’algoritme:
Anàlisi del cost computacional • Recursivitat. Backtracking. Emplenat de polígons • Hem d’emplenar un polígon amb un color determinat • Dades del problema: • Un polígon de n pixels • Posició x,y inicial per a on començar a emplenar
Anàlisi del cost computacional • Recursivitat. Backtracking. Emplenat de polígons • Plantejarem el problema en 4 connectivitat. És a dir un pixel és veïnat d’un altre si el toca en 4 connectivitat 4 connexió 8 connexió
Anàlisi del cost computacional • Recursivitat. Backtracking. Emplenat de polígons • Partirem d’un punt x,y (pixel) intern del polígon • Per a cada pixel: • Marcar-lo (pintar-lo del color) • Si podem seguir el nord seguir-lo recursivament • Si podem seguir l’est seguir-lo recursivament • Si podem seguir el sud seguir-lo recursivament • Si podem seguir el oest seguir-lo recursivament • Acabat això tenim el polígon emplenat
Anàlisi del cost computacional • Recursivitat. Backtracking. Emplenat de polígons • Complexitat de l’algoritme:
Anàlisi del cost computacional • Recursivitat. Backtracking. Recorregut del tauler • Pràctica:
Anàlisi del cost computacional • Recursivitat. Backtracking. Recorregut del tauler • Pràctica: Es tracta de realitzar un programa que tenint pre-definides 8 peces (cavall, torre, òrfil, rei i quatre peces inventades per l’usuari), sigui capaç donada una casella d’inici de realitzar un recorregut exhaustiu per un tauler d’escacs de nxn caselles si existeix i si no és així informar de la situació. • Recorregut exhaustiu: Passem per totes les caselles del tauler visitant cada una d’elles sols una vegada.
Anàlisi del cost computacional • Recursivitat. Backtracking. Recorregut del tauler • Pràctica: La solució ha de desenvolupar-se en backtracking i si troba més d’un recorregut favorable, basta que informi d’un dels existents. • Com a paràmetres d’entrada el programa ha de poder acceptar la dimensió del tauler, la casella d’inici i la peça a utilitzar. • Es proporciona una llibreria gràfica simple que es pot substituir o millorar per part de l’alumne.
Anàlisi del cost computacional • Recursivitat. Backtracking. Recorregut del tauler • Pràctica: Per emprar la llibreria es proporciona un exemple de projecte “Cavall”. Basta tenir accés al paquet “scacswinlib.jar”. • Al final la pràctica ha de presentar un bon disseny objecte. • La data límit serà el dia 27/01/2005.
Anàlisi del cost computacional Sub-sol. 1 Sub-prob. 1 PROBLEMA SOLUCIÓ Sub-prob. 2 Sub-sol. 1 • Recursivitat. Dividir i vèncer. Mètode general • Descompondre un problema en sub-problemes més petits • Resoldre els sub-problemes • Combinar les sub-solucions per obtenir la solució general