8.  Ordenamiento.

Slides:



Advertisements
Presentaciones similares
How to Conjugate… SPANISH VERBS.
Advertisements

Control en cascada.
Ordenamiento, Heapsort y Colas de prioridad
1 Ordenamiento y estadísticas de orden Agustín J. González ELO 320: Estructura de Datos y Algoritmos.
7.  El TDA Diccionario.
Arboles B (búsqueda externa)
1 Ordenando. 2 Sorting Input Una secuencia de numeros a 1, a 2, a 3, …, a n Output Una permutación (reorden) a’ 1, a’ 2, a’ 3, …, a’ n de la input, tal.
ECOM-6030 PASOS PARA LA INSTALACIÓN DE EASYPHP Prof. Nelliud D. Torres © - Derechos Reservados.
¿Cuánto tiempo hace que…? You can ask when something happened in Spanish by using: ¿Cuándo + [preterit verb]…? ¿Cuándo llegaste a la clínica? When did.
Stamps to be traced. 2 and 3 ALC 21 Hoy es miércoles el 23 de octubre. match the columns writing out the words. 1.Fat 2.Handsome 3.Long 4.Old 5.Pretty.
1 Ordenación, Clasificación Introducción Algoritmos Complejidad.
Scientific Method- Steps followed by scientists to find the answer to a scientific problem. Método Científico- pasos seguidos por los científicos para.
EQUILIBRIUM OF A PARTICLE IN 2-D Today’s Objectives: Students will be able to : a) Draw a free body diagram (FBD), and, b) Apply equations of equilibrium.
Métodos para ejecutar la operación de reunión (join)
Árboles binarios. Algoritmos básicos
Ingeniería en Sistemas
Stored Procedures Firebird.
1. Desarrollo de Programas iterativos usando invariante
My Spanish 2 classes are 2nd and 3rd periods
Estructuras de Datos Recursividad.
Complejidad Programación II de febrero de 2009.
Telling Time in Spanish
Heapsort Idea: dos fases: 1. Construccion del heap 2. Output del heap
Heaps.
ANTE TODO Adverbs are words that describe how, when, and where actions take place. They can modify verbs, adjectives, and even other adverbs. In previous.
Searching data in Arrays
Base de Datos II Almacenamiento.
First Grade Dual High Frequency Words
El Imperfecto Español 2.
Árboles Binario de Búsqueda
More sentences that contain if…
Complete the following sentences using the word bank.
Warm-up Fill in the blank with the correct form of the verb “ser” for each subject (p. 35): 1. Yo _______________ de Savannah. 2. Mis amigas ________.
ÁRBOLES ESTRUCTURA DE DATOS II ING. CARLOS ALBERTO PULLAS.
Genentech A Discussion Winter 2018Joseph Milner, RSM54011.
¡Los últimos apuntes gramaticales!
Árboles Binarios de Búsqueda (ABB)
Quasimodo: Tienes que hacer parte D de la tarea..
Arboles M.C. José Andrés Vázquez FCC/BUAP
El subjuntivo en cláusulas adverbiales:
Curso de Programación Estructurada
Día número 139—español 1 El 30 de marzo
Fundamentos de Informática Especialidad de Electrónica –
TEMAS *Arboles Binarios *listas Abiertas y Cerradas - Inserción - Recorrido - Eliminación *Pilas - Concepto - Inserción - Recorrido -
Curso de Programación Estructurada
El subjuntivo en cláusulas adverbiales:
Telling Time in Spanish
Hace = For/Since.
Estructuras de Datos MC Beatriz Beltrán Martínez Primavera 2018
In Lección 2, you learned how to express preferences with gustar
How to Conjugate… SPANISH VERBS.
MC Beatriz Beltrán Martínez Verano 2018
Preparacion Hoy es jueves el 3 de diciembre
METODOS DE ORDENAMIENTO CHRISTIAN MICHAEL OBANDO GARCES JOAO ADRIAN BARIONUEVO.
APUNTES: EL FUTURO pág. 1/2
ZERO CONDITIONAL. What is zero conditional? Zero conditional is a structure used to talk about general truths, that is, things that always happen under.
Recursividad 1 Análisis de algoritmos. Matrushka La Matrushka es una artesanía tradicional rusa. Es una muñeca de madera que contiene otra muñeca más.
Nelson Baloian, José A. Pino
UNIT 1: The structure of matter: FQ3eso_U1_3: Electron configurations
METODOS DE ORDENAMIENTO
Quasimodo: How could you express the following information in Spanish (you know 2 ways right now): The test will be on Friday. El examen va a ser el viernes.
Para el fin de esta leccíon, se puede:
Arrays Programming COMP102 Prog. Fundamentals I: Arrays / Slide 2 Arrays l An array is a collection of data elements that are of the same type (e.g.,
Welcome to PowerPoint gdskcgdskfcbskjc. Designer helps you get your point across PowerPoint Designer suggests professional designs for your presentation,
Departamento de Ingeniería de Sistemas e Industrial
ALGORITMO DE ORDENAMIENTO POR BURBUJA. El método de la burbuja es uno de los mas simples, es tan fácil como comparar todos los elementos de una lista.
In Lección 2, you learned how to express preferences with gustar
Ordenación Por Inserción
UNIVERSIDAD AÚTONOMA DE SINALOA “Facultad de Informática Culiacán”
Las Preguntas (the questions) Tengo una pregunta… Sí, Juan habla mucho con el profesor en clase. No, Juan no habla mucho en clase. s vo s vo Forming.
Transcripción de la presentación:

8.  Ordenamiento

Problema Dado una lista de elementos {X1, X2, ..., XN}, se desea reordenarlos para que se cumpla Xi ≤ Xj para i < j Hasta ahora hemos visto 3 métodos: Selección: siempre O(n2) Inserción: mejor caso O(n) si estaba ordenado, peor caso O(n2) si esta ordenado inversamente Burbuja: similar a Inserción ¿Es posible hacerlo más rápido ?.

Cota inferior teórica Para ordenar tres datos A, B y C tenemos el siguiente árbol de decisión

Generalización Si tenemos n elementos hay n! formas de ordenamiento posibles Si partimos de un punto inicial basados en decisiones true-false debemos poder llegar a cada una de las n! hojas del árbol Un árbol binario completo de n! hojas tiene altura log(n!) Usando la aproximación de Stirling, se puede demostrar que log2 n! = n log2 n + O(n), por lo cual la cota inferior es de O(n log n).

Quicksort Inventado por C.A.R. Hoare a comienzos de los '60s, y sigue siendo el método más eficiente para uso general. Ejemplo clásico de la aplicación del principio de dividir para reinar. Su estructura es la siguiente: Primero se elige un elemento al azar, que se denomina el pivote. El arreglo a ordenar se reordena dejando a la izquierda a los elementos menores que el pivote, el pivote al medio, y a la derecha los elementos mayores que el pivote: Luego cada sub-arreglo se ordena recursivamente La recursividad se detiene en principio cuando hay 1 elemento o 0 pero es mejor detenerla con n=0 y aplicar otro algoritmo

Clase23: ordenamiento de arreglos J.Alvarez

Orden Mejor caso: siempre se escoge un pivote que parte el (sub-)arreglo en dos partes (casi) iguales. T(n) = 2T(n/2) + kn Peor caso: siempre se escoge un pivote que es el mayor o el menor del sub-arreglo. T(n) = T(n-1) + kn

Caso promedio El funcionamiento de Quicksort puede graficarse mediante un árbol de partición: El árbol de partición es un árbol de búsqueda binaria, y si el pivote es escogido al azar, la raíz de cada subárbol puede ser cualquiera de los elementos del conjunto en forma equiprobable. En consecuencia, los árboles de partición y los árboles de búsqueda binaria tienen exactamente la misma distribución. En el proceso de partición, cada elemento de los subárboles ha sido comparado contra la raíz (el pivote). Al terminar el proceso, cada elemento ha sido comparado contra todos sus ancestros. Si sumamos todas estas comparaciones, el resultado total es igual al largo de caminos internos. Usando todas estas correspondencias, tenemos que, usando los resultados ya conocidos para árboles, el número promedio de comparaciones que realiza Quicksort es de: 1.38 n log2 n + O(n) Por lo tanto, Quicksort es del mismo orden que la cota inferior (en el caso esperado).

Mejoras a Quicksort Quicksort puede ser optimizado de varias maneras, pero es desaconsejable hacer cosas que aumenten la cantidad de trabajo que se hace dentro del "loop" de partición, porque este es el lugar en donde se concentra el costo O(n log n). Quicksort con "mediana de 3" se extrae una muestra de 3 elementos, y entre ellos se escoge a la mediana de esa muestra como pivote. Si se toman el primer, el del medio y el último , el peor caso (arreglo ordenado) se transforma en mejor caso. Si la muestra se escoge al azar el análisis muestra que el costo esperado para ordenar n elementos es 1.19 n log2 n Esta se debe a que el pivote es ahora una mejor aproximación a la mediana. si en lugar de escoger una muestra de tamaño 3, lo hiciéramos con tamaños como 7, 9, etc., se lograría una mejor aproximación pero con rendimientos rápidamente decrecientes.

Uso de Ordenación por Inserción para ordenar sub-arreglos pequeños No es eficiente ordenar recursivamente sub-arreglos demasiado pequeños. En lugar de esto, se puede establecer un tamaño mínimo M, de modo que los sub-arreglos de tamaño menor que esto se ordenan por inserción en lugar de por Quicksort. Claramente debe haber un valor óptimo para M, porque si creciera indefinidamente se llegaría a un algoritmo cuadrático. Esto se puede analizar, y el óptimo es cercano a 10. Implementación Al detectarse un sub-arreglo de tamaño menor que M, se lo deja sin ordenar, retornando de inmediato de la recursividad. Al final se tiene un arreglo cuyos pivotes están en orden creciente, y encierran entre ellos a bloques de elementos desordenados, pero están en el grupo correcto. Para completar la ordenación, se hace una sola gran pasada de Ordenación por Inserción, la cual ahora no tiene costo O(n2), sino O(nM), porque ningún elemento esta a distancia mayor que M de su ubicación definitiva

Ordenar recursivamente sólo el sub-arreglo más pequeño Un problema potencial con Quicksort es la profundidad que puede llegar a tener el arreglo de recursividad. En el peor caso, ésta puede llegar a ser O(n). Para evitar esto, vemos primero cómo se puede programar Quicksort en forma no recursiva, usando un stack. El esquema del algoritmo sería el siguiente (en seudo-Java): void Quicksort(Object a[]) { Pila S = new Pila(); S.apilar(1,N); // límites iniciales del arreglo while(!S.estaVacia()) { (i,j) = S.desapilar(); // sacar límites if(j-i>0) { // al menos dos elementos para ordenar p = particionar(a,i,j); // pivote queda en a[p] S.apilar(i,p-1); S.apilar(p+1,j); }

Convertir la ultima llamada recursiva en un while Es posible que la pila llegue a tener profundidad O(n). Para evitarlo, colocar en la pila sólo los límites del sub-arreglo más pequeño, dejando el más grande para ordenarlo de inmediato, sin pasar por la pila: void Quicksort(Object a[]) { Pila S = new Pila(); S.apilar(1,N); // límites iniciales del arreglo while(!S.estaVacia()) { (i,j) = S.desapilar(); // sacar límites while(j-i>0) { // al menos dos elementos para ordenar p = particionar(a,i,j); // pivote queda en a[p] if(p-i>j-p) { // mitad izquierda es mayor S.apilar(p+1,j); j=p-1; } else { S.apilar(i,p-1); i=p+1; } Cada intervalo apilado es a lo más de la mitad del tamaño del arreglo, sea S(n) a la profundidad de la pila: S(n) <= 1 + S(n/2) lo cual tiene solución log2 n, de modo que la profundidad de la pila nunca es más que logarítmica.

Un algoritmo de selección basado en Quicksort Seleccionar el k-ésimo elemento de un arreglo. Idea : ejecutar Quicksort, pero ordenar la mitad en donde se encontraría el elemento buscado. Los elementos están en a[1],...,a[n] y k está entre 1 y n. Cuando el algoritmo termina, el k-ésimo elemento se encuentra en a[k]. Quickselect se llama inicialmente como Quickselect(a,k,1,N). void Quickselect(Object a[], int k, int i, int j) { if(j-i>0) { // aún quedan al menos 2 elementos p = particionar(a,i,j); if(p==k) // ¡bingo! return; if(k<p) // seguimos buscando a la izquierda Quickselect(a,k,i,p-1); else Quickselect(a,k,p+1,j); } El análisis de Quickselect es difícil, pero se puede demostrar que el costo esperado es O(n). Sin embargo, el peor caso es O(n2).

Heapsort Idea: dos fases: 1. Construccion del heap 2. Output del heap Para ordenar numeros ascendentemente: mayor valor => mayor prioridad (el mayor esta en la raiz) Heapsort es un procedimiento in-situ

Recordemos Heaps Heap con orden reverso: Para cada nodo x y cada sucesor y de x se cumple que m(x)  m(y), left-complete, significa que los niveles se llenan partiendo por la raíz y cada nivel de izquierda a derecha Implementación en arreglo, donde los nodos se guardan en orden (de izquierda a derecha).

Primera Fase: 1. Construccion del Heap in-situ: métido simple : insert n-veces Cost0: O(n log n).

Segunda Fase costo: O(n log n). Sacar n-veces el maximo (en la raíz), e intercambiarlo con ultimo elemento del heap, dejarlo caer. El Heap se reduced en un elemento y el mayor queda al final. Repetir este proceso hasta que haya solo un elemento en el heap (el menor) costo: O(n log n). Heap Heap Ordered elements Ordered elements

Optimización primera Fase Definición segmento de heap como un segmento de arreglo a[ i..k ] ( 1  i  k <=n ) donde se cumple:         para todo j de {i,...,k}     m(a[ j ])  m(a[ 2j ])     if 2j  k y   m(a[ j ])  m(a[ 2j+1])  if 2j+1  k Si a[i+1..n] es un segmento de heap podemos facilmente convertir a[i…n] en un segmento de heap tambien „hundiendo“ a[ i ].

Optimización primera Fase Definición segmento de heap como un segmento de arreglo a[ i..k ] ( 1  i  k <=n ) donde se cumple:         para todo j de {i,...,k}     m(a[ j ])  m(a[ 2j ])     if 2j  k y   m(a[ j ])  m(a[ 2j+1])  if 2j+1  k Si a[i+1..n] es un segmento de heap podemos facilmente convertir a[i…n] en un segmento de heap tambien „hundiendo“ a[ i ].

Optimización primera Fase Se puede considerar cualquier arreglo a[1 … n ] como un segmento de heap desde a[n div 2] hasta a[n]. Los elementos de la mitad izquierda aun no ordenados se dejan “caer” en la secuencia: a[n div 2] … a[2] a[1] (los elementos … a[n div 2 +1] están ya en las hojas HH The leafs of the heap

Cost calculation k = [log n+1] es la altura del heap que se está construyendo en la fase 1 Para un elemento en el nivel j, suponiendo que los niveles j+1 hasta k estan construidos, el costo máximo de incluirlo en el segmento será: k – j. Además en cada nivel j hay 2j elementos En suma: {j=0,…,k} (k-j)•2j = 2k • {i=0,…,k} i/2i =2 • 2k = O(n).

Ventajas: Este procedimiento de construccion del heap es más rápido! Uso: cuando se requieren solo los m mayores elementos: 1. construccion en O(n) pasos. 2. obteneción de los m mayores elementos en O(m•log n) pasos. costo total : O( n + m•log n).

Addendum: Ordenando con árboles de búsqueda Algorithm: Construccion del árbol de búsqueda (e.g. AVL-tree) con lo elementos que hay que ordenar haciendo n opearciones de inserción. Obtención de los elementos recorriendo el árbol en secuencia InOrder.  Secuencia Ordenada. costo: 1. O(n log n) con AVL-trees, 2. O(n). en total: O(n log n). optimal!

Bucketsort No se basa en comparación entre elementos Adecuado cuando los elementos están compuestos de un número fijo (y ojalá no muy grande) de símbolos Ejemplo: Ordenar 10 claves numéricas de 5 dígitos n = 10 k = 5 73895 93754 82149 99046 04853 94171 54963 70471 80564 66496

Idea general Es fácil ordenar un conjunto de números según una de sus componentes usando un arreglo de listas (colas) igual a la cantidad de símbolos distintos que pueden aparecer En el ejemplo, pueden aparecer 10 símbolos y se ordenó según el tercer digito 99046 82149 94171 70471 66496 80564 93754 73895 04853 54963

Distribución de los elementos en las colas En el caso del ejemplo, se tienen 10 colas Q[0]..Q[9] y para ordenar por el tercer elemento: Poner cada x en la cola Q[ x/100 mod 10] Armar una sola lista poniendo primero las que quedaron en Q[0] luego las de Q[1] .. Y por último las de Q[9] 99046 82149 94171 70471 66496 80564 93754 73895 04853 54963

Iteración Este proceso se hace iterativamente utilizando el último símbolo de la clave, luego el penúltimo y así hasta llegar al primero ¿ análisis ? 73895 93754 82149 99046 04853 94171 54963 70471 80564 66496 94171 70471 04853 54963 80564 93754 73895 66496 99046 82149 99046 82149 04853 93754 54963 80564 94171 70471 73895 66496 99046 82149 94171 70471 66496 80564 93754 73895 04853 54963 70471 80564 82149 93754 73895 94171 04853 54963 66496 99046 04853 54963 66496 70471 73895 80564 82149 93754 94171 99046

Sorting Externo Problema: ordenar un archivo muy grande guardado en bloques (páginas). Eficiencia: numero de acceso a páginas debe minimizarse! Estrategia: Usar un algoritmo que procese los datos en forma secuencial para evitar frecuentes cambios de página: MergeSort!

Forma General para Merge mergesort(S) { # retorna el conjunto S ordenado if(S es vacío o tiene sólo 1 elemento) return(S); else { Dividir S en dos mitades A y B; A'=mergesort(A); B'=mergesort(B); return(merge(A',B')); } Clásico ejemplo de dividir para reinar

void merge(Comparable[]x,int ip,int im,int iu){ Comparable[]a=new Comparable[iu+1]; int i=ip,i1=ip,i2=im+1; while (i1<=im && i2 <= iu) if (x[i1] < x[i2]) a[i++]=x[i1++]; else a[i++]=x[i2++]; while (i1 <= im) a[i++]=x[i1++]; while (i2 <= iu) a[i++]=x[i2++]; for(int i=ip; i<=iu; ++i) x[i]=a[i]; }

Análisis

Meregesort en Archivos: Start: se tienen n datos en un archivo g1, divididos en páginas de tamaño b: Page 1: s1,…,sb Page 2: sb+1,…s2b … Page k: s(k-1)b+1 ,…,sn ( k = [n/b]+ ) Si se procesan secuencialmente se hacen k accesos a paginas, no n.

Variacion de MergeSort para external sorting MergeSort: Divide-and-Conquer-Algorithm Para external sorting: sin el paso divide, solo merge. Definicion: run := subsecuencia ordenada dentro de un archivo. Estrategia: by merging increasingly bigger generated runs until everything is sorted.

Algoritmo 1. Step: Generar del input file g1 „starting runs“ y distribuirlas en dos archivos f1 and f2, con el mismo numero de runs (1) en cada uno (for this there are many strategies, later). Ahora: use 4 files f1, f2, g1, g2.

2. Step (main step): while (number of runs > 1) { Merge each two runs from f1 and f2 to a double sized run alternating to g1 und g2, until there are no more runs in f1 and f2. Merge each two runs from g1 and g2 to a double sized run alternating to f1 and f2, until there are no more runs in g1 und g2. } Each loop = two phases

Example: Start: g1: 64, 17, 3, 99, 79, 78, 19, 13, 67, 34, 8, 12, 50 1st. step (length of starting run= 1): f1: 64 | 3 | 79 | 19 | 67 | 8 | 50 f2: 17 | 99 | 78 | 13 | 34 | 12 Main step, 1st. loop, part 1 (1st. Phase ): g1: 17, 64 | 78, 79 | 34, 67 | 50 g2: 3, 99 | 13, 19 | 8, 12 1st. loop, part 2 (2nd. Phase): f1: 3, 17, 64, 99 | 8, 12, 34, 67 | f2: 13, 19, 78, 79 | 50 |

Example continuation 1st. loop, part 2 (2nd. Phase): f1: 3, 17, 64, 99 | 8, 12, 34, 67 | f2: 13, 19, 78, 79 | 50 | 2nd. loop, part 1 (3rd. Phase): g1: 3, 13, 17, 19, 64, 78, 79, 99 | g2: 8, 12, 34, 50, 67 | 2nd. loop, part 2 (4th. Phase): f1: 3, 8, 12, 13, 17, 19, 34, 50, 64, 67, 78, 79, 99 | f2:

Costs Page accesses during 1. step and each phase: O(n/b) In each phase we divide the number of runs by 2, thus: Total number of accesses to pages: O((n/b) log n), when starting with runs of length 1. Internal computing time in 1 step and each phase is: O(n). Total internal computing time: O( n log n ).

Two variants of the first step: creation of the start runs A) Direct mixing sort in primary memory („internally“) as many data as possible, for example m data sets  First run of a (fixed!) length m, thus r := n/m starting runs. Then we have the total number of page accesses: O( (n/b) log(r) ).

Two variants of the first step: creation of the start runs B) Natural mixing Creates starting runs of variable length. Advantage: we can take advantage of ordered subsequences that the file may contain Noteworthy: starting runs can be made longer by using the replacement-selection method by having a bigger primary storage !

Replacement-Selection Read m data from the input file in the primary memory (array). repeat { mark all data in the array as „now“. start a new run. while there is a „now“ marked data in the array { select the smallest (smallest key) from all „now“ marked data, print it in the output file, replace the number in the array with a number read from the input file (if there are still some) mark it „now“ if it is bigger or equal to the last outputted data, else mark it as „not now“. } Until there are no data in the input file.

Example: array in primary storage with capacity of 3 The input file has the following data: 64, 17, 3, 99, 79, 78, 19, 13, 67, 34, 8, 12, 50 In the array: („not now“ data written in parenthesis) Runs : 3, 17, 64, 78, 79, 99 | 13, 19, 34, 67 | 8, 12, 50 64 17 3 99 79 78 (19) (13) (67) 19 13 67 34 (8) (12) (50) 8 12 50

Implementation: In an array: At the front: Heap for „now“ marked data, At the back: refilled „not now“ data. Note: all „now“ elements go to the current generated run.

Expected length of the starting runs using the replace-select method: (m = size of the array in the primary storage = number of data that fit into primary storage) by equally probabilities distribution Even bigger if there is some previous sorting!

Multi-way merging Instead of using two input and two output files (alternating f1, f2 and g1, g2) Use k input and k output files, in order to me able to merge always k runs in one. In each step: take the smallest number among the k runs and output it to the current output file.

Cost: In each phase: number of runs is devided by k, Thus, if we have r starting runs we need only logk(r) phases (instead of log2(r)). Total number of accesses to pages: O( (n/b) logk(r) ). Internal computing time for each phase: O(n log2 (k)) Total internal computing time: O( n log2(k) logk(r)) = O( n log2(r) ).