Divide y vencerás. Diseño y Análisis de Algoritmos

Documentos relacionados
Tema 9. Recursividad

Esquema de Dividir y Vencer

Estructuras de Datos y Algoritmos. Curso 2009/2010. Tema 3: Divide y Vencerás

1. Planteamiento general

Estructura de datos y de la información Boletín de problemas - Tema 9

Introducción Supongamos un subconjunto de n elementos X = {e 1,,e n de un conjunto referencial Y, X Y. Dentro de Y se define una relación de orden tot

Tema 3.2: Eficiencia de algoritmos recursivos. Diseño y Análisis de Algoritmos

Análisis de algoritmos

Universidad de Valladolid. Departamento de informática. Campus de Segovia. Estructura de datos Tema 4: Ordenación. Prof. Montserrat Serrano Montero

Divide-y-vencerás, backtracking y programación dinámica

Análisis y Diseño de Algoritmos (AyDA) Isabel Besembel Carrera

Tema 2. Divide y vencerás.

Programa de teoría. Algoritmos y Estructuras de Datos II. 2. Divide y vencerás. 1. Análisis de algoritmos

<tipo> Tipo de dato de los elementos del vector

Tema 5- Diseño Recursivo y Eficiente. Tema 5- Diseño Recursivo y. Descomposición recursiva ascendente de un vector. Etapas del diseño recursivo

Multiplicación de matrices simétricas

Solución - práctico 10

Al considerar varios polígonos regulares inscritos resulta: perímetro del cuadrado < π. perímetro del 96 gono < π

Algoritmos Iterativos de Búsqueda y Ordenación y sus tiempos

Resolución numérica de ecuaciones no lineales

CONTENIDOS MÍNIMOS PRIMER CURSO. Bloque 2. Números. Números naturales.

Algorítmica y Complejidad. Tema 5 Divide y Vencerás.

Diseño y Análisis de Algoritmos

ANÁLISIS Y DISEÑO DE ALGORITMOS

Matemáticas números reales

Algoritmos y Estructuras de Datos Tema 2: Diseño de Algoritmos

Recursividad. 1.1 Concepto de Recursividad. Objetivos. Metodología de la Programación II Entender el concepto de recursividad.

Complejidad de algoritmos recursivos

Programación II. Mario Aldea Rivas Programación II 13/04/11 1. Mario Aldea Rivas Programación II 13/04/11 2

Últimas notas de SVD

TEMA 1.- POLINOMIOS Y FRACCIONES ALGEBRAICAS

001. Interpreta correctamente códigos (teléfonos, matrículas, NIF ).

Estructuras de Datos y de la Información Ingeniería Técnica en Informática de Gestión. Curso 2007/2008 Ejercicios del Tema 2

dit UPM Tema 2: Algoritmos /ordenación /java Análisis y diseño de software José A. Mañas

Problemas Ampliación de Matemáticas. Sistemas lineales 1.- Encontrar la factorización L U de las siguientes matrices:

Fundación Uno. (a) Con signos de agrupación y productos indicados (b) Con valor absoluto (c) Con literales

TEMA 1: DIVIDE Y VENCERÁS

Ecuaciones de primer grado

CURSO DE METODOS NUMERICOS Año Académico Curso Tercero de Matemáticas EXAMEN FINAL FEBRERO

Resolución de ecuaciones no lineales y Método de Bisección

Técnicas de diseño de algoritmos Divide y Vencerás

Relación de ejercicios 5

Decrementa y vencerás II

Divide y vencerás. Dr. Eduardo A. RODRÍGUEZ TELLO. 7 de marzo de CINVESTAV-Tamaulipas

TEMA 7. ALGORITMOS DE BÚSQUEDA, ORDENACIÓN

Tema 3 Álgebra Matemáticas I 1º Bachillerato. 1

1/16. Coste de Algoritmos. 8 de abril de 2018

Tema 3. Análisis de costes

Expresiones algebraicas

POLINOMIOS Y DIVISIÓN DE POLINOMIOS MATEMÁTICAS 3º ESO

Metodología de la Programación II. Recursividad

Métodos Numéricos. Grado en Ingeniería en Informática Tema 4. Análisis Numérico Matricial I

(a) (0.5 puntos) Compruebe que esta ecuación tiene exactamente una solución en el intervalo

FICHAS REPASO 3º ESO. Para restar números enteros, se suma al minuendo el opuesto del sustraendo y después se aplican las reglas de la suma.

Contenidos Mínimos de Taller de Matemáticas de Primer Curso. - Concepto y definición del número natural como cardinal de conjuntos coordinables.

Algoritmos Recursivos de Búsqueda y Ordenación y sus tiempos

Tema 5- Diseño Recursivo y. Objetivos Principales. Bibliografía Básica

2. Sistemas de ecuaciones lineales

ANÁLISIS Y DISEÑO DE ALGORITMOS. PRACTICAS

Programación II Práctica 03: Recursividad Versión del 10/08/2016

Ecuaciones No-Lineales y raices polinomiales

TEMA 4: Sistemas de ecuaciones lineales II

I.E.S. El Galeón Curso CONTENIDOS MÍNIMOS MATEMÁTICAS 1º E.S.O.

Unidad 2: Ecuaciones, inecuaciones y sistemas.

Recursividad. Dept. Ciencias de la Computación e I.A. Universidad de Granada

Instituto Tecnológico Autónomo de México. 1. At =..

Curso de Programación 1

Métodos de ordenamiento y búsqueda para datos en memoria principal

EJE N 3 : ECUACION LINEAL, CUADRATICA Y SISTEMA DE ECUACIONES

Preparación para Álgebra universitaria con trigonometría

Algoritmos de Ordenamiento

Tema 4.- Recursión e iteración

Tema 3. Polinomios y fracciones algebraicas

Criterios de evaluación. Tema 1. Matemáticas. 5º Primaria

Métodos de ordenamiento y búsqueda para datos en memoria principal

Álgebra Parte de las matemáticas que tiene que ver con el estudio y resolución de las ecuaciones.

Tema 4. Polinomios Operaciones

Geometría. Facultad de Ciencias Exactas y Naturales Universidad de Buenos Aires. Training Camp 2012

Parte de Algoritmos de la asignatura de Programación Master de Bioinformática. Divide y vencerás

1. Expresiones polinómicas con una indeterminada

Propuesta de distribución v1.12 (feb-17) - Curriculum ESPAÑA

3.1 Polinomios Polinomio: Expresión algebraica formada por la suma y/o resta de varios monomios.

Introducción al Análisis del Coste de Algoritmos

CONTENIDOS MINIMOS DE REFUERZO DE MATEMATICAS DE 2º DE ESO 1 Los números naturales

Tema 2 Resolución de EcuacionesNo Lineales

EXPRESIONES ALGEBRAICAS EXPRESIONES ALGEBRAICAS Y POLINOMIOS

La transformada rápida de Fourier (FFT) y otros algoritmos para la implementación de la DFT

PRUEBA EXTAORDINAORIA DE SEPTIEMBRE DE 2014 CONTENIDOS MÍNIMOS DE MATEMÁTICAS

Algorítmica y Lenguajes de Programación. Ordenación (ii) En la lección anterior se vieron dos métodos de ordenación:

Tema: Métodos de Ordenamiento. Parte 3.

Divide y Vencerás Programación Dinámica

Propuesta de distribución v1.20 (jun-17) - Curriculum ESPAÑA

CURSO CONTENIDOS MÍNIMOS U1: NÚMEROS NATURALES. U2: POTENCIA Y RAÍCES.

FFT : Fast Fourier Transform

CEPA Rosalía de Castro. Fundamentos de Matemáticas Tema 4: Expresiones algebraicas

3. DISEÑO DE ALGORITMOS PARALELOS Y DISTRIBUIDOS

Análisis Numérico: Soluciones de ecuaciones en una variable

Descomposición factorial. Suma o diferencia de cubos perfectos. P r o c e d i m i e n t o

Transcripción:

Diseño y Análisis de Algoritmos

Contenidos Contenidos 1 Introducción 2 Transforma y vencerás 3 Decrementa y vencerás 4 URJC DAA 2 / 54

Introducción Introducción URJC DAA 3 / 54

Introducción Uno de los más importantes paradigmas de diseño algorítmico Se basa en la resolución de un problema dividiéndolo en dos o más subproblemas de igual tipo o similar El proceso continúa hasta que éstos llegan a ser lo suficientemente sencillos como para que se resuelvan directamente Al final, las soluciones a cada uno de los subproblemas se combinan para dar una solución al problema original Muchos algoritmos basados en esta estrategia son recursivos También hay algoritmos iterativos de divide y vencerás URJC DAA 4 / 54

Introducción Simplificación y descomposición de problemas Las palabras clave en este tema van a ser la simplificación y la descomposición de problemas Veremos tres estrategias para simplificar y descomponer problemas: Transforma y vencerás Decrementa y vencerás URJC DAA 5 / 54

Transforma y vencerás Transforma y vencerás URJC DAA 6 / 54

Transforma y vencerás Transforma y vencerás Esta estrategia también se denomina reducción Esta técnica procura resolver un problema transformándolo en otro más simple, conocido, o para el que existan algoritmos eficientes transformación Problema A Problema B resolución difícil o ineficiente solución A paso sencillo solución B resolución sencilla o eficiente URJC DAA 7 / 54

Transforma y vencerás Encontrar la mediana de un array desordenado Sea un array v de n números 1 Ordenar el array v Θ(n log n) 2 Devolver v[(n + 1)/2] si n es impar v[n/2] + v[1 + n/2] si n es par 2 4 2 5 5 6 1 0 3 4 5 8 7 ordenar 0 1 2 3 4 4 5 5 5 6 7 8 4.5 URJC DAA 8 / 54

Transforma y vencerás Estimación del valor de π Planteamos un problema alternativo Buscamos una aproximación del perímetro p de un círculo de radio R p = 2πR π = p 2R Aproximamos un círculo con un poĺıgono regular inscrito o circunscrito al círculo El perímetro del poĺıgono inscrito p i nos dará una cota inferior de p El perímetro del poĺıgono circunscrito p c nos dará una cota superior de p p i 2R π p c 2R URJC DAA 9 / 54

Transforma y vencerás Estimación del valor de π Comenzamos por un poĺıgono regular inscrito (por ejemplo, un hexágono), cuyo perímetro será 6R A continuación, doblamos el número de lados, obteniendo una mejor aproximación Hexágono regular Dodecágono regular El perímetro de un poĺıgono con el doble de lados se puede obtener fácilmente a partir del primero Los perímetros de los poĺıgonos circunscritos se pueden obtener de los perímetros de los poĺıgonos inscritos URJC DAA 10 / 54

Transforma y vencerás Estimación del valor de π L' l L/2 R x y URJC DAA 11 / 54

Transforma y vencerás Estimación del valor de π Si el lado de un poĺıgono inscrito mide L, se puede hallar la longitud un lado del poĺıgono l con el doble de lados R 2 = y 2 + ( L ) 2 y = R 2 2 ( L ) 2 x = R y = R R 2 2 ( L ) 2 2 ( L ) 2 l = + R 2 2 + R 2 ( L ) 2 2R R 2 2 ( L ) 2 = R 2 4 ( L ) 2 2 R El lado L de un poĺıgono circunscrito se puede hallar a partir del lado L de un poĺıgono inscrito L R = L L = LR y y la estimación de π se obtiene a partir de los perímetros hallados: L número de lados 2R π L número de lados 2R URJC DAA 12 / 54

Transforma y vencerás Otros métodos para estimar del valor de π Simulación Monte Carlo Integración numérica Series arctan x = x x 3 3 + x 5 5 x 7 7 +... para x = 1 π 4 = 1 1 3 + 1 5 1 7 +... URJC DAA 13 / 54

Transforma y vencerás Raíz cuadrada Deseamos hallar a Transformamos el problema en el de hallar un cero de una función x = a x 2 = a x 2 a = 0 Por tanto, querremos hallar un cero de la función y = x 2 a Como x será generalmente un número real, nos podemos conformar con una aproximación Hay varios métodos para resolver este nuevo problema, por ejemplo: Método de Newton-Raphson (que veremos a continuación) Método de bipartición (de decrementa y vencerás ) URJC DAA 14 / 54

Transforma y vencerás Método de Newton-Raphson Se trata de un método iterativo, que parte de un valor inicial x 0, y aplica la siguiente regla para hallar un cero de la función f (x): x n+1 = x n f (xn) f (x n) En cada iteración se busca la recta tangente a f (x) que pasa por el punto (x n, f (x n)) El corte de la recta con el eje de abscisas constituye el nuevo punto x n+1 URJC DAA 15 / 54

Transforma y vencerás Método de Newton-Raphson El método surge del desarrollo de f (x) en serie de Taylor, para un entorno del punto x n : f (x) = f (x n ) + f (x n )(x x n ) + (x x n ) 2 f (x n ) 2! +... Si se trunca el desarrollo a partir del término de grado 2, se obtiene la recta tangente (que pasa por el punto (x n, f (x n ))) Posteriormente evaluamos en x n+1 : f (x n+1 ) = f (x n ) + f (x n )(x n+1 x n ) Si asumimos que x n+1 tiende hacia el cero de la función, podemos sustituir f (x n+1 ) = 0, obteniéndose el algoritmo URJC DAA 16 / 54

Transforma y vencerás Raíz cuadrada - método de Newton-Raphson Debemos aplicar la regla para f (x) = x 2 a, con f (x) = 2x x n+1 = x n x 2 n a 2x n = 2x 2 n 2x n x 2 n a 2x n = x 2 n + a 2x n 25 20 f(x) =x 2 13 15 10 5 0 x n x n+1 5 10 15 20 25 1 0 1 2 3 4 5 6 URJC DAA 17 / 54

Transforma y vencerás Factorización LU Supongamos que queremos resolver un sistema de ecuaciones Ax = b repetidas veces, para muchos valores diferentes de b, pero para la misma matriz A Para acelerar el cálculo se puede realizar una factorización LU Sea A una matriz cuadrada en invertible, buscamos una factorización A = LU, donde L es triangular inferior, y U triangular superior (del mismo tamaño). Para una matrix de 3 3 tendríamos: a 11 a 12 a 13 l 11 0 0 u 11 u 12 u 13 a 21 a 22 a 23 = l 21 l 22 0 0 u 22 u 23 a 31 a 32 a 33 l 31 l 32 l 33 0 0 u 33 Para resolver el sistema Ax = b ahora se van a resolver dos, pero más sencillos: Ax = LUx = b Ly = b, Ux = y Una descomposición es útil cuando hay que hacer repetidas operaciones con la matriz A URJC DAA 18 / 54

Decrementa y vencerás Decrementa y vencerás URJC DAA 19 / 54

Decrementa y vencerás Decrementa y vencerás La descomposición de un problema genera un solo subproblema La solución al subproblema puede ser la solución al problema original Para otros problemas se requiere realizar alguna operación adicional con la solución al subproblema decrementa Problema Subproblema operación sencilla solución URJC DAA 20 / 54

Decrementa y vencerás Búsqueda binaria en un array ordenado Se compara el elemento central con el elemento a buscar Si no se encuentra se busca en alguna de las dos mitades T (n) = { a si n = 1 b + T (n/2) si n 2 Θ(log n) URJC DAA 21 / 54

Decrementa y vencerás Método de bipartición Método para hallar un cero de una función f continua en un intervalo [a, b] Los signos de f (a) y f (b) son distintos Se busca un cero en la mitad del intervalo c = (a + b)/2 Si no se encuentra se busca en [a, c] o [c, b] Se repite el proceso hasta una determinada precisión ε (hasta que el ancho del intervalo sea menor que 2ε) URJC DAA 22 / 54

Decrementa y vencerás Ordenación por selección 1 Encontrar el menor elemento de una lista 2 Intercambiarlo con el primero de la lista 3 Aplicar el algoritmo de nuevo al resto de la lista (toda la lista salvo el primer elemento) problema (tamaño n) problema (tamaño n-1) Observad que se ha omitido a propósito mostrar más niveles para ilustrar 2, 3, 4... elementos ordenados Sólo se muestra la descomposición necesaria para realizar el diseño URJC DAA 23 / 54

Decrementa y vencerás Algoritmo de Euclides La reducción del tamaño del problema no siempre es tan obvia El algoritmo de Euclides encuentra el máximo común divisor de dos números naturales Hay dos versiones n si m = 0 mcd1(m, n) = mcd1(n, m) si m > n mcd1(m, n m) si (m n) y (m 0) mcd2(m, n) = { n si m = 0 mcd2(n %m, m) si m 0 En cada paso nos vamos acercando al caso base URJC DAA 24 / 54

Decrementa y vencerás Algoritmo de Euclides - Demostración mcd1 n si m = 0 mcd1(m, n) = mcd1(n, m) si m > n mcd1(m, n m) si (m n) y (m 0) Supongamos que m n (en caso contrario el propio algoritmo intercambia los parámetros) m = az, n = bz, con a b z son los factores primos (máximo común múltiplo) a y b no comparten factores primos Hacemos b = a + c n = bz = (a + c)z = (a 1 a k + c 1 c l )z No se puede sacar factor común. Si se pudiera sería otro factor de z. a, c no comparten primos Por tanto, dado que z = mcd1(az, bz) = mcd1(az, cz), y c = b a tenemos: mcd1(m, n) = mcd1(az, bz) = mcd1(az, cz) = mcd1(m, n m) URJC DAA 25 / 54

Decrementa y vencerás Algoritmo de Euclides - Demostración mcd2 mcd2(m, n) = { n si m = 0 mcd2(n %m, m) si m 0 Supongamos que m n (en caso contrario el propio algoritmo intercambia los parámetros) m = az, n = bz, con a b z son los factores primos a y b no comparten factores primos Hacemos b = ac + d, donde c y d son el cociente y el resto de b/a a y d no pueden compartir factores, de lo contrario serían también factores de b Por tanto: z = mcd2(az, bz) = mcd2(dz, az) mcd2(m, n) = mcd2(n %m, m) URJC DAA 26 / 54

Decrementa y vencerás Potencia en tiempo Θ(log n) 5 13 = 5 1101 2 = 1 5 8 + 1 5 4 + 0 5 2 + 1 5 1 Algoritmo iterativo: aux e e %2 suma 5 1 13 1 5 1 5 2 6 0 0 + 5 1 5 4 3 1 5 4 + 0 + 5 1 5 8 1 1 5 8 + 5 4 + 0 + 5 1 Algoritmo recursivo (se calculan potencias de la mitad de tamaño, y luego se combina su resultado): b 0 = 1 b e = b e/2 b e/2 para e par b e = b b (e 1)/2 b (e 1)/2 para e impar Sin embargo, como los subproblemas son idénticos, sólo se calculan una vez, obteniéndose un algoritmo eficiente URJC DAA 27 / 54

URJC DAA 28 / 54

La descomposición de un problema genera varios subproblemas Las soluciones a los subproblemas se combinan para generar la solución al problema original, la cual puede requerir alguna operación adicional divide Subproblema combina Problema Subproblema solución Subproblema URJC DAA 29 / 54

Máximo de un vector de números Caso base Si el vector tiene tamaño 1 se devuelve el elemento Descomposición m 1 = máximo de la primera mitad del vector m 2 = máximo de la segunda mitad del vector Combinación max(v) = n = v.length máximo = máx{m 1, m 2 } { v[1] si n = 1 máx(max(v[1 : n/2]), max(v[n/2 + 1 : n])) si n > 1 URJC DAA 30 / 54

Máximo de un vector de números Conseguimos un algoritmo más eficiente que una búsqueda lineal? No. Sea cual sea nuestra estrategia tenemos que mirar todos los elementos del vector Este problema tiene una cota inferior Ω(n) T (n) = { 1 si n = 1 1 + 2T (n/2) si n > 1 A pesar de dividir el problema por dos, pero tenemos que resolver dos problemas El árbol de recursión tiene del orden de 2 h nodos, donde h es la altura del árbol Pero en este problema h = log 2 n, y el número de nodos es n T (n) Θ(n) URJC DAA 31 / 54

Máximo de un vector de números 1 public static int max2 (int[] v) { 2 return maxdyv (v, 0, v.length-1); 3 } 4 private static int max (int m, int n) { 5 return (m>n?m:n); 6 } 7 public static int maxdyv (int[] v, int inf, int sup) { 8 if (inf==sup) 9 return v[inf]; 10 else { 11 int medio = (inf+sup)/2; 12 return max (maxdyv (v, inf, medio), 13 maxdyv (v, medio+1, sup)); 14 } 15 } URJC DAA 32 / 54

Merge-sort Sea un vector de tamaño n Algoritmo de ordenación en tiempo Θ(n log n) En todos los casos: mejor, peor, y medio Memoria auxiliar Θ(n) en todos los casos: mejor, peor, y medio Se denominan: out-of-place : se requiere un vector auxiliar de tamaño n. Es decir, la ordenación no se realiza en el propio vector URJC DAA 33 / 54

Merge-sort Caso base Si el vector tiene tamaño 1 se devuelve el elemento Descomposición Se divide el vector en dos, generalmente por la mitad, y se ordenan las dos partes por separado Combinación Se mezclan las dos mitades ordenadas { 1 si n = 1 T (n) = n + 2T (n/2) si n > 1 Cuál es el tiempo si no se divide el vector por la mitad, sino según un 10 % y 90 %? También Θ(n log n) URJC DAA 34 / 54

Merge-sort Paso a paso 38 27 43 3 9 82 10 38 27 43 3 9 82 10 38 27 43 3 9 82 10 Parte izquierda 38 27 43 3 9 82 10 Parte derecha 27 38 3 43 9 82 10 3 27 38 43 9 10 82 Vector ordenado 3 9 10 27 38 43 82 URJC DAA 35 / 54

Merge-sort Para diseñar el código, es mejor pensar en este esquema 38 27 43 3 9 82 10 Descomponer el problema 38 27 43 3 9 82 10 3 27 38 43 9 10 82 Ordenar subproblemas 3 9 10 27 38 43 82 Combiar soluciones URJC DAA 36 / 54

Implementación del Merge-sort I 1 void mergesort1 (int[] v) { 2 ordenarpormezcla1 (v, 0, v.length-1); 3 } 4 5 void ordenarpormezcla1 (int[] v, int inf, int sup) { 6 if (inf<sup) { 7 int medio = (inf+sup)/2; 8 ordenarpormezcla1 (v, inf, medio); 9 ordenarpormezcla1 (v, medio+1, sup); 10 mezclar1 (v, inf, medio, sup); 11 } 12 } URJC DAA 37 / 54

Implementación del Merge-sort I Mezcla ineficiente (puede ocasionar errores en tiempo de ejecución) 1 void mezclar1 (int[] v, int inf, int medio, int sup) { 2 //vector auxiliar de longitud n (lento) 3 int[] vaux = new int[v.length]; 4... Mezcla eficiente 1 void mezclar1_mejor (int[] v, int inf, int medio, int sup) { 2 //vector auxiliar de longitud exacta 3 int[] vaux = new int[sup-inf+1]; 4... URJC DAA 38 / 54

Implementación alternativa del Merge-sort II El parámetro auxiliar debe pasarse por referencia 1 void mergesort2 (int[] v) { 2 //vector auxiliar de longitud n, se propaga 3 int[] vaux = new int[v.length]; 4 5 ordenarpormezcla2 (v, 0, v.length-1, vaux); 6 } 7 8 void ordenarpormezcla2 (int[] v, int inf, int sup, int[] vaux) { 9 if (inf<sup) { 10 int medio = (inf+sup)/2; 11 ordenarpormezcla2 (v, inf, medio, vaux); 12 ordenarpormezcla2 (v, medio+1, sup, vaux); 13 mezclar2 (v, inf, medio, sup, vaux); 14 } 15 } 1 void mezclar2 (int[] v, int inf, int medio, int sup, int [] vaux) { 2... URJC DAA 39 / 54

Quick-sort Caso base Si el vector tiene tamaño 1 se devuelve el elemento Descomposición Se escoge un elemento pivote Se divide el vector en tres partes: Parte izquierda: elementos menores o iguales que el pivote El propio pivote Parte derecha: elementos mayores que el pivote Posteriormente se ordenan las partes izquierda y derecha Combinación Trivial: el vector ya está ordenado, no hay que hacer nada más URJC DAA 40 / 54

Quick-sort Esquema: 26 5 37 1 61 11 59 15 48 19 Descomponer el problema 11 5 19 1 15 26 59 61 48 37 Ordenar subproblemas 1 5 11 15 19 26 37 48 59 61 trivial Combiar soluciones 1 5 11 15 19 26 37 48 59 61 URJC DAA 41 / 54

Quick-sort Caso mejor (el elemento pivote está en la mitad) T (n) = { 1 si n = 1 2T (n/2) + Θ(n) si n > 1 Θ(n log n) Caso peor (un subvector queda siempre vacío) T (n) = { 1 si n = 1 T (0) + T (n 1) + Θ(n) si n > 1 Θ(n 2 ) URJC DAA 42 / 54

Quick-sort Algoritmo de ordenación rápido en la práctica Caso peor: Θ(n 2 ) Caso mejor: Θ(n log n) Caso medio: Θ(n log n) Suele superar a otros algoritmos Θ(n log n) al utilizar mejor las jerarquías de memoria Memoria auxiliar O(n) Puede ser out-of-place o in-place (la ordenación no se realiza en el propio vector) URJC DAA 43 / 54

Implementación del Quick-sort 1 void quicksort (int[] v) { 2 ordenarrapido (v, 0, v.length-1); 3 } 4 5 void ordenarrapido (int[] v, int inf, int sup) { 6 if (inf<sup) { 7 int med = partir (v, inf, sup); 8 if (inf<med) ordenarrapido (v, inf, med-1); 9 if (med<sup) ordenarrapido (v, med+1, sup); 10 } 11 } URJC DAA 44 / 54

Implementación del Quick-sort 1 int partir (int[] v, int inf, int sup) { 2 int piv = v[inf]; 3 int izq = inf+1; 4 int dcha = sup; 5 int temp; 6 do { 7 for (; v[izq]<=piv && izq<sup ; izq++); 8 for (; v[dcha]>piv /*&&dcha>inf*/; dcha--); 9 if (izq<dcha) { 10 temp = v[izq]; 11 v[izq] = v[dcha]; 12 v[dcha] = temp; 13 } 14 } while (izq<dcha); 15 /* v[inf] <-> v[dcha] */ 16 temp = v[inf]; 17 v[inf] = v[dcha]; 18 v[dcha] = temp; 19 return dcha; 20 } URJC DAA 45 / 54

Implementación del Quick-sort, método partir piv intercambio 4 3 5 6 2 1 izq dcha piv intercambio 4 3 1 6 2 5 izq dcha piv intercambio 4 3 1 2 6 5 izq dcha 2 3 1 4 6 5 Hay otras implementaciones que no escogen el primer elemento como pivote URJC DAA 46 / 54

Traspuesta de una matriz Sea una matriz A de dimensiones n n, donde n es una potencia de 2 Se puede definir su traspuesta A T dividiendo la matriz en bloques: A = A 11 A 12 A 21 A 22 A T = A T 11 A T 21 A T 12 A T 22 URJC DAA 47 / 54

Implementación de la traspuesta de una matriz 1 void trasponer (int[][] m) { 2 trasponerdyv1 (m, 0, m.length-1, 0, m.length-1); 3 } 4 5 void trasponerdyv1 (int[][] m, 6 int finicio, int ffin, int cinicio, int cfin) { 7 // caso básico de 1x1 8 if (finicio<ffin) { 9 int fmedio = (finicio+ffin)/2; 10 int cmedio = (cinicio+cfin)/2; 11 trasponerdyv1 (m, finicio, fmedio, cinicio, cmedio); 12 trasponerdyv1 (m, finicio, fmedio, cmedio+1, cfin); 13 trasponerdyv1 (m, fmedio+1, ffin, cinicio, cmedio); 14 trasponerdyv1 (m, fmedio+1, ffin, cmedio+1, cfin); 15 intercambiar (m, fmedio+1, cinicio, finicio, cmedio+1, ffin-fmedio); 16 } 17 } URJC DAA 48 / 54

Implementación de la traspuesta de una matriz 1 void intercambiar (int[][] m,int finia, int cinia, 2 int finib, int cinib, int dimen) { 3 for (int i=0; i<=dimen-1; i++) 4 for (int j=0; j<=dimen-1; j++) { 5 int aux = m[finia+i][cinia+j]; 6 m[finia+i][cinia+j] = m[finib+i][cinib+j]; 7 m[finib+i][cinib+j] = aux; 8 } 9 } URJC DAA 49 / 54

Traspuesta de una matriz no cuadrada También puede implementarse cuando n no es una potencia de dos, o incluso cuando la matriz no es cuadrada Se pueden usar matrices de tamaño fijo: A B A T C T B T D T C D espacio no usado espacio no usado matriz original matriz nueva (copia auxiliar) Por supuesto, también se puede usar memoria dinámica URJC DAA 50 / 54

Multiplicación de matrices La división de una matriz en bloques tiene varias ventajas: Simplifica operaciones algebraicas Se puede aprovechar para construir algoritmos eficientes que hagan buen uso de la memoria caché Para realizar una multiplicación hay varias formas de dividir la matriz ( ) A1 A B = ( ( ) ) A1 B B 1 B 2 = 1 A 1 B 2 A 2 B 1 A 2 B 2 A 2 A B = ( ( ) B1 A 1 A 2 B 2 ) = ( ) A 1 B 1 + A 2 B 2 ( A11 A 12 A B = A 21 A 22 ) ( B11 B 12 B 21 B 22 ) ( A11B 11 + A 12B 21 A 11B 12 + A 12B 22 = A 21B 11 + A 22B 21 A 21B 12 + A 22B 22 ) URJC DAA 51 / 54

Multiplicación de matrices - complejidad Sea A una matriz de p q, y B una matriz de q r El producto C = AB requiere O(pqr) operaciones Considérese que las matrices son cuadradas de dimensión n n, y la siguiente descomposición: ( ) ( ) ( ) A11 A 12 B11 B 12 A11B 11 + A 12B 21 A 11B 12 + A 12B 22 A B = = A 21 A 22 B 21 B 22 A 21B 11 + A 22B 21 A 21B 12 + A 22B 22 T (n) = { 1 si n = 1 8T (n/2) + 4Θ(n 2 ) si n > 1 8 multiplicaciones (de matrices de n/2 n/2) 4 sumas (de matrices de n/2 n/2) Por el teorema maestro: T (n) = Θ(n log 2 8 ) = Θ(n 3 ) URJC DAA 52 / 54

Multiplicación de matrices - algoritmo de Strassen La operación básica más costosa es la multiplicación El algoritmo de Strassen consigue reducir el número de multiplicaciones Considérese la siguiente descomposición: ( ) ( ) ( ) A11 A 12 B11 B 12 C11 C = 12 A 21 A 22 B 21 B 22 C 21 C 22 M 1 = (A 11 + A 22 )(B 11 + B 22 ) M 2 = (A 21 + A 22 )B 11 M 3 = A 11 (B 12 B 22 ) M 4 = A 22 (B 21 B 11 ) M 5 = (A 11 + A 12 )B 22 M 6 = (A 21 A 11 )(B 11 + B 12 ) M 7 = (A 12 A 22 )(B 21 + B 22 ) C 11 = M 1 + M 4 M 5 + M 7 C 12 = M 3 + M 5 C 21 = M 2 + M 4 C 22 = M 1 M 2 + M 3 + M 6 URJC DAA 53 / 54

Multiplicación de matrices - algoritmo de Strassen Con esa factorización el algoritmo requiere 7 multiplicaciones 18 sumas T (n) = { 1 si n = 1 7T (n/2) + 18Θ(n 2 ) si n > 1 Por el teorema maestro: T (n) = Θ(n log 2 7 ) = Θ(n 2,807 ) Solo es más eficiente que una multiplicación ordinaria si el tamaño de las matrices es muy elevado Actualmente hay un algoritmos en O(n 2,376 ) (Coppersmith - Winograd) En la práctica la mejor estrategia para acelerar el producto de dos matrices consiste en aprovechar la estructura jerárquica de la memoria URJC DAA 54 / 54