Descarga la aplicación para disfrutar aún más
Esta es una vista previa del archivo. Inicie sesión para ver el archivo original
2011_Tema_3_Algoritmos_de_Busqueda.pdf Tema 3: Algoritmos de Búsqueda 3.1 Algoritmos básicos de búsqueda Resultados conocidos Búsqueda lineal Búsqueda binaria Tenemos que calcular N N N i BLin e C S iTkpiTknNA BLin 1 ])[(])[()( cdc OBcon )( NNW BLin )()1()lg()lg()( NAONNNW fBBinBBin )(NAeBBin 3 Coste medio de BBin con éxito. Veamos un ejemplo: T=[1 2 3 4 5 6 7] N=7=23-1 Para N=2k-1 se tiene )3333221( 7 1 ])[( 7 1 )( 7 1 i BBin e iTknNA BBin 4 2 6 1 3 5 7 )2·32·22·1( 7 1 )4·32·21( 7 1 )( 210 NAe BBin ]1)lg([ 1 )(]122[ 1 2 1 )( 1 NNN N NAk N i N NA ekk k i ie BBinBBin Obs: N=2k-1klog(N) )()lg()( 1 1)lg()( NONNA N NNA ee BBinBBin 4 Árbol de decisión para algoritmos de búsqueda por CDC: Definición Si A es un algoritmo de búsqueda por comparación de clave y N es un tamaño de tabla, se puede construir su árbol de decisión TA N para N tal que cumple las siguientes 5 condiciones: 1. Contiene nodos de la forma i que indica la cdc entre el elemento i-ésimo de la tabla y la clave k. 2. Si k coincide con el elemento i-ésimo (T[i]==k) entonces la búsqueda de la clave k termina en el modo i 3. El subárbol izquierdo del nodo i en TA N contiene el trabajo (cdcs) que realiza el algoritmo A si k < i. 4. El subárbol derecho del nodo i en TA N contiene el trabajo (cdcs) que realiza el algoritmo A si k > i. 5. Las hojas H en TA N recogen la evolución de las búsquedas fallidas. 5 Árbol de decisión: Ejemplos 5 BBinT 3 41 2 5F F F F F F < < < < < > > >> > = = == = 3 BLordT 1 2 3F F F F < < < > > > = = = Tabla ordenada 3 BLT 3 4 5 F F < < < > > > = = = 5 F F < >= 4 5 F F < < > > = = 5 F F < >= Tabla no ordenada Obs: TA N es un árbol binario con al menos N nodos internos. Esto da la cota inferior: WA(N)≥profmin(N) Profundidad mínima de un árbol con al menos N nodos internos 6 Árbol de decisión: Cotas inf. Caso Peor Estimamos profmin(N) N T Profmin(N) 1 1 2 2 3 2 4 3 7 3 7 Cotas inferiores en búsqueda por cdcs Tenemos que WA(N)≥profmin(N) =lg(N)+1 WA(N)=(lg(N)) AB con B={A: algoritmo de búsqueda por cdc} BBin es óptimo para el caso peor. Se puede demostrar también AA(N)=(lg(N)) AB BBin es óptimo para el caso medio. 8 ¿Ya hemos acabado? Observación: la búsqueda no es una operación aislada Los elementos no sólo se buscan sino que también se insertan o se borran No sólo importa cómo se busca sino también dónde se busca Contexto: TAD Diccionario 9 En esta sección hemos … Recordado los costes peor y medio de búsqueda lineal y binaria Aprendido el concepto de árbol de decisión en búsqueda por cdcs Aprendido a construir árboles de decisión en búsqueda por cdcs Visto que la búsqueda binaria es óptima en los casos peor y medio dentro de los algoritmos de búsqueda por cdcs 10 3.2 Búsqueda sobre diccionarios TAD Diccionario Diccionario: conjunto ordenado de datos con las primitivas. pos Buscar(clave k, dicc D) Devuelve la posición de la clave k en el diccionario D o un código de error ERR si k no está en D. status Insertar (clave k, dicc D) Inserta la clave k en el diccionario D, devuelve OK o ERR si k no se pudo incorporar a D. void Borrar (clave k, dicc D) Elimina la clave k en el diccionario D 12 EdEs para Diccionarios I ¿Qué EdE es la más adecuada para un diccionario? Opción 1: Tabla ordenada (|D|=N) Buscar: Usamos BBin => nBuscar(k,D)=O(log(N)) => óptimo. Insertar: Hay que mantener la tabla ordenada => la inserción es costosa Ejemplo: Si se inserta en la posición 1, hay que desplazar N elementos En el caso medio se desplazan N/2 elementos Por tanto nInsertar(k,D)=(N): malo!! 24 25 27 29 Insertar 26 Hay que desplazar a la derecha estos elementos 13 EdEs para Diccionarios II Opción 2: Árbol binario de búsqueda (ABdB) Definición: Un ABdB es un árbol binario T que para todo nodo T’T se cumple: Info(T’’)<Info(T’)<Info(T’’’) para cualquier nodo T’’ a la izq de T’ y T’’’ a la derecha de T’ Es decir, todos los nodos a la izquierda de T’ tienen un valor menor que info(T’) y todos los nodos a la derecha de T’ tienen un valor mayor que info(T’) Ejemplo: 5 2 7 1 4 6 9 8 11 14 Buscar sobre ABdBs I Ejemplo 5 2 7 1 4 6 9 8 11 B(k=8) 8>5 8>7 8<9 k==8 15 Buscar sobre ABdBs II Pseudocódigo: Observación: AB Buscar (clave k, AB T) si T==NULL : return NULL; si info(T)==k : return T; si k<info(T) : return Buscar(k,izq(T)); si k>info(T) : return Buscar(k,der(T)); nBuscar(k,T)=prof(T) 16 Insertar en ABDBs I Ejemplo 5 2 7 1 4 6 9 8 11 I(k=3) 3<5 3>2 NULL 3<4 BuscarUltimo 5 2 7 1 4 6 9 8 11 3 Último, 3<4 y izq(4)==NULL izq(4)==3 17 Insertar en ABDBs II Pseudocódigo Observación status Insertar (clave k, AB T) T’=BuscarUltimo(k,T); T’’=GetNodo(); si T’’==NULL : return ERR; info(T’’)=k; si k<info(T’) : izq(T’)=T’’ else : der(T’)=T’’; return OK; AB BuscarUltimo(clave k, AB T) si k == info(T): return NULL; si (k<info(T) y izq(T) ==NULL) o (k>info(T) y der(T) ==NULL): return T; si k<info(T) y izq(T) !=NULL : return BuscarUltimo(k,izq(T)); si k>info(T) y der(T) !=NULL : return BuscarUltimo(k,der(T)); return T ; nInsertar(k,T)=nBuscarUltimo(k,T)+1 nInsertar(k,T)=O(prof(T)) 18 Borrar en ABdBs Pseudocódigo: void Borrar (clave k, AB T) T’=Buscar(k,T); si T’!=NULL : EliminaryReajustar(T’,T); En EliminaryReajustar hay tres posibles casos, dependiendo del número de hijos que tenga el nodo T’ a eliminar 19 Eliminar y Reajustar I Caso 1: El nodo a eliminar no tiene hijos se libera el nodo T’ (free(T’)), y el puntero del padre de T’ que apuntaba a T’ se reasigna a NULL. Coste EliminaryReajustar = O(1) T T’ NULL NULL T NULL EliminaryReajustar(T’) 20 Eliminar y Reajustar II Caso 2: El nodo a eliminar tiene sólo un hijo el puntero del padre de T’ que apuntaba a T’ se hace apuntar al único hijo de T’ y se libera T’ Coste EliminaryReajustar = O(1) T T’ NULL T EliminaryReajustar(T’) T’’ T’’ 21 Eliminar y Reajustar III Caso 3: El nodo a eliminar tiene dos hijos T’ se sustituye por el nodo que contiene al sucesor (el elemento siguiente en la tabla ordenada), y se elimina el nodo T’ según el caso 1 o 2. Coste EliminaryReajustar ≤ prof(T) T T’ T’’’ T’’ T’Sucesor’ T’’’’ T T’ T’’’ T’’ T’Sucesor’ T’’’’ T T’’’’ T’’’ T’’ T’Sucesor’ 22 Eliminar y Reajustar III Ejemplo 17 5 3 1 4 14 11 15 6 12 7 Sucesor B(5) 17 6 3 1 4 14 11 15 5 12 7 17 6 3 1 4 14 11 15 12 7 Caso 1 23 Búsqueda del Sucesor Pseudocódigo AB BuscarSucesor(AB T’) T’’=der(T’); mientras izq(T’’)!=NULL : T’’=izq(T’’); return T’’ ; Obs: Si k’ es el sucesor en un ABdB de k, entonces izq(k’)==NULL: Si izq(k’)==k’’ se tendria que k’’<k’ Pero k’’>k, pues k’’ está a la derecha de k Luego se tiene que k<k’’<k’ y Por tanto, k’ no puede ser el sucesor de k. 24 Primitivas de diccionarios con TAD ABdB nEyR(T’,T)=nBuscarSucesor+nReajustarPunteros= O(prof(T))+O(1) Por tanto nBorrar(k,T)=O(prof(T))+ O(prof(T))= O(prof(T)) ABdB es eficaz siempre que prof(T)= (lg(N)) Pero WBuscar(N)=N: ¡¡malo!! Buscar EyR 1 2 3 N 25 Coste medio de búsqueda en ABdBs I AeBuscar(N)= coste medio de (1) la búsqueda de todos los elementos (2) para todos los T )),(( 1 ! 1 )( ! 1 )( 1 Tin NN TA N NA NN N i Buscar e Buscar e Buscar ]))(( 1 1[ ! 1 ]1))(([ 1 ! 1 11 NN N i N i iprof NN iprof NN N Tn NN Crear )( ! 11 1 )( 1 1)( NA N NA eCrear e Buscar Por tanto 26 Coste medio de búsqueda en ABdBs II Vemos a un pseudocódigo alternativo para Crear AB Crear (tabla ) T=IniAB(); InsAB((1),T); Repartir(, i, d); Ti=Crear(i); Td=Crear(d); izq(T)=Ti; der(T)=Td; return T; =[3 5 2 6 4 1] Crear 3 [2 1] [5 6 4] Caso similar a QS: nC ()=N-1+ nC(i)+ nC(d) ))(log()()log(2 1 1)( 1 1)( NNONN N NA N NA eCrear e Buscar Por tanto: )()log(2)( NONNNACrear 27 Resumen de primitivas sobre ABdBs Si B es algoritmo de Búsqueda por cdc WB(N)=(N) Si la EdD es un ABdB las primitivas son eficaces en promedio Si aseguramos que para todo N se tiene un ABdB tal que prof(T)=(lg(N)), tendriamos que WBuscar(N)= (lg(N)) 28 En esta sección hemos … Introducido el concepto de diccionario y sus primitivas Estudiado su implementación sobre ABdBs Comprobado que su coste viene determinado por la profundidad del ABdB Comprobado que dicha implementación es óptima en el caso medio Comprobado que en el caso peor dicha implementación tiene un coste (lg(N)) 29 La construcción y uso de Árboles Binarios de Búsqueda Eliminación de nodos en ABdBs Problemas a resolver (al menos) 110, 112, 114, 115 Herramientas y técnicas a trabajar 3.3 Árboles AVL Árboles AVL (Adelson-Velskii-Landis) Definición: El factor de equilibrio de un nodo T en un ABdB se define FE(T)=prof(Ti)-prof(Td) Ejemplo: 0 0 0 0 0 0 0-2=-2 4-3=1 3-1=2 0 2-0=2 Definición: Un AVL T es un ABdB tal que subárbol T’de T se verifica FE(T’)={-1,0,1} 32 Construcción de AVLs Para construir un AVL se procede en 2 pasos. Paso 1: Se realiza la inserción normal de un nodo en un ABdB Paso 2: Si es necesario se corrigen desequilibrios y una vez corregidos, se vuelve al paso 1 Ejemplo: T=[1 2 3 4 5 6 7 15 14 13 12 11 10 9 8] I(1)+I(2) 1 -1 2 0 I(3) 1 -2 2 -1 3 0 RI(2) 1 0 2 0 3 0 33 Construcción de AVLs La operación que acabamos de hacer se denomina Rotación a la Izquierda en el -1, en este caso en el elemento 2. En realidad la rotación a la izquierda en el -1 corresponde a la siguiente reasignación de punteros x1 x2 x3 T1 T2 T4T3 RI(x2) x1 x2 x3 T1 T2 T4T3 y y tmp=izq(x2), izq(x2)=x1, der(x1)=tmp, izq(y)= x2 o bien der(y)= x2 34 Construcción de AVLs Seguimos el proceso 1 0 2 0 3 0 I(4) 1 0 2 -1 3 -1 4 0 I(5) 1 0 2 -2 3 -2 4 -1 5 0 RI(4) 1 0 2 -1 3 0 4 0 5 0 1 0 2 -2 3 0 4 -1 5 -1 6 0 I(5) RI(4) 1 0 2 0 3 0 4 0 5 -1 6 0 35 1 0 2 0 3 0 4 0 5 -1 6 0 I(7) 1 0 2 0 3 0 4 -1 5 -2 6 -1 7 0 RI(6) 1 0 2 0 3 0 4 0 6 0 7 0 5 0 I(15)+I(14) 1 0 2 0 3 0 4 -2 6 -2 7 -2 5 0 15 1 14 0 RD(14) 1 0 2 0 3 0 6 -2 7 -2 5 0 15 0 14 -1 RI(14) 1 0 2 0 3 0 6 -1 7 0 5 0 15 0 14 0 4 -2 4 -1 RDI(izq(1))=RDI(14) I(13) 36 1 0 2 0 3 0 6 -2 7 -1 5 0 15 0 14 1 4 -2 RD(7) 13 0 1 0 2 0 3 0 6 -2 7 -2 5 0 15 0 14 0 4 -2 RI(7) 13 0 1 0 2 0 3 0 7 5 0 1 15 0 14 0 4 -1 I(12) 13 0 6 0 RDI(7) 1 0 2 0 3 0 7 5 0 1 15 0 14 1 4 -2 RI(7) 13 1 6 -1 12 0 1 0 2 0 3 0 7 5 0 1 15 0 14 1 4 0 13 16 0 12 0 I(11) 37 1 0 2 0 3 0 7 5 0 1 15 0 14 1 4 0 13 16 0 12 0 RD(12) 1 0 2 0 3 0 7 5 0 1 15 0 14 2 4 0 13 26 -1 12 1 11 0 I(11) 1 0 2 0 3 0 7 5 0 1 15 0 14 1 4 0 12 06 0 11 0 13 0 I(10) 1 0 2 0 3 0 7 5 0 1 15 0 14 2 4 0 12 16 -1 11 1 13 0 10 0 RD(12) 38 1 0 2 0 3 0 7 5 0 1 15 0 14 0 4 0 12 0 6 0 11 1 13 0 10 0 I(9) 1 0 2 0 3 0 7 5 0 1 15 0 14 0 4 0 12 1 6 -1 11 2 13 0 10 1 9 0 RD(10) 1 0 2 0 3 0 7 5 0 1 15 0 14 0 4 0 12 0 6 0 10 0 13 0 9 0 11 0 1 0 2 0 3 0 7 5 0 1 15 0 14 0 4 0 12 1 6 -1 10 1 13 0 9 1 11 0 I(8) 8 0 Hemos construido el AVL 39 Resumen de rotaciones Tipo de desequilibrio Rotación (-2,-1) Rot Izquierda en -1 (hijo izq de -1 pasa a hijo der de -2) (2,1) Rot Derecha en 1 (hijo der de 1 pasa a hijo izq de 2) (-2,1) Rot Derecha Izquierda en izquierda de 1 RotIzq(izq(1))+ RotDer(izq(1)) (2,-1) Rot Izquierda Derecha en derecha en -1 RotDer(der(-1))+ RotIzq(der(-1)) 40 Funcionamiento de las rotaciones Para ver que efectivamente las rotaciones solucionan los desequilibrios es necesario ver cada uno de los casos. x y 1 2 T1 T2 T3 p p-1 p-1 prof =p+1 RD(y) x y 0 0 T1 T2 T3 p p-1 p-1 prof =p (2,1)→RD(1) x y -1 2 T1 T3 T4 p p RID(z) (2,-1)→RID(der(-1)) z T2 p p p p-1 p-1 p3 posibles casos z y T1 T4T2 p x T3 p p p p p-1 p-1 p 0 -1 0 0 0 1 0 -1 1 0 1 -1 41 Funcionamiento de las rotaciones Observación: Las rotaciones resuelven desequilibrios de tipo 2, situados mas arriba del desequilibrio (2, 1) x y-1 2 T1 T3 T4 p p RID(z) z T2 p p p p-1 p-1 p z y T1 T4T2 p x T3 p p p p p-1 p-1 p 0 -1 0 0 0 1 0 -1 1 0 1 -1 w 2 T5 p+1 prof p+2 prof p+3 w 1 T5 p+1 prof p+2 42 Funcionamiento de las rotaciones Observación: Si se tiene un AVL, tras la inserción de un elemento no pueden darse desequilibrios de la forma (2, 0). x y0 2 T1 T3 p p-1 Con lo cual la situación Antes de insertar el nodo era T2 Supongamos que tras una inserción tenemos p El nodo debió insertarse en uno de estos dos subárboles x y 2 T1 T3 p-1 T2 p p-1 p p-1 p p 1 -1 0prof p+1 prof p+1 ¡ No era AVL ! 43 Profundidad de Árboles AVL Proposición: Si T es un AVL con N nodos entonces prof(T)=O(log(N)) Dado que para cualquier árbol binario con n nodos se tiene que prof(T)=(log(N)), tenemos que si T es AVL entonces prof(T)=(log(N)) Para ver lo anterior vamos a estimar el número mínimo de nodos np de un AVL Tp de profundidad p. 44 AVLs mínimos p AVL np np+1 Fp+2 0 1 2 F2 1 2 3 F3 2 4 5 F4 3 7 8 F5 4 12 13 F6 … …. …. 45 AVL de Fibonacci I Fp es el p-ésimo número de Fibonacci. Los números de Fibonacci verifican: Fn=Fn-1+Fn-2 , con F0=F1=1 Los AVL Tp se construyen np =1+ np-1+ np-2, por tanto se tiene 1+np =1+ np-1+1+ np-2 Por tanto np+1= Hp= Fp+2 Tp Tp-1 Tp-2 Tp Tp-2 Tp-1 o bien Hp Hp-1 Hp-2 Obs: H0=1+n0=2=F2, H1=1+n0=3=F3 46 AVL de Fibonacci II Se puede demostrar que en N-simo número de Fibonacci es 2 51 y 2 51 donde 5 1 11 NNNF N→ N→ 0 ya que >1 y ||<1 Con lo cual se tiene FN(1/5) N y como np= Fp+2- 1 obtenemos donde p es la profundidad y C una constante , 5 3 pp p Cn 47 Profundidad de un AVL II Entonces si T es un AVL con N nodos y profundidad p, se sigue que Nnp C p Esto es, se tiene que lg(N) p·lg()+lg(C), es decir log(N)=(prof(T)), y por lo tanto prof(T)=O(lg(N)) Es decir, el coste de Buscar sobre un AVL es O(lg(N)) en el caso peor 48 Conclusión Si usamos un AVL como EdD para un diccionario, tanto Buscar como Insertar tienen un coste O(log(N)) en el caso peor. ¿Qué ocurre con Borrar? No es fácil reajustar los nodos de un AVL después de haber eliminado un nodo. La solución habitual es realizar un Borrado Perezoso: en lugar de eliminar el nodo, se marca como libre, además si el elemento se reinserta, la inserción es muy fácil y rápida. Ejemplo: El inconveniente de este método es que se pierden posiciones de almacenamiento 1 2 3 4 5 Eliminar (2) 1 3 4 5 49 En esta sección hemos aprendido… El concepto de árbol AVL. A construir un árbol AVL insertando como en ABdBs y corrigiendo desequilibrios mediante rotaciones A estimar el número mínimo de nodos de un AVL de profundidad P La relación de lo anterior con los números de Fibonacci y algunas propiedades de estos Que la profundidad de un AVL con N nodos es O(lg(N)) Que el caso peor de búsqueda en un AVL es O(lg(N)) 50 Construcción y propiedades de árboles AVL Construcción y propiedades de árboles de Fibonacci Problemas a resolver (al menos) 119, 120, 125, 126 Herramientas y técnicas a trabajar 3.4 Hashing Ordenación y búsqueda Ordenación Búsqueda Métod. malos O(N2) O(N) Métod. Buenos O(N lg N) O(lgN) Límite O(N) O(1) 53 A grandes rasgos, los costes de búsqueda son 1/N veces los de ordenación Ordenación y búsqueda II ¿Es posible hacer búsquedas en tiempo inferior a O(log(N))? 1. Imposible mediante comparaciones de clave 2. Pero muy fácil cambiando el punto de vista!! Escenario: 1. TAD diccionario con D={datos D}. 2. Cada dato D tiene una clave única k=k(D). 3. Buscamos por claves pero no mediante claves (no cdcs). Idea 1 1. Calculamos k*=max{k(D): DD} 2. Guardamos cada D en una tabla T de tamaño k* (suponiendo que no hay claves repetidas). Pseudocódigo: Consecuencia: nBuscar(k,D)=O(1) !!! Problema: si k* es muy grande (aunque |D| sea pequeño), la cantidad de memoria necesaria para la tabla T es exagerada. ind Buscar(dato D, tabla T) si T[k(D)]==D return k(D); else devolver NULL ) Idea 2 1. Fijamos M > |D| y se define una función inyectiva (si, kk’ k(k) k(k’) ) k : {k(D)/DD}→{1,2,3,….,M}. 2. Situamos el elemento D en la posición k(k(D)) de la tabla T. 3. Pseudocódigo de Buscar : Tiempo de búsqueda constate con un consumo de memoria no exagerado. Problema: muy difícil encontrar una función inyectiva y universal (independiente del conjunto de claves). ind Buscar2(dato D, tabla T) si T[k(k(D))]==D return k(k(D)); else devolver NULL Obs: nBuscar2(k,D)=O(1) Idea 3 1. Buscamos una función k universal (válida para cualquier conjunto de claves). 2. Somos flexibles con la inyectividad de k: Permitimos que k no sea inyectiva, luego dos datos distintos pueden optar a ocupar la misma posición en la tabla T, pero a) Imponemos que el número de colisiones, esto es, pares kk’ pero k(k)=k(k’) sean pocos. b) Implementamos algún mecanismo de resolución de colisiones 1. Cuestiones abiertas: a) Cómo encontrar una tal h b) Cómo resolver colisiones Funciones hash Objetivo: probabilidad pequeña de colisiones Si T tiene M datos, lo óptimo sería que p(colisión)=1/M Idea: h(D) = valor al lanzar un dado de M caras pero Cada vez que aparece D el dado lo puede enviar a posiciones distintas!! Luego queremos que h(k(D)) siempre valga lo mismo para cada k(D) particular. Esto es, queremos que h sea función y aleatoria Como rand() en C Q: ¿cómo construir funciones aleatorias? Hash por división Dado un diccionario D fijamos un número m>|D|, que sea primo. Definimos h(k)=k%m Con alguna condición adicional sobre m, se puede conseguir que para valores kj aleatorios, los valores h(kj) también lo parezcan Esto es, superan diversos tests de aleatoriedad Hash por multiplicación Fijamos un número m>|D|, no necesariamente primo (por ejemplo 2k o 10k) y un número irracional (p. ej. (1+5)/2 ó (5-1)/2) Definimos h(k)=m·(k·) , con (x) la parte fraccionaria de x: (x)=x- x De nuevo se puede conseguir que para valores kj aleatorios, los valores h(kj) también lo parezcan Cuestión pendiente: cómo resolver colisiones. Función hash uniforme Definición: Decimos que una función hash h es uniforme si Las funciones hash uniforme son “ideales”. 1. No se pueden conseguir por medios algorítmicos. 2. Pero el rendimiento para ellas es óptimo. Las usaremos en nuestros análisis teóricos Dados k,k’; kk’ entonces p(h(k)=k(k’))=1/m Resolución por Encadenamiento En el hash por encadenamiento, usamos como tabla hash una tabla de punteros a listas enlazadas D D Dx Dy 0 k h(k) h Si estamos seguros de que D no Está en T, introducimos el dato D al principio de la lista enlazada. Si primero comprobamos que no Está, lo insertamos al final Buscar en Encadenamiento Pseudocódigo: Blin en lista enlazada. Coste ya no O(1), pues en BLin hay un bucle Además WBLin (N)=N si para todo k, h(k) = h0 ind Buscar(dato D, tabla T) return BLin(D,T[h(k(D))]); ···· 0 N D D D D Obs: Esta situación puede pasar, pero debería ser muy poco probable si la función hash está bien construida. Encadenamiento con hash uniforme I Proposición: Sea h función hash uniforme en tabla hash con encadenamiento y dimensión m y sean N los datos a introducir; entonces: se denomina el factor de carga: cuanto mayor es, tanto más costosa es la búsqueda m N mNAi fBHE ),( )( )1( 2 1),( )( OmNAii eBHE Factor de carga Coste medio en búsqueda sin éxito Demostración (i): Sea D un dato que no esta en la tabla hash y sea h(k(D))=h(D)=i, sea nBHE(D,T)=|T[i]| (número de elementos en la lista enlazada de la posición i de la tabla hash). m N iT m iTiDhpmNA m i m i h f BHE 11 uniforme |][| 1 |][|))((),( ···· 0 |T[i]| i D Coste medio en búsqueda con éxito Demostración (ii): Vamos a reducir la búsqueda con éxito a una búsqueda sin éxito en una tabla más pequeña. Para ello numeramos los datos de la tabla T, según el orden en el que los introducimos en la tabla T, {D1,D2,….,Dj,….,DN} Además denotamos por Ti al estado de la tabla T antes de introducir el elemento Di (la tabla Ti tiene los elementos D1,D2,….,Dj-1), Por tanto Di no está en Ti, con lo cual se tiene: éxitosin búsquedaéxitocon búsqueda ),(1),( mDnmDn i f BHEi e BHE Nota: aquí asumimos que cada elemento Di se inserta al final de la lista enlazada. Búsqueda con éxito= 1+Búsqueda sin éxito Coste medio en búsqueda con éxito II Asumimos la aproximación m i miAmDn fBHEi e BHE 1 1),1(1),( Factor de carga en Ti 1 111 1 1 1 1 1 ),( 1 ),( N i N i N i i e BHE e BHE i Nmm i N mDn N mNA entonces )1( 2 1 2 1 2 1 1 2 )1(1 1 O mm NNN Nm m N mNA fBHE ),( )1( 2 1),( OmNAeBHE Obs: Si la función hash es uniforme se obtienen búsquedas en tiempo constante si =(1), lo cual ocurre si Nm. Por ejemplo si N=200 y m=100 Af200/100=2 Ae 1+2/2=2 Hashing por direccionamiento abierto En el hash por direccionamiento abierto la tabla T contiene los datos ¿Qué hacemos cuando la función hash nos asigna una casilla que está ya ocupada (colisión)? Dx DY D k h(k) h Libre Libre Libre Libre Ocupada Libre Ocupada Dx D DY Libre Libre Libre Libre Ocupada Ocupada Ocupada T T Colisiones en direccionamiento abierto Hay varios métodos para resolución de colisiones en direccionamiento abierto mediante repetición de sondeos Sondeos lineales: Si la posición p=T[h(D)] está ocupada, se intenta colocar D sucesivamente el las posiciones (p+1)%m, (p+2)%m,…., hasta llegar a un i donde la posición (d+i)%m está libre. Dx Dy Dz p=h(k(D)) D Ocupada Ocupada Ocupada Libre Dx Dy Dz D Ocupada Ocupada Ocupada Ocupada (p+2)%m (p+1)%m (p+3)%m Colisiones en direccionamiento abierto Sondeos cuadráticos: Igual que los sondeos lineales pero intentando en las posiciones p=(p+02)%m, (p+12)%m, (p+22)%m,…., hasta que para algún i, (p+i2)%m. Sondeos aleatorios: Intentamos las posiciones, p1, p2, p3,….,pi obtenidas aleatoriamente Este método es inviable en la práctica Es una opción “ideal” en tablas hash Es adecuada para calcular el rendimiento de las búsquedas. Diferencias en los métodos Obs 1: En hash con encadenamiento, la posición de un dato D, siempre será una posición fija de la tabla (h(k(D)), En hash con direccionamiento abierto, la posición de D dependerá h(k(D) y del estado de la tabla en el momento de la Inserción. Obs 2: En hash con encadenamiento (=N/m), puede ser >1. En hash con direccionamiento abierto siempre se tiene Nm, y por tanto 1. En la práctica se usa N< m y <1 (por ejemplo m=2*N y =.0.5). Coste medio con sondeos aleatorios I Proposición: Sea h función hash uniforme en tabla hash con direccionamiento abierto y sondeos aleatorios. Entonces: 1 1 ),( )( mNAi fBHE 1 1 log 1 ),( )( mNAii eBHE Obs 1: ),( entonces 1 Si mNA fBHE Obs 2: ),( entonces 1 Si mNAeBHE Nota: Estos dos resultados se dejan como ejercicio. Coste medio en búsqueda sin éxito Demostración (i): Sea T una tabla hash con DA, de dimensión m y N datos. Como h es uniforme se tiene, dado un dato D p(T[h(D)] ocupada) = N/m = p(T[h(D)] libre) = 1- N datos en una Tabla de tamaño m )1(· sondeos)k (·),( 1 1 1 k k k e BHDA khacerpkmNA nº de sondeos hechos k-1 posiciones ocupadas 1 posición libre Para hacer k sondeos tiene que ocurrir y p(hacer k sondeos) =k-1(1-)1 1 1 )1( 1 )1( 1 1 )1()1( · )1( 2 0 1 1 d d d d k k k k k Coste medio en búsqueda con éxito I Proposición (ii): 1 1 log 1 ),( mNAeBHE Demostración: De nuevo vamos a reducir la búsqueda con éxito a una búsqueda sin éxito en una tabla más pequeña. Al igual que en BHE enumeramos los datos de la tabla T, según el orden en el que los introducimos en la tabla T, {D1,D2,….,Dj,….,DN}, y denotamos por Ti al estado de la tabla T antes de introducir el elemento Di. Obs: Si es el número de sondeos necesarios para encontrar (= al numero necesario para insertar) el elemento Di en la tabla Ti tenemos que )( i e T Dn ),1()()( miADnDn fBHAi f Ti e T i Coste medio en búsqueda con éxito II Por tanto se tiene: 1 011 1 11 1 1 11 )( 1 ),( N j N i N i i e T e BHA m jN m iN Dn N mNA Esta última expresión se puede aproximar mediante una integral, con lo que se tiene: du uu m N dx m xN mNA mNN e BHA 0 / 00 1 11 1 11 1 11 ),( Esta integral es inmediata, con lo que se obtiene: 1 1 log 1 ),( mNAeBHE Cambio de variable. u=x/m dx=m·du Costes medios para otros sondeos I En la demostración anterior vemos que si tenemos la expresión del rendimiento de la búsqueda sin éxito podemos calcular el rendimiento de la búsqueda con éxito calculando Este argumento lo podemos repetir con cualquier tipo de sondeo S con direccionamiento abierto, es decir 1 1 ),()( mNAf fBHA 00 1 11 )( 1 ),( du u duufmNAeBHA 0 )( 1 ),( entonces )(),( Si duufmNAfmNA eS f S Costes medios para otros sondeos II Proposición: Si se usan sondeos lineales: 2)1( 1 1 2 1 ),()( mNAi fSL 1 1 1 2 1 )1( 1 1 2 11 ),()( 0 2 dumNAii eSL En esta sección … Hemos aprendido El Concepto tabla hash. Los mecanismos de construcción y búsqueda en una tabla hash. El concepto de función hash uniforme Algunos tipos universales de funciones hash (división y multiplicación). En esta sección …… Y también Los principales métodos de resolución de colisiones en una tabla hash: encadenamiento y direccionamiento abierto Los principales métodos de sondeo en una tabla hash con direccionamiento abierto. A estimar el rendimiento medio de las búsquedas con o sin éxito en el caso de sondeos aleatorios. A reducir el rendimiento medio de las búsquedas con éxito al rendimiento de las búsquedas sin éxito. Funcionamiento y construcción de tablas hash Diseño de tablas hash que aseguren un cierto rendimiento Estimación de costes medios de búsquedas con éxito a partir de costes medios sin éxito Problemas a resolver (al menos) 128, 129, 130, 131, 133, 134, 135, 136 Herramientas y técnicas a trabajar 2013Tema1Intro.pdf Tema 1: Introducción J.Dorronsoro, P. Varona, C. Aguirre 1 1.1 Introducción al Análisis de Algoritmos J.Dorronsoro, P. Varona, C. Aguirre 2 Tiempo Abstracto de Ejecución (TAE) ¿Qué analizar en un algoritmo? Corrección. Uso de memoria. Rendimiento (tiempo de ejecución). ¿Cómo medir el rendimiento? Mediante un reloj (tiempo puro de ejecución) Intuitivo pero problemático … Analizando el pseudocódigo: tiempo abstracto de ejecución (tae) J.Dorronsoro, P. Varona, C. Aguirre 3 ¿Cómo medir el tae? Opción 1: Contar el número de sentencias básicas (líneas acabadas en ; que no son llamadas a función) que ejecuta el algoritmo dada una entrada I. Opción compleja Depende de cómo se escriba el pseudocódigo Aporta información innecesaria. Esto es, damos un tae de 1 a las sentencias básicas Pero vamos a ver un ejemplo J.Dorronsoro, P. Varona, C. Aguirre 4 Cálculo del TAE Ejemplo. SelectSort (Pseudocódigo) void SelectSort(Tabla T, ind P, ind U) i=P; mientras i<U: min=i ; para j de i+1 a U : si T[j]<T[min] : min=j ; swap(T[i],T[min]) ; i++; J.Dorronsoro, P. Varona, C. Aguirre 5 Funcionamiento de SelectSort Ejemplo. SelectSort Entrada: T=[4,3,2,1], P=1, U=4. Iteración Operaciones Tabla i=1 min=4 swap(T[1],T[4]) [1,3,2,4] i=2 min=3 swap(T[2],T[3]) [1,2,3,4] i=3 min=3 swap(T[3],T[3]) [1,2,3,4] J.Dorronsoro, P. Varona, C. Aguirre 6 Funcionamiento de SelectSort II En más detalle: Entrada: T=[4,3,2,1], P=1, U=4. 1 3 2 4 1 2 3 4 i=1 1 2 3 4 1 2 3 4 i=2 1 2 3 4 1 2 3 4 i=3 i=4 Fin (i=U) min =1 j=2 ¿T[2]<T[1]? Si → min=2 j=3 ¿T[3]<T[2]? Si → min=3 j=4 ¿T[4]<T[3]? Si → min=4 min=4, swap(T[1],T[4]) Bucle 2 min =2 j=3 ¿T[3]<T[2]? Si → min=3 j=4 ¿T[4]<T[3]? No → min=3 Bucle 2 min=3, swap(T[2],T[3]) min =3 ¿T[4]<T[3]? No → min=3Bucle 2 min=3, swap(T[3],T[3]) 4 3 2 1 1 2 3 4 J.Dorronsoro, P. Varona, C. Aguirre Bucle 1 7 TAE de SelectSort SelectSort funciona con 2 bucles anidados void SelectSort(Tabla T, ind P,ind U) i=P; mientras i<U: min=i; para j de i+1 a U: si T[j]<T[min] : min=j; swap(T[i],T[min]); i++; Vamos a intentar calcular su TAE J.Dorronsoro, P. Varona, C. Aguirre Bucle 2Bucle 1 8 TAE de SelectSort II Cálculo de taeSelectsort(T;P,U): void SelectSort(Tabla T, ind P,ind U) i=P; mientras i<U: min=i; para j de i+1 a U: si T[j]<T[min]: min=j; swap(T[i],T[min]); i++; Bucle de P a U-1 bucle 1 U-P iteraciones J.Dorronsoro, P. Varona, C. Aguirre bucle 2 U-i iteraciones Bucle de i+1 a U 9 Parece que el número de bucles y su tamaño determina el tae TAE de SelectSort III J.Dorronsoro, P. Varona, C. Aguirre 10 32/52/3 2/)1(3)1(41 2/))(1(3)(41 3)(41))(34(1 )),,(4(1))((1),,( 2 1 1 1 2 1 NN NNN PUPUPU jPUiU UiTtaeiitertaeUPTtae U Pi PU j U Pi bucle U Pi SS Hemos llegado a un tae de la forma f(N) Pero hay cosas sueltas, sobre todo en los coeficientes Ejemplo: es el de tae (swap) 1? ó 3? Observando que N=U-P+1 es el tamaño de T, se tiene 2/)1( 1 1 NNi PUN N i ¿Cómo simplificar y normalizar el TAE? Observación: el TAE de SS está dominado por el bucle más interno Opción 2. Definir una operación básica y contar el número de veces que la ejecuta el algoritmo A sobre una entrada I (nA(I)) Tomar como tiempo abstracto de ejecución del algoritmo A, para la entrada I el número de operaciones básicas que ejecuta A sobre I: taeA(I)= nA(I) . Operación básica: Se ha de encontrar en el bucle más interno del algoritmo (es la operación que más veces se ejecuta). Debe ser representativa del algoritmo (pero también de otros que resuelven el mismo problema). J.Dorronsoro, P. Varona, C. Aguirre 11 Vuelta al psc de SelectSort void SelectSort(Tabla T, ind P, ind U) i=P; mientras i<U: min=i ; para j de i+1 a U : si T[j]<T[min] : min=j ; swap(T[i],T[min]) ; i++; J.Dorronsoro, P. Varona, C. Aguirre 12 Operación básica de SelectSort Operación básica Debe estar en el bucle más interno Ser “representativa” del algoritmo. Un buen candidato a ser OB de SelectSort es la operación si T[j]<T[min]; . Esta operación se denomina “comparación de claves” (CDC). Efectivamente, se encuentra en el bucle mas interno. Es representativa de SelectSort y de otros muchos algoritmos de ordenación J.Dorronsoro, P. Varona, C. Aguirre 13 Análisis del rendimiento de SelectSort Cálculo de nSelectSort(T,P,U) void SelectSort(Tabla T, ind P,ind U) i=P; mientras i<U: min=i; para j de i+1 a U: si T[j]<T[min]: min=j; swap(T[i],T[min]); i++; 1 1 1 1 1 1 1 1 1 2 )(1),,(),1,( N j N i N i N ij N i bucleSelectSort jiNNiTnNTn Bucle de P a U-1 222 )1( NNNN 2 bucle 1 U-P iteraciones J.Dorronsoro, P. Varona, C. Aguirre bucle 2 U-i iteraciones Bucle de i+1 a U 14 Ejemplo: Búsqueda Binaria Búsqueda Binaria ind BBin(Tabla T, ind P, ind U, clave k) mientras P≤U : m=(P+U)/2; si T[m]==k : devolver m; else si k < T[m] : U=m-1; else : P=m+1; devolver error; Importante: BBin sólo funciona si la tabla T está ordenada. J.Dorronsoro, P. Varona, C. Aguirre 15 En cada iteración o hay retorno o la tabla se reduce El tamaño de la tabla es aproximadamente la mitad tras cada iteración Si se sale del bucle P≤U porque P > U significa que la clave buscada k no está en T. ¿Cómo funciona BBin? P Um m+1m-1 k<T[m] k>T[m] Si k<T[m] P UP=m+1U=m-1 Si k>T[m]Si k==m Devolver m J.Dorronsoro, P. Varona, C. Aguirre 16 OB para BBin Un buen candidato a ser OB es la operación: si T[m]==k : ….. else si k < T[m] : …… else : …….. Se trata de nuevo de una operación de comparación de clave Aunque hay dos sólo la contamos una vez J.Dorronsoro, P. Varona, C. Aguirre 17 Análisis de rendimiento de BBin nBBin(T,P,U,k)= número de iteraciones (P<U) ≤ número de veces que se puede dividir un número N entre 2. Tras cada iteración el tamaño de la tabla es menor que: Ejercicio: Realizar el calculo anterior, contando todas la sentencias básicas en lugar de solamente la OB Solución: nBBin ≤5 log2N + 2 1 2 ....... 22 2 k NNNN k=máximo de divisiones por 2=número máximo de iteraciones k)N,(T,1,n22 BBin1 Nlog2kN kk J.Dorronsoro, P. Varona, C. Aguirre 18 Observaciones sobre tae Observación 1: Parece que para cualquier algoritmo A, a sus entradas I se les puede asignar un tamaño de entrada ((I)) y se puede encontrar una cierta función de N, fA(N) tal que: taeA(I)=nA(I) ≤ fA((I)) En los ejemplos vistos A I fA SelectSort (T,P,U) U-P+1 N2/2-N/2 BBin (T,P,U,k) U-P+1 log2N J.Dorronsoro, P. Varona, C. Aguirre 19 Observaciones sobre tae Observación 2: El tae permite Generalizar los tiempos de ejecución en función del tamaño de la entrada. Estimar tiempos reales de ejecución. Ejemplo: SelectSort con I tal que (I)=N e I’ tal que (I’)=2N taeSSort(I)= N2/2+…, taeSSort(I’)= (2N)2/2+…=4N2/2+… ~ 4taeSSort(I) En general si (I’)=kN se tiene taeSSort(I’) ~k2taeSSort(I) Supongamos que una tabla con N=1000 tarda 1seg. en ser ordenada. Entonces Tamaño 1000 2000 10000 100000 Tiempo real 1s 4s 100s 10000s J.Dorronsoro, P. Varona, C. Aguirre 20 Ejemplo: método de la Burbuja Ordenación por burbuja (BurbujaSort_v1). BurbujaSort_v1(Tabla T, ind P,ind U) para i de U a P+1: para j de P a i-1: si T[j]>T[j+1]: swap(T[j],T[j+1]); Índice j: burbuja que intenta subir. Si no puede, cambiamos de burbuja En cada iteración en i el final de la tabla se va ordenando de derecha a izquierda J.Dorronsoro, P. Varona, C. Aguirre 21 BubbleSort_v1 Entrada: T=[4,3,2,1], P=1, U=4. Funcionamiento de la Burbuja i j Operaciones Tabla 4 1 T[1]> T[2] ? Si swap(T[1],T[2]) 3,4,2,1 4 2 T[2]> T[3] ? Si swap(T[2],T[3]) 3,2,4,1 4 3 T[3]> T[4] ? Si swap(T[3],T[4]) 3,2,1,4 3 1 T[1]> T[2] ? Si swap(T[1],T[2]) 2,3,1,4 3 2 T[2]> T[3] ? Si swap(T[2],T[3]) 2,1,3,4 2 1 T[1]> T[2] ? Si swap(T[1],T[2]) 2,1,3,4 Burbuja J.Dorronsoro, P. Varona, C. Aguirre 22 j=1 T[1]> T[2] ? Si 4 3 2 1 43 2 1 Swap(T[1],T[2]) 1 2 43 1 2 43 j=2 T[1]> T[2] ? Si3 4 2 1 23 4 1 Swap(T[2],T[3]) 1 2 43 1 2 43 j=3 T[1]> T[2] ? Si 3 2 4 1 23 1 4 Swap(T[3],T[4]) 1 2 43 1 2 43 j=1 T[1]> T[2] ? Si 3 2 1 4 32 1 4 Swap(T[1],T[2]) 1 2 43 1 2 43 j=2 T[1]> T[2] ? Si 2 3 1 4 12 3 4 Swap(T[2],T[3]) 1 2 43 1 2 43 j=1 T[1]> T[2] ? Si 2 1 3 4 21 3 4 Swap(T[1],T[2]) 1 2 43 1 2 43 i=4 i=3 i=2 J.Dorronsoro, P. Varona, C. Aguirre 23 Rendimiento de la Burbuja OB? CDC!! Ordenación por burbuja (BurbujaSort_v1). BurbujaSort_v1(Tabla T, ind P,ind U) para i de U a P+1: para j de P a i-1: si T[j]>T[j+1] : swap(T[j],T[j+1]); Entonces OB(i-1)-P+1 Iteraciones 22 )1(1),1,( 122 1 1 1_ NiiNTn N i N i N i i j vBSort 2N J.Dorronsoro, P. Varona, C. Aguirre 24 Observaciones sobre el tae de la Burbuja El tae de BurbujaSort_v1 (y de SelectSort) NO depende de la entrada (es siempre N2/2-N/2). Se tarda lo mismo en ordenar una tabla desordenada que una tabla ordenada!!! En SelectSort no tiene remedio: No se puede saber si T ya está ordenada J.Dorronsoro, P. Varona, C. Aguirre 25 Mejorando la Burbuja En BurbujaSort_v1 sí se puede saber si T está ordenada Ejemplo: T = [ 1 2 3 4 ] En la primera iteración no se hacen swaps, pues la subtabla está ordenada Se puede añadir un flag para comprobar si se hacen o no swaps en el bucle interno Si no se hacen, la subtabla ya está ordenada y también la tabla completa Se puede terminar el algoritmo y mejorar así el rendimiento. J.Dorronsoro, P. Varona, C. Aguirre 26 Rendimiento de la V2 de la Burbuja Ordenación por burbuja (BurbujaSort_v2). BurbujaSort_v2(Tabla T, ind P,ind U) Flag=1; i=U; mientras (Flag==1 && i≥P+1) : Flag=0; para j de P a i-1 : si T[j]>T[j+1] : swap(T[j],T[j+1]); Flag=1; i--; Ahora se tiene nBSort_v2([1,2,….N])=N-1 y para el caso peor se sigue teniendo nBSort_v2(T,1,N)≤ N2/2-N/2 J.Dorronsoro, P. Varona, C. Aguirre 27 Pero … Estamos trabajando con algoritmos de manera individual … Pero queremos comparar unos algoritmos con otros Q: ¿Cómo comparar dos algoritmos? J.Dorronsoro, P. Varona, C. Aguirre 28 Comparación de Algoritmos Sólo `posible sobre algoritmos “parecidos” 1. Que resuelvan el mismo problema (ordenación, búsqueda) 2. Que tengan la misma operación básica. Agrupamos los algoritmos en familias F que cumplan las condiciones 1 y 2. Ejemplo F={Algoritmos de ordenación por comparación de clave} ={InsertSort, SelectSort, BubbleSort, QuickSort, MergeSort,…..} 29 Comparación de Algoritmos II Método a seguir 1. Para todo algoritmo AF encontrar fA(N) tal que nA(I) ≤ fA((I)) con (I) el tamaño de entrada 2. Diremos que A1 es mejor que A2 si fA1(N) es “menor” que fA2(N) Sólo tiene sentido la comparación para entradas “grandes” = asintótica Sólo compararemos fA1(N) y fA2(N) cuando N es grande (es decir para N →∞): 30 En esta sección hemos aprendido… La medida básica de eficacia de algoritmos El concepto de operación básica El funcionamiento de algunos algoritmos simples (BBin, BurbujaSort, SelectSort). El cálculo del tae de los algoritmos simples anteriores como número de ejecuciones de su OB. Cómo enfocar la comparación del algoritmos J.Dorronsoro, P. Varona, C. Aguirre 31 Herramientas y técnicas a trabajar … Sumatorios Estimación del número de iteraciones en bucles Buen conocimiento del funcionamiento del algoritmo a analizar Problemas a resolver: los recomendados de la sección 1 de las hojas de ejercicios y problemas (al menos!!) J.Dorronsoro, P. Varona, C. Aguirre 32 1.2 Estimación del crecimiento de funciones J.Dorronsoro, P. Varona, C. Aguirre 33 Comparación asintótica de funciones: o Definición 1 (f=o(g), f “<“g): Si f y g son funciones positivas, decimos que f=o(g) si Ejemplos f=Nk , g=Nk+ε f=log(N) , g=Nε f=(log(N)) k , g=Nε (ejercicio; se puede hacer por L’Hôpital) 0 )( )(lim Ng Nf N 34 Comp. asintótica de funciones: O Definición 2 (f=O(g), f “≤“g): f=O(g) si existen N0 y C ≥0 tales que para todo N ≥N0 f(N)≤Cg(N) Ejemplo f=N2 , g=N2+√N Y también g = O(f) Interpretación: g es mayor o igual que f “eventualmente y con ayuda” 35 Observaciones sobre f=O(g) f=o(g) f=O(g) El reciproco a lo anterior es falso: f=O(g) f=o(g) Las constantes “no importan” en O, es decir, si f=O(g) f=O(kg) donde k > 0. Si f=O(g) y h=o(g) entonces f=O(g+h), pues g+h = O(g) Decir f=O(N2+N) no añade precisión Basta con f=O(N2) 36 Comp. asintótica de funciones: Definición 3 (f=(g), f “≥“g) f=(g) si g=O(f) Definición 4 (f=(g), f “=“g) f= (g) si f=O(g) y f=(g) Observamos que f=(g) g=(f) Además f =(g) si 0 )( )(lim L Ng Nf N 37 Comp. asintótica de funciones: ~ Definición 5 (f~g): Decimos que f es asintóticamente equivalente a g si Ejemplo f(N)=N2+√N+log N, g(N)=N2 Observación f~g f=(g) Pero el recíproco es falso 1 )( )( lim Ng Nf N 38 Comp. asint. de funciones: f=g+O(h) Definición 6 (f=g+O(h)) Si h=o(g) entonces decimos que f=g+O(h) si |f- g|=O(h) Ejemplo f(N) = N2 + √N + log(N), g(N)=N2. Entonces f = g + O(√N) 39 Comparación asintótica de funciones Tenemos una escala de precisión decreciente Si f=g+O(h) f~g Si f~g, entonces f=(g) Si f=(g) entonces f=O(g) Pero los recíprocos son falsos 40 Comparación asintótica de funciones II Además: Si f=O(g) y f’ = O(g’), entonces f + f’ = O(g + g’) f f’ = O(g g’) Si P(N) es un polinomio de grado k se tiene que P(N)=akNk+O(Nk-1) 41 Crec. de progs. aritméticas y geométricas Observaciones: )( 22 )1()( 2 1 NONNNiSNf N i N 1 1 1 x xxxS NN i i N x x x xxS N N N 11 1 xSi 1 )( 1 xSi NN xS NSN 1 xSi 42 Ya hemos visto Progresión geométrica (muy importante!!) Crecimiento de funciones derivadas Serie derivada Suma de potencias cúbicas Nos interesa el crecimiento y no tanto la fórmula cerrada Se puede simplificar? )( 11 N N i i N i i N Nxxdx dxixS )( 36 )12)(1( 23 1 2 NONNNNiS N i N 43 Estimaciones de crecimiento de sumas ¿Que hacer cuando no tenemos una expresión cerrada para una suma ? Podemos aproximar la suma mediante integrales. N i i i N i N i i i i i i i dxxfifdxxfdxxfifdxxf 1 1 1 1 1 1 1 )()()()()()( dxxfSdxxf N N N 1 10 )()( f(x) creciente N i N ifS 1 )( 44 Estimaciones de crecimiento de sumas II Análogamente, si f(x) es decreciente Algunas sumas que se estiman por este método dxxfSdxxf N N N 1 10 )()( )( 1 también o 1 11 1 k k N k N N i k N NOk NS k NSiS )log()!log()log( 1 NNSNiS N N i N harmónico) número simo-(N )log(1 1 NH i H N N i N Nota: Se recomienda seguir en la pizarra o en los apuntes el método por el cual se han obtenido estas expresiones, ya que cada una de ellas presenta peculiaridades sobre la aplicación directa de la fórmula de la acotación por integrales. 45 En esta sección hemos aprendido… Los diferentes tipos de comparaciones asintóticas entre funciones. Cómo estimar el crecimiento de algunas funciones, mediante fórmulas cerradas o mediante integrales. 46 Herramientas y técnicas a trabajar … Trabajo básico con las estimaciones o, O, etc Aplicación de las estimaciones o, O, etc. Estimación mediante integrales del crecimiento asintótico de sumas Problemas a resolver: los recomendados de la sección 2 de las hojas de ejercicios y problemas (al menos!!) J.Dorronsoro, P. Varona, C. Aguirre 47 1.3 Complejidad de Algoritmos J.Dorronsoro, P. Varona, C. Aguirre 48 Complejidad de Algoritmos Hasta ahora, el trabajo realizado por un algoritmo dependía de cada entrada en particular: nA(I) ≤ fA((I)). En algunos algoritmos hay un desequilibrio muy grande entre diferentes entradas, por ejemplo NBSort_v2([N,N-1,….,1],1,N)=1/2(N2-N) (mucho) NBSort_v2([1,2,….,N],1,N)=(N-1) (muy poco) Nos gustaría precisar la definición del trabajo que realiza un algoritmo, Para ello definimos el Espacio de entradas de tamaño N de un algoritmo A como: EA(N)={I entrada de A/ (I)=N} 49 Ejemplo: BSort EBSort(N)={(T,P,U)/U-P+1=N} Con, P,U y T cualquiera este espacio es inmanejable (demasiado grande) => es necesario hacer este espacio mas pequeño. Una simplificación sencilla es tomar P=1 y U=N. Otra simplificación es tomar TN (permutaciones de tamaño N), ya que lo importante es el desorden entre los elementos de la tabla. Con estas simplificaciones EBSort(N)= N y | EBSort(N) |=N! 50 Ejemplo: BBin EBBin(N)={(T,P,U,k)/k cualquiera, U-P+1=N, T ordenada} Una simplificación sencilla es tomar P=1 y U=N. Como T está ordenada, tomamos T=[1 … N] Como claves en la tabla tomamos k=1, …, N BBin hace el mismo número de cdcs para cualquier k no en T => añadimos la clave de error otra Con estas simplificaciones EBBin(N)= { 1, 2, … N, otra} y |EBBin(N) |=N+1 51 Casos mejor, peor, medio Definiciones de complejidad WA(N)=max {nA(I)/ IEA(N)} Caso peor BA(N)=min {nA(I)/ IEA(N)} Caso mejor AA(N)= donde p(I) es la probabilidad con la que aparece la entrada I Caso medio )()( )( IpIn NEI A A Observación: BA(N) ≤ AA(N) ≤ WA(N) 52 Complejidad en el caso peor ¿Cómo estimar el caso peor de un algoritmo? Paso 1: Encontrar fA(N) tal que si (I)=N se tiene nA(I) ≤ fA(N) Paso 2: Encontrar una entrada Î, que sea la entrada peor del algoritmo, Î tal que nA(Î) ≥ fA(N) Por el paso 1, se tiene WA(N)≤fA(N) Por el paso 2 WA(N) ≥ fA(N), Por tanto WA(N) = fA(N) El caso mejor se estima de una forma similar se deja como ejercicio escribir ambos pasos para el caso mejor). 53 Caso peor de BSort Ejemplo: WBSort2(N) (1) Ya vimos que para toda N nBSort2()≤N2/2+O(N) (2) Si =[N,N-1,N-2,…1] entonces nBSort2()=N2/2+O(N) Por (1) y (2) se tiene WBSort2(N)= N2/2+O(N) Ejercicio: demostrar que BBSort2(N)=N-1 54 Complejidad en el caso medio El caso medio suele ser el mas difícil de calcular. En general (aunque no siempre) supondremos equiprobablidad en el espacio de entradas, es decir p(I)=1/|EA(N)| Ejemplos: En BSort p()=1/N!, y En BBin p(k)=1/(N+1) 55 Caso medio de búsqueda lineal Consideramos la Búsqueda Lineal equiprobable. Operación básica: CDC (si T[i]==k) EBLin(N) = {1, 2, …, N, otra} BLin(tabla T, ind P, ind U, clave k) para i de P a U; si T[i]==k; devolver k; devolver ERROR; 56 Caso medio de búsqueda lineal II EBLin(N) = {1,2,3,…,N, otro}, |EBLin(N)| = N+1 Se tiene p(k==i) = 1/(N+1) (1≤i≤N) p(k==otro) = 1/(N+1) Si k≠T[i] nBlin(k) = N Si k=T[i] nBlin(k) = i En consecuencia WBlin(N) = N, BBlin(N) = 1. ABlin(N) = N/2 + O(1) 57 Caso medio de búsqueda lineal III Ejemplo: B. lineal con éxito no equiprobable. En este caso se tiene que CN es una constante de normalización que garantiza SN y CN se aproximan (por ejemplo, por integrales) Se obtiene finalmente una aproximación para A. )(1])[(])[()( 11 if C iiTkpiTknNA N N i N i BLinBLin )(1])[( if C iTkp N N i N N i N ifCif C 11 )(decir es ,1)(1 )( donde ,)(1 11 ifiS C Sifi C N i N N N N iN 58 Caso medio de búsqueda lineal IV Por ejemplo, si tenemos Aproximando por integrales se tiene De lo que se obtiene fácilmente: Este ultimo paso no es difícil, pero tampoco inmediato pues hay que demostrar la última equivalencia asintótica. i i C iTkp N )log(1])[( N i N i N N i N ii iiS i iCentonces 111 )log()log(y )log( )log(y (log(N)) 2 1 2 NNSC NN )log( 2)( N NNABLin 59 En esta sección hemos aprendido… Las expresiones de los casos mejor, peor y medio de un algoritmo. Cómo calcular el caso mejor peor y medio de algunos algoritmos simples (BSort y Blin) 60 Herramientas y técnicas a trabajar … Cálculo de casos peores y mejores de algoritmos simples Cálculo de caso medio de búsqueda lineal y variantes Problemas a resolver: los recomendados de la sección 3 de las hojas de ejercicios y problemas (al menos!!) J.Dorronsoro, P. Varona, C. Aguirre 61 2011_Tema_2_Algoritmos_de_Ordenacion.pdf Tema 2 Algoritmos de ordenación 1 2.1 Algoritmos locales de ordenación 2 InsertSort La idea de InsertSort consiste en tener los i-1 primeros elementos de la tabla ordenados entre sí al inicio de la iteración i. En la iteración i se coloca el elemento (i) en la posición correspondiente entre 1 e i de tal forma que pasan a estar ordenados entre sí los i primeros elementos de la tabla. (2) …. (i-1) (i) (i+1) (1) ….. (N) Ordenados Elemento a insertar Elemento a insertar Posición de inserción Elemento insertado 1 2 i-1 i i+1 N Ordenados Ordenados 1 3 6 7 2 5 4 1 3 3 6 7 5 4 1 2 3 6 7 5 4 3 InsertSort InsertSort(Tabla T, ind P, ind U) para i de P+1 a U; A=T[i]; j=i-1; mientras (j ≥ P && T[j]>A); T[j+1]=T[j]; j--; T[j+1]=A; Observaciones: El trabajo de bucle interno depende de la entrada El trabajo sobre una entrada será: 1≤nIS(,i)≤i-1 Operación Básica (CDC) N i ISIS inn 2 ),()( 4 InsertSort: casos mejor y peor Tenemos que 1≤nIS(,i)≤i-1; por tanto se tiene que N: Caso peor Paso 1: Por lo anterior N, nIS()≤N(N-1)/2 Paso 2: nIS([N,N-1,N-2,…..,1])= N(N-1)/2 Caso mejor Paso 1: Por lo anterior N, nIS()≥N-1 Paso 2: nIS([1,2,3,…..,N])= N-1 2 )1( )(11),(1 222 NN nNiin IS N i N i IS N i WIS(N)=N(N-1)/2 BIS(N)=N-1 5 InsertSort: caso medio El caso medio para IS es Estado de la tabla en la iteración i NNN N i ISISISIS in N n N npNA 2 ),( ! 1 )( ! 1 )()()( N i IS N i IS iNAin N N 22 ),(),( ! 1 Nº medio de operaciones que realiza IS en la iteración i (2) …. (i-1) (i) (i+1) (1) ….. (N) Ordenados Elemento a insertar 1 2 i-1 i i+1 N 6 InsertSort: caso medio Observación: al abordar IS la entrada (i), ésta puede acabar en las posiciones i, i-1, i-2, …, j, …, 2, 1 haciendo respectivamente 1, 2, 3, …, i-j+1, …, i-1 e i-1 cdcs respectivamente Posición Final CDC perdidas ((i)<(j)) CDC ganadas ((i)>(j)) Total CDC i 0 1 ((i)>(i-1)) 1=i–i+1 i-1 1 ((i)<(i-1)) 1 ((i)>(i-2)) 2=i–(i-1)+1 i-2 2 ((i)<(i-1), (i)<(i-2)) 1 ((i)>(i-3)) 3=i–(i-2)+1 …j… i-j 1 ((i)>(j-1) i–j+1 3 i-3 ((i)<(i-1),…, (i)<(3)) 1 ((i)>(2)) i-2=i–3+1 2 i-2 ((i)<(i-1),…, (i)<(2)) 1 ((i)>(1)) i-1=i–2+1 1 i-1 ((i)<(i-1),…, (i)<(1)) 0 i-1 7 InsertSort: caso medio Esto es, nIS(i→j)=i-j+1 si 1<j≤i y nIS(i→1)=i-1, donde nIS(i→j) en el numero de CDC necesarias para insertar el elemento (i) en la posición j. Q: con qué probabilidad acabará (i) en la posición j? Si las son equiprobables, es razonable pensar que P((i) acabe en j) = 1/i para todo j entre 1 e i De aquí se deduce que el trabajo medio AIS (N, i) de IS sobre la entrada i-ésima de una tabla de N elementos será i/2 + O(1) Y por tanto AIS (N) = N 2/4 + O(N) En más detalle … 8 InsertSort: caso medio Recordamos que , donde p(j) es la probabilidad de que el elemento (i) termine en la posición j. Asumimos por equiprobabilidad que p(j) = 1/i (j=1,2,…i) , con lo que se tiene: Dado que , sustituyendo lo anterior resulta: i j ISIS jinjpiNA 1 )()(),( i ii iji i jin i iNA i j i j ISIS 1 2 1 )1()( 1 )( 1 ),( 11 N i ISIS iNANA 2 ),()( )( 4 1 2 11 2 1 )( 21 1 1 12 NO N i i i i ii NA N i N i N i IS 9 InsertSort: caso medio Sabemos que WIS (N) = N 2/2 + O(N) AIS (N) = N 2/4 + O(N) Conclusión: IS es algo mejor que SS y que BS, pero no mucho más en el caso medio e igual en el caso peor Q: hemos llegado al límite de eficacia en ordenación? 10 Cotas inferiores ¿Cuánto podemos mejorar un algoritmo de ordenacion por cdcs? Es decir ¿existe una f(N) universal tal que nA()≥f(N) para cualquier A? Obviamente se tiene que nA()≥N, por tanto nA()=(N). ¿Existe algún algoritmo que alcance esa cota mínima? Si existe ¿cómo es ese algoritmo y en que condiciones la alcanza ? Herramienta: medida del desorden de una tabla 11 ¿Cómo medir el desorden de una tabla? Las operaciones que realiza un algoritmo dependen del orden de la tabla. ¿Como medir el orden o desorden que hay en una tabla?. Definición: Decimos que dos índices i<j están en inversión si (i)> (j) Ejemplo: =(3 2 1 5 4) Inversiones de =((1,2),(1,3),(2,3),(4,5)) => 4 inversiones. Inv()=4 En la práctica decimos que “3 está en inversión con 2” en vez de que “los índices 1 y 2 están en inversión” 4 1 2 3 5 12 ¿Cómo medir el desorden de una tabla? Observaciones 1. inv([1,2,3,…..,N-1,N])=0 2. inv([5,4,3,2,1])=10 3. inv([N,N-1,N-2,….,2,1])=N+(N-1)+….+2+1=N2/2-N/2 Obs: No puede haber ninguna permutación con más inversiones que = [N,N-1,N-2,….,2,1] ya que inv([(1), (2),…., (N)])= inv((1))+inv((2))+ …+inv((N-1))+inv((N))≤ ≤(N-1)+(N-2)+…..+1=N2/2-N/2 ≥ N-1 ≥ N-2 ≥ 1 13 Cotas inferiores para algoritmos locales Definición: Un algoritmo de ordenación por comparación de clave (CDC) es local si por cada CDC que realiza el algoritmo se deshace a lo sumo una inversión. InsertSort, BurbujaSort y (moralmente) SelectSort son locales Obs: Si A es un algoritmo local, el número mínimo de CDC que realizará A será el número de inversiones que tenga la tabla a ordenar , es decir nA()≥inv(). Caso peor: Si A es local, WA(N)≥N 2/2-N/2 WA(N)≥nA([N,N-1,N-2,…,2,1]) ≥inv ([N,N-1,N-2,…,2,1]) =N 2/2-N/2 Consecuencia: IS, BS y SS son óptimos en el caso peor entre los algoritmos locales 14 Cotas inferiores en el caso medio Definición: Si N definimos su traspuesta, t como t(i)= (N-i+1). Ejemplo =[3,2,1,5,4] entonces t=[4,5,1,2,3] Observaciones: (t)t= inv([3,2,1,5,4])+inv([4,5,1,2,3])=3+7=10=(5*4)/2 inv([5,4,3,2,1])+inv([1,2,3,4,5])=10+0=10=(5*4)/2 Proposición: Si N inv()+ inv(t)=N(N-1)/2 Demo: Si 1 ≤ i < j ≤ N, o bien (i,j) es inversión de o (N-j+1, N-i+1) lo es de t 15 Cotas inferiores en el caso medio Si A es local AA(N)≥N 2/4+O(N) InsertSort es óptimo para el caso medio entre los algoritmos locales. tNN t AA invinv N inv N n N NA , )()( ! 1 )( ! 1 )( ! 1 )( )( 42 ! 2 )1( ! 1 1 2 )1( ! 1 2 , NO NNNN N NN N t A local Los algoritmos locales de ordenación son poco eficaces. 16 En esta sección hemos aprendido… El algoritmo de ordenación InsertSort, así como el cálculo de sus casos mejor, peor y medio. El concepto de algoritmo de ordenación local, así como sus cotas inferiores para los casos peor y medio. 17 Herramientas y técnicas a trabajar … Funcionamiento de InsertSort Evolución de algoritmos locales Casos peor, medio y mejor de InsertSort y algoritmos similares y variantes Detección y cuenta de inversiones en permutaciones Rendimiento de algoritmos locales en permutaciones concretas Problemas a resolver (al menos!!) : 32, 33, 34, 35, 37, 39, 40, 44, 45, 46 J.Dorronsoro, P. Varona, C. Aguirre 18 2.2 Algoritmos recursivos de ordenación 19 Métodos divide y vencerás (DyV) La idea de los algoritmos divide y vencerás es la siguiente: Partir la tabla T en dos subtablas T1 y T2 Ordenar T1 y T2 recursivamente. Combinar T1 y T2 ya ordenados en T también ordenada. Pseudocódigo general de algoritmos DyV Una primera opción es implementar una función Partir sencilla y una función Combinar complicada. Resultado: MergeSort. DyVSort(tabla T) si dim(T)≤dimMin : directSort(T); else : Partir(T,T1,T2); DyVSort(T1); DyVSort(T2); Combinar(T,T1,T2); 20 MergeSort Va a requerir memoria dinámica status MergeSort(tabla T, ind P, ind U) si P>U: devolver ERROR; si P==U: //tabla con un elemento devolver OK; else: M=(P+U)/2; // ”partir” MergeSort(T,P,M); MergeSort(T,M+1,U); devolver Combinar(T,P,M,U); 21 Combinar MergeSort Ejemplo 5 3 1 4 6 2 1 2 3 4 5 6 Partir 5 3 1 4 6 2 Partir Partir 5 3 4 6 Partir Partir 1 2 Combinar 3 5 4 6 Combinar Combinar 1 3 5 2 4 6 Combinar 1 2 3 4 5 6 5 3 4 6 22 MergeSort: Combinar status Combinar(Tabla T,ind P,ind U,ind M) T’=TablaAux(P,U); Si T’==NULL: devolver Error; i=P;j=M+1;k=P; mientras i≤M y j≤U: si T[i]<T[j]: T’[k]=T[i];i++; else: T’[k]=T[j];j++; k++; si i>M: // copiar resto de tabla derecha mientras j≤U: T’[k]=T[j];j++;k++; else si: j>U: // copiar resto de tabla izquierda mientras i≤M: T’[k]=T[i];i++;k++; Copiar(T’,T,P,U); Free(T’); devolver T; Operación Básica de Combinar y de MS Tabla auxiliar con indices de P a U Copia T’ en T entre los indices P y U 23 1 2 3 4 5 6 Combinar: Ejemplo 1 3 5 2 4 6 1 2 3 4 5 6 i j T 1 2 3 4 5 6 k T’ 1 3 5 2 4 6 i j T 1 2 3 4 5 6 k T’ 1 1 2 3 4 5 6 1 3 5 2 4 6 i j T 1 2 3 4 5 6 T’ 1 2 k 1 2 3 4 5 6 1 3 5 2 4 6 i j T 1 2 3 4 5 6 T’ 1 2 3 k 1 2 3 4 5 6 1 3 5 2 4 6 i j T 1 2 3 4 5 6 T’ 1 2 3 4 5 k 1 2 3 4 5 6 1 3 5 2 4 6 i j T 1 2 3 4 5 6 T’ 1 2 3 4 5 6 k T[1]<T[4] i++,k++ T[3]>T[4] j++,k++ T[2]<T[5] i++,k++ T[3]>T[5] j++,k++ T[3]<T[6] i++,k++ i>M Finalmente copiamos T’ en T y liberamos T’ 24 MergeSort: Rendimiento Observaciones 1. OB: en Combinar T[i]<T[j] 2. nMS()= nMS(i)+ nMS(d)+ nCombinar(, i , d) 3. tamaño (i)=N/2 ; tamaño (d)=N/2 4. N/2 ≤nCombinar(, i , d)≤N-1 Con estas observaciones se tiene: WMS(N) ≤ WMS(N/2 ) + WMS(N/2 ) +N-1; WMS(1)=0. Primer ejemplo de desigualdad recurrente. CG: T(N) ≤ T(N1) + T(N2) + …..+ T(Nk) +f(N), con Ni<N CB: T(1)=X (X constante). 25 MergeSort: Rendimiento, caso peor ¿ Cómo se resuelve una desigualdad recurrente ? Paso 1: Se obtiene una solución particular, por ejemplo sobre un caso particular fácil de calcular. Por ejemplo en el caso de MS, se toma N=2k En el caso de MS, tomando N=2k se tiene la desigualdad recurrente WMS(N) ≤ 2WMS(N/2)+N-1 y WMS(1)=0 Desarrollando en cadena la expresión anterior se obtiene WMS(N) ≤ Nlg(N)+O(N). Paso 2: Se demuestra que la expresión obtenida en el paso 1 es válida para todo N mediante el método de demostración por inducción. Nota importante: Se recomienda ver el desarrollo anterior para ambos pasos en clase o en los apuntes de la asignatura. 26 MergeSort: Rendimiento, casos peor y medio Por un razonamiento similar al del caso peor se tiene que BMS(N) ≥ BMS(N/2 ) + BMS(N/2 ) + N/2 y BMS(1)=0 Tomando, de nuevo N=2k se obtiene la ecuación recurrente BMS(N) ≥ 2BMS(N/2)+N/2 y BMS(1)=0 Resolviendo la desigualdad anterior se obtiene: BMS(N) ≥ (1/2)Nlg(N) Para estimar el caso medio observamos que: (1/2)Nlg(N) ≤ BMS(N) ≤ AMS(N) ≤ WMS(N) ≤ Nlg(N)+O(N), con lo cual se tiene que: AMS(N)=(Nlg(N)) El rendimiento es bueno, pero el algoritmo necesita memoria dinámica y además tiene costes ocultos en la recursión 27 QuickSort En Quicksort (QS), se parte de una función Partir complicada que hace innecesaria una función Combinar. La idea de Partir en QS consiste en elegir una elemento M=T[m] de la tabla a ordenar (pivote). Tras Partir los elementos de la tabla quedan ordenados respecto a M =>no hace falta Combinar. M T[2] T[3] T[N] M=T[1] T[1] T[2] T[i-1] M T[i-1] T[N] i > M < M Partir Ti Td Ejemplo: 28 QuickSort: pseudocódigos status QS(tabla T, ind P, ind U) si P>U: devolver ERROR; si P==U: devolver OK; else: M=Partir(T,P,U); si P<M-1: QS(T,P,M-1); si M+1 < U: QS(T,M+1,U); devolver OK; ind Partir(tabla T, ind P, ind U) M=Medio(T,P,U); k=T[M]; swap(T[P],T[M]); M=P; para i de P+1 a U: si T[i]<k: M++; swap(T[i],T[M]); swap(T[P],T[M]); devolver M; Pivote 29 QuickSort: Elección del pivote El pivote se puede elegir de varias maneras: El primer elemento (devolver P). El último elemento (devolver U). La posición que está en mitad de la tabla (devolver (P+U)/2). Una posición aleatoria entre el primer y ultimo elemento de la tabla (devolver aleat(P,U)). No se garantiza que el valor del pivote sea aproximadamente el valor medio de la tabla 30 Ejemplo 4 5 3 1 6 2 M=1,k=4 swap(T[1],T[1]) 4 5 3 1 6 2 i=2 T[2]>k 4 5 3 1 6 2 i=3 T[3]<k, M=2 swap(T[2],T[3]) 4 3 5 1 6 2 i=4 T[4]<k, M=3 swap(T[3],T[4]) 1 2 3 4 5 6 4 3 1 5 6 2 i=5 T[5]>k 4 3 1 5 6 2 i=6 T[6]<k, M=4 swap(T[4],T[6]) 4 3 1 2 6 5 swap(T[1],T[4]) 2 3 1 4 6 5 < > devolver 4 31 QS: Rendimiento en el caso peor Observaciones 1. OB: en Partir “si T[i]<k” 2. nQS()= nQS(i)+ nQS(d)+ nPartir() 3. nPartir()=N-1 (Si Medio devuelve P, nMedio()=0) Entonces, si i tiene k elementos, d tiene N-1-k elementos y por tanto nQS() ≤ N-1+ W (k) + W(N-1-k) ≤ N-1+ maxk = 1,…, N-1 { W(k) + W(N-1-k) } Esto es, W(N) ≤ N-1+ maxk = 1, …, N-1 { W(k) + W(N-1-k) } Y se puede demostrar por inducción que W(N) ≤ N2/2-N/2 32 QS: Rendimiento en el caso peor Pero además WQS(N) N 2/2-N/2. Consideramos T=[1,2,3,….., N] Partir [2,3,….., N] [1,2,3,….., N] Partir N-1 cdc N-2 cdc [3,….., N] [N-1,N] Partir 1 cdc [N] Partir Por tanto se tiene: nQS([1,2,3,…,N])= (N-1)+(N-2)+…..+1= N2/2-N/2 Luego WQS(N) = N 2/2-N/2 33 QS: Rendimiento en el caso medio De nuevo tenemos nQS()= nQS(i)+ nQS(d)+ N-1. Aproximamos nQS(i)AQS(i-1) y nQS(d)AQS(N-i) con lo que obtenemos nQS() AQS(i-1) + AQS(N-i) + N-1. Y obtenemos la igualdad recurrente aproximada Se puede demostrar 0)1( )]()1([ 1 )1()( 1 A iNAiA N NNA N i QSQSQS )()log(2)( NONNNAQS Nota: Se recomienda seguir la demostración de lo anterior en la pizarra o en los apuntes de la asignatura. 34 En esta sección hemos aprendido… Los algoritmos Quick y MergeSort Sus ecuaciones de rendimiento en los casos peor y medio Cómo resolverlas Cómo escribir la ecuación de rendimiento de un algoritmo recursivos Cómo efectuar estimaciones de ecs. recurrentes Intuyendo soluciones particulares en algunos casos Desplegando para estimar una solución general o particular Estimando el caso general por inducción Herramientas y técnicas a trabajar … Funcionamiento de MergeSort y QuickSort Casos peor, medio y mejor de MS y QS y variantes Estimación del crecimiento de funciones en desigualdades recurrentes Determinación de ecuaciones de rendimiento de algoritmos recurrentes y su resolución Problemas a resolver (al menos!!) : 63, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 78, 79 J.Dorronsoro, P. Varona, C. Aguirre 36 2.3 HeapSort 37 HeapSort Definición: Un heap (montón) es un árbol binario quasicompleto (es decir, solo tiene huecos en los elementos más a la derecha del último nivel). Árbol binario completo Árbol binario quasicompleto (heap) Árbol binario (no heap) Definición: Un Max-heap es un heap tal que subárbol T’ de T se tiene info(T’)>info(T’i), info(T’d) Ejemplo: 7 6 5 4 3 2 1 Observación: Un max-heap es fácil de ordenar. 38 Ordenación de max-heap. 1. Se intercambia el nodo de la raiz con el nodo inferior derecho 2. Se mantiene la condición de max-heap con el nodo recién colocado en la raiz. 7 6 5 4 3 2 1 1 6 5 4 3 2 7 6 1 5 4 3 2 7 6 4 5 1 3 2 7 2 4 5 1 3 6 7 5 4 2 1 3 6 7 3 4 2 1 5 6 7 4 3 2 1 5 6 7 1 3 2 4 5 6 7 3 1 2 4 5 6 7 2 1 3 4 5 6 7 2 1 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4 5 6 7 39 HeapSort: Ordenación en tablas Observaciones: 1. Si recorremos el árbol resultante al final de arriba a abajo y de izquierda a derecha se tiene una tabla ordenada 2. Los nodos de un heap se pueden colocar en una tabla de tal forma que el método sea in-place. Ejemplo: 7 6 5 4 3 2 1 1 0 2 3 4 5 6 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 6 5 4 3 2 1 1 0 2 3 4 5 6 7 6 5 4 3 2 1 0 1 2 3 4 5 6 1 6 5 4 3 2 7 0 1 2 3 4 5 6 swap(T[0],T[6]) 40 HeapSort: Posiciones en tablas que contienen max-heaps Padre →Hijo izquierdo y Padre →Hijo derecho Padre Hijo Izq Hijo der j 2j+1 2j+2 P HI HD 0 1 2 1 3 4 2 5 6 … … … Hijo →Padre H P 1 0 2 0 3 1 4 1 5 2 6 2 … … Hijo Padre j (j-1)/2 41 HeapSort: Creación del heap El proceso anterior permite ordenar un heap ¿Cómo podemos crear un heap a partir de una tabla dada? Se mantiene la condición de heap en todos los nodos internos (nodos que tienen al menos un hijo), de derecha a izquierda y de abajo arriba. 1 2 3 4 5 6 7 1 2 7 4 5 6 3 1 5 7 4 2 6 3 7 5 1 4 2 6 3 7 5 6 4 2 1 3 ya es un heap Ejemplo: 1 2 3 4 5 6 7 0 1 2 3 4 5 6 1 2 7 4 5 6 3 0 1 2 3 4 5 6 1 5 7 4 2 6 3 0 1 2 3 4 5 6 7 5 1 4 2 6 3 0 1 2 3 4 5 6 7 5 6 4 2 1 3 0 1 2 3 4 5 6 42 HeapSort: Pseudocódigo HeapSort(tabla T, int N) CrearHeap(T,N); OrdenarHeap(T,N); CrearHeap(tabla T, int N) si N==1: volver ; para i de (N-2)/2 a 0 : heapify(T,N,i); OrdenarHeap(tabla T, int N) para i de N-1 a 1 : swap(T[0],T[i]); heapify(T,i,0); heapify(tabla T,int N,ind i) mientras ( 2*i+1 ≤ N-1) : ind=max(T,N,i,izq(i),der(i)); if (ind ≠ i) : swap( A[i], A[ind] ) ; i = ind ; else : return; HeapSort CrearHeap OrdenarHeap heapify Donde la función max(T,N,i,izq(i),der(i)) devuelve el índice del elemento de la tabla T que contiene el valor mayor entre i, izq(i), der(i) 43 Profundidad de Heaps Observación: Si T es un heap con N nodos, prof(T)= log(N) Nº de nodos N Ejemplo de Heap Prof. 1 0 2, 3 1 4, 5, 6, 7 2 … … HeapSort: Rendimiento Observaciones: nHeapSort(T)=nCrearHeap(T)+nOrdenarHeap(T) El número máximo de cdc que CrearHeap y OrdenarHeap realizan sobre un nodo es prof(T) prof(T)= log(N) pues T es quasi-completo nCrearHeap(T)≤N log(N) y nOrdenarHeap(T)≤N log(N) WHS(N)=O(Nlog(N)) nCrearHeap ([1,2,…,N])=Nlog(N) El método seguido no es recursivo Es el método de ordenación más eficaz hasta ahora! WHS(N)=(Nlog(N)) 45 En esta sección hemos aprendido… El concepto de Maxheap y su construcción El algoritmo HeapSort y su rendimiento Herramientas y técnicas a trabajar La construcción de Maxheaps La aplicación del algoritmo HeapSort Problemas a resolver (al menos!!) : 83, 90 2.4 Árboles de decisión para algoritmos de ordenación Cotas inferiores para algoritmos de ordenación por cdcs Hasta ahora el mejor algoritmo de ordenación por cdcs es HeapSort Ningún algoritmo de ordenación va a tener un coste mejor que (N) Pregunta: ¿hay algoritmos de ordenación de coste mejor que (Nlog(N))? Respuesta: NO al menos si trabajamos sobre cdcs Herramienta: árboles de decisión Árbol de decisión: Ejemplo InsertSort 1 2 3 1:2 1 2 3 2:3 2 1 3 1:3 1 2 3 1 3 2 1:3 2 1 3 2 3 1 2:3 1 3 2 3 1 2 2 3 1 3 2 1 < < < < < > > > > > 3 IST 1 2 3 1 3 2 2 3 1 2 1 3 3 1 2 3 2 1 Árbol de decisión: definición Si A es un algoritmo de ordenación por comparación de clave y N es un tamaño de tabla, se puede construir su árbol de decisión TA N sobre N cumpliendo las siguientes 4 condiciones: 1. Contiene nodos de la forma i:j (i<j) que indica la cdc entre los elementos inicialmente en las posiciones i y j. 2. El subárbol izquierdo de i:j en TA N contiene el resto del trabajo (cdcs) que realiza el algoritmo A si i < j. 3. El subárbol derecho de i:j en TA N contiene el el resto del trabajo (cdcs) que realiza el algoritmo A si i > j. 4. A cada N le corresponde una única hoja H en TA N y los nodos entre la raíz y la hoja H son las sucesivas cdc que realiza el algorimo A al recibir la permutación para ordenarla. Ejemplo de árbol de decisión: BurbujaSort 1 2 3 1:2 1 2 3 2:3 2 1 3 1:3 1 2 3 1 3 2 1:3 2 1 3 2 3 1 2:3 1 3 2 3 1 2 2 3 1 3 2 1 < < < < < > > > > > 1 2 3 1 3 2 2 3 1 3 1 2 3 2 1 3 BST 1:2 2 1 3 2 1 3 > < * Imposible B B B B B B B=Burbuja Árbol de decisión: consecuencias 1. El número de hojas en TA N es N! =|N|. 2. nA()=nº de cdc=profundidad de la hoja H en TA N 3. Por tanto: )()( Hprofn N AT A )(max)(max)( HprofnNW N A NN TAA Cota inferior en el caso peor I ¿Cuál es la profundidad mínima de un árbol binario de H hojas? Nº de hojas H ABMinimo(H) Prof. 1 0 2 1 3 2 4 2 …. …. …. Cota inferior en el caso peor II Parece que la Prof Mínima de un AB con H hojas es log(H) Para el caso peor se tiene: Como sabemos que log(N!)=(Nlog(N)) se tiene que WA(N)=(Nlog(N)). HeapSort y MergeSort son óptimos para el caso peor. )!log( hojas N!con AB demín prof)(max)( N HprofNW N A N TA Cota inferior en el caso medio I Tenemos Luego AA(N)≥PMmin(N) donde PMmin(k) = mín {prof media(T): T AB con k hojas} Pero LCE: Longitud de Caminos Externos N A N A N TH TAA Hprof N n N NA )( ! 1 )( ! 1 )( )( 1 prof(H) 1 )( T de hojasH TLCE kk Tmediaprof hojaskcon Cota inferior en el caso medio II H1 H2 H3 Suma de estas longitudes=LCE Tenemos hojask tieneT :)(min)( con )!( ! 1 )( min min TLCEkLCE NLCE N NAA Cota inferior en el caso medio III Estimamos LCEmin(k) k T Óptimo LCEmin(k) 1 0 2 2(1+1) 3 5(2+2+1) 4 8(2+2+2+2) 5 12(3+3+2+2+2) …. …. …. Cota inferior en el caso medio IV Se puede demostrar (ver apuntes o clase) LCEmin(k)=klog(k)+k-2 log(k) Dado que Se sigue que MS, QS y HS son óptimos para el caso medio. )!( ! 1 )( min NLCE N NAA ! 2 1)!log(2!)!log(! ! 1 )!log()!log( N NNNN N N N ))log(()!log( NNN ))log(()( NNNAA En esta sección hemos aprendido… El concepto de árbol de decisión para un algoritmo de ordenación por cdc A construir un árbol de decisión para un algoritmo de ordenación por CDC. Las cotas inferiores para los algoritmos de ordenación por CDC Cómo se obtienen mediante el uso de árboles de decisión. La construcción de Árboles de Decisión para tablas de 3 elementos La construcción de Árboles de Decisión parciales para tablas de 4 elementos Problemas a resolver (al menos!!) : 92, 96, 97, 100, 101, 102, 103, 106 Herramientas y técnicas a trabajar
Compartir