Tema2 Transparencias
Tema2 Transparencias
Tema2 Transparencias
Complejidad
Cmo podemos medir y comparar algoritmos, si estos se ejecutan a distintas velocidades y requieren diferentes cantidades de espacio segn en qu ordenador se ejecuten, y con qu lenguaje de programacin (o compilador) hayan sido implementados? Con la simple recogida de los tiempos de ejecucin de los algoritmos indudablemente no.
Tamao del array n 125 250 500 1000 2000 Ordenador A (ms) 12.5 Ordenador B (ms) 2.8
49.3
11.0
195.8
43.4
780.3
172.9
3114.9
690.5
Complejidad
3500 Tiempo de Ejecucin 3000 2500 2000 1500 1000 500 0 125 250 500 T am a o 1000 2000 f 1(n) f 2(n)
f1(n) = 0,0007772n2+0,00305n+0,001
f2(n)=0,0001724n2+0,00400n+0,100
Independientemente de la mquina, el lenguaje de programacin o el compilador que se haya utilizado para la ejecucin del algoritmo A, el tiempo de ejecucin que consume dicho algoritmo SIEMPRE dar lugar a una funcin cuadrtica del tamao del array que trate. Es decir, la forma de la curva ser la misma.
Notacin O.
Los tiempos de ejecucin para diferentes algoritmos dan lugar a diferentes clases de complejidad. Cada clase de complejidad se caracteriza por una familia de curvas distinta. Todas las curvas de una clase de complejidad concreta tienen la misma forma bsica, pues solo se diferencian entre ellas por el valor de sus constantes. La notacin O (tambin llamada O mayscula), se utiliza para comparar la eficiencia de los algoritmos. La notacin O se centra en el trmino dominante an2 (es decir, en aquel que ms crece cuando n aumenta; tal y como se observa en la Tabla2), e ignora el resto de trminos. Por lo tanto, desprecia tambin la constante de proporcionalidad a. As:
O(an2 + bn + c) = O(an2) = O(n2)
f(n)=an2+bn+c
donde a = 0,0001724, b = 0,00400, c = 0,1
f(n)
an2
Propiedades Notacin O
O( f(x) ) + k O( k f(x) ) O( f(x) ) * O( g(x) ) O( f(x) ) + O( g(x) ) g(x) ) ) = = = = O( f(x) ) O( f(x) ) O( f(x) * g(x) ) max ( O( f(x) ), O(
Complejidad de un Algoritmo
A continuacin se muestra un ejemplo de clculo de subsecuencia de suma mxima resuelto de tres formas diferentes y cmo influye su resolucin en la complejidad del algoritmo. Dada la secuencia de enteros (posiblemente negativos) A1, A2, ..., An, encontrar (e identificar la subsecuencia correspondiente) el valor mximo de j k=i Ak. Cuando todos los enteros son negativos entenderemos que la subsecuencia de suma mxima es la vaca, siendo su suma cero.
Por ejemplo para la entrada {-2, 11, -4, 13, -5, 2}, la respuesta es 20. Y para {-2, 11, 1}, la respuesta es 12. Se marca en negrita la subsecuencia de suma mxima
O(n3)
O (n3)
O(n2) O(n)
O (n2)
O(n)
return sumaMax; }
O (n)
Complejidad logartmica
En la complejidad logartmica no se tiene en cuenta la base, porque un cambio entre bases slo implica multiplicar por una constante. Log10n = log2n / log210 1/log210 = 0.301 Log10n = 0.301 * log2n
Complejidad Logartmica
Es adecuado implementar algoritmos con una complejidad logartmica, porque los logaritmos crecen muy lentamente aunque el nmero de datos aumente considerablemente. Se define formalmente un logaritmo para cualquier b, n > 0, como: Los logaritmos crecen lentamente. Ej. Un logaritmo de un milln es aproximadamente 20, y el algoritmo de un billn es aproximadamente 40.
Logbn = k si bk=n
Logb n = k si bk=n
Logb n = k si bk=n
Valor de X
21
22
23
2p
El nmero de veces que se duplica es p. 2p = N, es decir p = log2 N. Por lo tanto se duplica un nmero logartmico de veces.
Logb n = k si bk=n
N/2
N/4
N/8
N/N
N de datos
N/21
N/22
N/23
N/2p
El nmero de veces que se divide es p. 2p = N, es decir p = log2 N. Por lo tanto se divide N hasta llegar a 1 un nmero logartmico de veces.
O(n)
O(n)
Bsqueda Interna
El problema de la bsqueda es un problema de recuperacin de la informacin lo ms rpidamente posible y consiste en localizar un elemento en una lista o secuencia de elementos. La operacin de bsqueda puede llevarse a cabo sobre elementos ordenados o sobre elementos desordenados. Bsqueda interna si todos los elementos se encuentran en memoria principal (por ejemplo, almacenados en arrays, vectores o listas enlazadas) Bsqueda externa si los elementos se encuentran en memoria secundaria.
Bsqueda Interna
Definicin en Java de un array.
//declaracin de un array de tipo_elemento tipo_elemento [] array; //reserva de espacio para almacenar los datos en el array array = new tipo_elemento[n];
Cada algoritmo de bsqueda trata de localizar en un array un elemento X. Una vez finalizada la bsqueda puede suceder:
que la bsqueda haya tenido xito, habiendo localizado la posicin donde estaba almacenado el elemento X, o que la bsqueda no haya tenido xito, concluyndose que no exista ningn elemento X.
Bsqueda Lineal
Es la forma ms simple de buscar un elemento y consiste en examinar secuencialmente uno a uno hasta encontrar el buscado o haber revisado todos los elementos sin xito.
public static int busquedaLineal(int X, int [] A) { int i = 0; int n = A.length -1; while (i < n && A[i] != X) i++; /* Si se encuentra el elemento se devuelve su posicin sino se devuelve -1 (indica que el elemento no est)*/ if (A[i] == X) return i; else return -1;
Bsqueda Binaria
Si los elementos sobre los que se realiza la bsqueda estn ordenados, entonces podemos utilizar un algoritmo de bsqueda mucho ms rpido que el secuencial, la bsqueda binaria. Consiste en reducir paulatinamente el mbito de bsqueda a la mitad de los elementos, basndose en comparar el elemento a buscar con el elemento que se encuentra en la mitad del intervalo y en base a esta comparacin:
Si el elemento buscado es menor que el elemento medio, entonces sabemos que el elemento est en la mitad inferior de la tabla. Si es mayor es porque el elemento est en la mitad superior. Si es igual se finaliza con xito la bsqueda ya que se ha encontrado el elemento.
return -1; }
Bsqueda Indexada
Necesita que los elementos sobre los que se realiza la bsqueda estn ordenados de acuerdo a una determinada clave. El mtodo utiliza un array auxiliar denominado array ndice. Cada objeto en el array ndice consta de un valor y la posicin que ocupa dicho valor en el correspondiente array ordenado: En Java se define como se muestra a continuacin: class ElemIndice{ private int clave; private int posicion; public ElemIndice(int c, int p){ clave=c; posicion=p;} public int getClave(){ return clave; } public int getPosicion(){ return posicion; }
Bsqueda Indexada
Mediante cada elemento del array ndice se asocian grupos de elementos del array inicial. Los elementos en el ndice y en el array deben estar ordenados. El mtodo consta de dos pasos:
1. 2.
La ventaja del mtodo estriba en que la bsqueda se realiza inicialmente en el array de ndices, cuantitativamente ms pequea que el array de elementos. Cuando se ha encontrado el intervalo correcto, se hace una segunda bsqueda en una parte reducida del array. Estas dos bsquedas pueden ser secuenciales o binarias y el tiempo de ejecucin depender del tipo de bsqueda utilizado en cada uno de los arrays
Buscar en el array_ndice el intervalo correspondiente al elemento buscado. Restringir la bsqueda a los elementos del intervalo que se localiz previamente.
Se decide dividir el array inicial en bloques de tres elementos. El array ndice estar formado por n/k + 1 elementos, por no ser el ltimo bloque de igual tamao, es decir, 11/3 +1= 4
Clave Posicin
3 0
6 3
9 6
16 9
Se puede implementar la bsqueda binaria en el array de ndices. Cuando finaliza la bsqueda, o ha encontrado el elemento buscado o est en la posicin que contiene al elemento mayor de los ms pequeos al elemento buscado Si X = 10, en el array de ndice indicar la posicin 2. Por lo tanto, la bsqueda en el array inicial comenzar en la posicin 6 hasta el final del bloque.
Clave Posicin
3 0
6 3
9 6
16 9
Ejercicio
Implementa los algoritmos de bsqueda indexada usando la bsqueda binaria tanto en el array de ndices como en el array inicial. public int Bus_Binaria_array_indice(Elem_indice [] array_indice, int X){ int inicio = 0; int fin = array_indice.length -1; int medio; while (inicio <= fin) { medio = (inicio+fin)/2; if (array_indice[medio].getClave() < X) inicio = medio+1; else if (array_indice[medio].getClave() > X) fin = medio -1; else return array_indice[medio].getPosicion();
//Busqueda Binaria array public int Bus_Binaria_array(int [] A, Elem_indice [] array_indice, int X, int k){ int i = Bus_Binaria_array_indice(array_indice, X); if (i != -1){ int f = i+k-1; if (f >= A.length) f=A.length-1; while (i <= f) { int medio = (i+f)/2; if (A[medio] < X) i = medio+1; else if (A[medio] > X) f = medio -1; else return medio; } // fin while }// fin if return -1; }
superposicin por desplazamiento donde todas las partes se suman entre s. superposicin por plegado se hace la inversa a las partes pares, X2, X4, ..., antes de sumarlas, con el fin de afinar ms.
Mtodo del medio del cuadrado: Se escogen el 4 y el 5 dgitos por la derecha par obtener la dir. Hash
K: 3205 K2:10272025 7148 51093904 2345 5499025
Por plegado:
H(3205) = 32+50 = 82 H(7148) = 71+84 = 55 H(2345) = 23+54 = 77
Rehasing o Reasignacin
Se trata de insertar o buscar un elemento cuya posicin ya est ocupada, en otra posicin disponible en la tabla. Esto se hace mediante la funcin de reasignacin R(H(X)), la cual acepta un ndice de la tabla y produce otro. Mtodos de reasignacin:
Prueba lineal Prueba cuadrtica Doble direccin hash
Rehasing, mejora
para cualquier funcin R(H(i))=(i+c) % m, donde m es el nmero de elementos de la tabla y c es una constante tal que c y m son primos relativos (es decir, no tienen factores en comn), genera valores sucesivos que cubren toda la tabla. Sin embargo, si m y c tienen factores en comn, el nmero de posiciones diferentes de la tabla que se obtienen ser el cociente de dividir m entre c. Basndonos en esta ltima afirmacin, el algoritmo de bsqueda (y el de carga) tienen un problema: utilizando una funcin de rehashing de este tipo podran salir sin insercin aun cuando exista alguna posicin vaca en la tabla
Ejemplo: Dada la funcin de reasignacin: RH(i) = ( i + 200 ) % 1000 posiciones posibles: (1000/200= 5)
Para evitar que la Prueba Lineal se convierta en una bsqueda Lineal: Se cumple que,
Con esta funcin, cada clave solo puede ser colocada en cinco
si i = 215, y esta posicin est ocupada, entonces se reasigna de la siguiente forma: RH(215)=(215+200) %1000 = 415 RH(415)=(415+200) %1000 = 615 RH(615)=(615+200) %1000 = 815 RH(815)=(815+200) %1000 = 15 RH(15)=( 15+200) %1000 = 215 RH(215)=(215+200) %1000 = 415 ........................... Si estas cinco posiciones posibles estn ocupadas, saldremos sin insercin aun cuando haya posiciones libres en la tabla.
Ejemplo de Agrupamiento
Clave 4618396 4957397 1286399 ndice 396 397 398 399 400 401 0000990 0000991 1200992 0047993 9846995 990 991 992 993 994 995
En este caso, es cinco veces ms probable que un registro sea insertado en la posicin 994 que en la posicin 401. Esto se debe a que cualquier registro cuya clave genera la asignacin 990, 991, 992, 993 o 994 ser colocado en la 994, mientras que cualquier registro cuya clave genera la asignacin 401 ser colocado en su posicin. Este fenmeno en el que dos claves que inicialmente generan una asignacin en dos sitios diferentes, luego compiten entre s en reasignaciones sucesivas, se denomina agrupamiento o clustering.
Agrupamiento o clustering
Agrupamiento o clustering: H(X) <> H(Y) y RH(X) = RH(Y) en reasignaciones sucesivas, se cumple que:
cualquier funcin de reasignacin que dependa nicamente del ndice dar lugar a agrupamiento. dara agrupamiento la funcin de reasignacin Rh(i) = ( i + c ) % m aunque c y m fuesen primos.
Problemas de Rehasing
INSERCIN: Como se asume una tabla de tamao fijo, si el nmero de elementos aumenta ms all de ese tamao es imposible insertarlo sin que sea necesario asignar una tabla ms grande y recalcular los valores de asignacin de las claves de todos los elementos que ya se encuentran en la tabla utilizando una nueva funcin de asignacin. BORRADO: Es difcil eliminar un elemento. Por ejemplo, si el elemento r1 est en la posicin p, para aadir un elemento r2 cuya clave k2 queda asignada en p, ste debe ser insertado en la primera posicin libre de las siguientes: Rh(p), Rh(Rh(p)).. Si luego r1 es eliminado y la posicin p queda vaca, una bsqueda posterior del elemento r2 comenzar en la posicin H(k2) =p. Como esta posicin est ahora vaca, el proceso de bsqueda puede errneamente llevarnos a la conclusin de que el elemento r2 no se encuentra en la tabla. Solucin: marcar el elemento eliminado como 'eliminado' en vez de 'vaco', y continuar la bsqueda cuando se encuentra una posicin como 'eliminada'.
Zona de desbordamiento
Se trata de mantener una zona reservada para aquellos elementos que llegan a colisionar, de manera que cuando se produzca una colisin el elemento se va a localizar en esta zona de desbordamiento. Al realizar la bsqueda y comprobar que la posicin est ocupada por otro elemento con el mismo valor de hashing, se seguir buscando a partir del inicio de la zona de desbordamiento de manera secuencial, hasta encontrar el elemento o llegar al final de dicha zona de desbordamiento.
Algoritmos de Ordenacin.
Ordenacin
La ordenacin de elementos segn un orden ascendente o descendente influye notablemente en la velocidad y simplicidad de los algoritmos que los manipulan posteriormente. En general, un conjunto de elementos se almacenan en forma ordenada con el fin de simplificar la recuperacin de informacin manualmente, o facilitar el acceso mecanizado a los datos de una manera ms eficiente. Los mtodos de ordenacin se suelen dividir en:
ordenamiento interno, si los elementos que han de ser ordenados estn en la Memoria Principal. ordenamiento externo, si los elementos que han de ser ordenados estn en un dispositivo de almacenamiento auxiliar.
Generalmente, la funcin de complejidad solo computa COMPARACIONES porque el nmero de las otras operaciones es como mucho constante del nmero de comparaciones.
COMPARACIONES que prueban si Ai < Aj Ai < B (donde B es una variable auxiliar) INTERCAMBIOS: permutar los contenidos de Ai y Aj Ai y B ASIGNACIONES de la forma B Ai, Aj B Aj Ai
Suponemos el primer elemento ordenado. Desde el segundo hasta el ltimo elemento, hacer:
1. 2. 3. 4.
suponer ordenados los (i 1) primeros elementos tomar el elemento i buscar su posicin correcta insertar dicho elemento, obteniendo i elementos ordenados
1 2 3
0 0 0
1 1 1
1 2 3
1 2 3
1 2 3
En general, para n elementos se realizan (n-1) intercambios y (n-1) comparaciones. Por tanto, O(n2).
Insercin Binaria.
public void OrdInsercionBin() { for (int i=1; i < A.length; i++) { int elem = A[i]; int bajo = 0; int alto = (i-1); while (bajo <= alto)//Se busca la posicin donde se debe almacenar el elemento a ordenar { int medio = (alto + bajo)/2; if (elem < A[medio]) alto = medio -1; else bajo = medio + 1; } for (int j = (i-1); j >= bajo; j--)//Se desplazan todos los elementos mayores que el elemento a ordenar una posicion a la derecha A[j+1] = A[j]; A[bajo] = elem; }
Si tenemos en cuenta que tras una pasada puede suceder que ya estn todos los elementos ordenados, en este caso no sera necesario seguir realizando comparaciones.
Ordenacin Shell
Es una mejora de la ordenacin por insercin (colocar cada elemento en su posicin correcta, moviendo todos los elementos mayores que l, una posicin a la derecha), que se utiliza cuando el nmero de datos a ordenar es grande. Para ordenar una secuencia de elementos se procede as: se selecciona una distancia inicial y se ordenan todos los elementos de acuerdo a esa distancia, es decir, cada elemento separado de otro a distancia estar ordenado con respecto a l. Se disminuye esa distancia progresivamente, hasta que se tenga distancia 1 y todos los elementos estn ordenados.
21 32 21 32
40 6 40 6 18 40 18 26 40 26 32 40
Distancia 4 4 Distancia 2 4
Ordenacin Distancia 1 4 por Inserccin
21 32 6 6 17 21 18 6 17 18 18
Final
14 17
Complejidad de Shell
No es fcil de calcular. O(n3/2). Si se divide la distancia por 2.2 optiene una complejidad de O(n5/4). El tiempo de ejecucin depende de la secuencia de incrementos que se elige. El rendimiento de la ordenacin Shell es bastante aceptable en la prctica, an para n grande. Su simplicidad lo hace adecuado para clasificar entradas moderadamente grandes.
Cdigo MergeSort
public void mergeSort (int [] A, int bajo, int alto){ if (bajo < alto) //Si hay ms de un elemento { int medio = (alto + bajo)/2; mergeSort (A, bajo, medio); mergeSort (A, medio+1, alto); //Procedimiento que mezcla el resultado de las dos llamadas anteriores merge (A, bajo, medio+1, alto); } }
Complejidad MergeSort
El anlisis de eficiencia de la ordenacin por mezcla da lugar a una ecuacin recurrente para el tiempo de ejecucin. Suponemos n potencia de 2, n = 2K Para N = 1, Tiempo constante. Para N > 1, El tiempo de ordenacin para n nmeros es igual al tiempo para 2 ordenaciones recursivas de tamao n/2 + el tiempo para mezclar (que es lineal). Por tanto, T(n) = 2 T(n/2) + n
Tiempo de Mezclar Tiempo de Ordenacin Log2 n = k
Complejidad MergeSort
Para resolver la ecuacin se divide por n. T(n) / n = (2 (T (n/2)) / n) + (n/n) T(n) / n = T(n/2) / (n/2) + 1 Esta ecuacin es vlida para cualquier potencia de 2, as que se puede escribir: T(n/2) / (n/2) = (T(n/4) / (n/4)) + 1 T(n/4) / (n/4) = (T(n/8) / (n/8)) + 1 As sucesivamente, hasta T(2) = (T(1) / 1) + 1
Complejidad MergeSort
Se suman todas las ecuaciones anteriores, como todos los trminos se anulan, se obtiene el siguiente resultado:
T(n) / n = (T(1) / 1) + k, siendo K el nmero de ecuaciones que tenemos, es decir, el nmero de divisiones a la mitad que realizamos, por tanto k = log2n Para resolver la ecuacin se dividi entre n, por tanto ahora multiplicamos por n. T(n) = n + n log n. Por tanto la complejidad del algoritmo MergeSort es de O (n log n)
Ordenacin QuickSort.
La eleccin del elemento Pivote se puede seleccionar de diferentes formas:
El mayor de los dos primeros elementos distintos encontrados. El primer elemento. El ltimo elemento. El elemento medio. Un elemento aleatorio. Mediana de tres elementos (El primer elemento, el elemento del medio y el ltimo elemento).
Si desde Ai a Aj hay al menos dos elementos distintos entonces comenzar la aplicacin del algoritmo. Seleccionar el PIVOTE como el elemento mayor de los dos primeros elementos distintos encontrados. Insertar PIVOTE en la ltima posicin. Permutar los elementos desde Ai hasta Aj de modo que, para algn i <= k <= j :
Ai, ..., Ak-1 < PIVOTE Ak, ..., Aj >= PIVOTE Es decir, en las (k-1) primeras posiciones queden los elementos menores que pivote, mientras que en la posicin k hacia delante queden los elementos mayores o iguales que el pivote.
5.
Invocar a:
D hacia la derecha sobre cualquier elemento MENOR que el pivote y I hacia la izquierda sobre cualquier elemento MAYOR o IGUAL que el pivote.
Cdigo, paso 4.
int particion (int i, int j, int pivote) { int derecha = i; int izquierda = j-1; while (derecha <= izquierda) { intercambiar(derecha,izquierda); while (A[derecha] < pivote) derecha++; while (A[izquierda] >= pivote) izquierda--; } return derecha; }
Cdigo QuickSort
void quickSort (int [] A, int i, int j) { int indicePivote = buscaPivote(i, j); if (indicePivote != -1) { int pivote = A[indicePivote]; intercambiar(indicePivote,j); int k = particion(i,j,pivote); quickSort(A, i, k-1); quickSort(A, k,j); } }
Complejidad QuickSort.
Caso Mejor: Cuando el pivote, divide al conjunto en dos subconjuntos de igual tamao. En este caso hay dos llamadas con un tamao de la mitad de los elementos, y una sobrecarga adicional lineal, igual que en MergeSort. En consecuencia el tiempo de ejecucin es O(n log n).
Complejidad QuickSort.
Caso Peor: Se podra esperar que los subconjuntos de tamao muy distinto proporcionen resultados malos. Supongamos que en cada paso de recursin slo hay un elemento menor a pivote. En tal caso el subconjunto I (elementos menores que pivote) ser uno y el subconjunto D (elementos mayores o igual a pivote) sern todos los elementos menos uno. El tiempo de ordenar 1 elemento es slo 1 unidad, pero cuando n > 1. T(N) = T(N-1) + N T(N-1) = T(N-2) + (N-1) T(N-2) = T(N-3) + (N-2) . T(2) = T(1) + 2 T(N) = T(1) + 2 + 3 + 4 + + N = N (N+1) /2 , O(n2).
Complejidad QuickSort.
Caso Medio: Complejidad O(n log n).