Algoritmos. el algoritmo de ordenación. de ordenación (II) a 18 anales. En la primera parte de este. Introducción

Documentos relacionados
Algoritmos de ordenación (I)

Métodos de Ordenamiento. Unidad VI: Estructura de datos

Algoritmos sobre Listas

Algorítmica y Complejidad. Tema 3 Ordenación.

Este método se basa en buscar el elemento menor el vector y colocarlo en la primera

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

Esquema de Dividir y Vencer

Tema 9. Recursividad

Ordenamiento (Sorting)

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

7.1 Consideraciones. Considere la búsqueda de un libro en una biblioteca. Considere la búsqueda de un nombre en el directorio telefónico.

Materia requisito: DOMINIOS COGNITIVOS (Objetos de estudio, temas y subtemas) I. Introducción al Análisis de Algoritmos.

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

5 Métodos de Ordenamiento. 5.1 Métodos de Ordenamiento Internos Burbuja Quicksort Heapsort Inserción Simple 5.1.

Francisco J. Hernández López

ASIGNATURA: (TIS-106) Estructuras de Datos II DOCENTE: Ing. Freddy Melgar Algarañaz TEMA 4. Montículos binarios (heaps)

Algoritmos de Ordenación

ELO320 Estructuras de Datos y Algoritmos. Heap & HeapSort. Tomás Arredondo Vidal

CAPITULO II ORDENAMIENTO Y BUSQUEDA. Ivan Medrano Valencia

Dividir-conquistar y podar-buscar

Examen de Estructuras de Datos y Algoritmos. (Modelo 2)

Examen de Estructuras de Datos y Algoritmos. (Modelo 1)

EDA. Tema 8 Colas de Prioridad: Heaps

Estructura de Datos. Árboles Binarios de Búsqueda ABB. Primer Semestre, 2010

TEMA 1: DIVIDE Y VENCERÁS

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

Eduardo Andrés Medina Ramírez Angel Robles Pérez MÉTODO DE ORDENAMIENTO QUICKSORT

Algoritmos de Ordenamiento

PROGRAMACIÓN ESTRUCTURADA

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

Complejidad computacional. Algoritmos y Estructuras de Datos I. Complejidad computacional. Notación O grande

Tema 3. Análisis de costes

Métodos de ordenamiento:

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

Programación (PRG) PRÁCTICA 10. Algoritmos de búsqueda

Ordenamiento y Búsqueda

Estructura de Datos Árboles Árboles 2-3

Tema 2.- Ordenación (Parte I)

Apunte de cátedra: Ordenación de Arreglos

Métodos de ordenamiento:

23. Ordenación de vectores (tablas) Diego Gutiérrez

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

Estructuras de datos: Árboles binarios de

Estructura de datos y Algoritmos. Tema III Clasificación en memoria secundaria

Métodos de ordenamiento y búsqueda en vectores

Algoritmos de búsqueda básicos

ANÁLISIS Y DISEÑO DE ALGORITMOS

ARBOLES B. Lo que si es cierto es que la letra B no significa "binario", ya que:

Análisis de Algoritmos

Tema: Métodos de Ordenamiento. Parte 3.

Teoría de Algoritmos 2 o curso de Ingeniería Informática

ESCUELA SUPERIOR POLITÉCNICA DEL LITORAL FACULTAD DE INGENIERÍA EN ELECTRICIDAD Y COMPUTACIÓN SYLLABUS DEL CURSO Análisis de Algoritmos

11-Ordenar Definiciones 11.2 Selección 11.3 Intercambio 11.4 Inserción 11.5 Shellsort 11.6 Quicksort 11.7 Mergesort.

10. Algoritmos de ordenación

Estructura de Datos. Complejidad de Algoritmos. Algoritmo. Algoritmo. Mauricio Solar Lorna Figueroa

Análisis y Diseño de Algoritmos

1. Planteamiento general

Capítulo. Algoritmos de ordenación y búsqueda. Contenido. Introducción

Programación Análisis de Algoritmos: Tiempo de Ejecución (Introducción)

ANX-PR/CL/ GUÍA DE APRENDIZAJE. ASIGNATURA Algoritmica y complejidad. CURSO ACADÉMICO - SEMESTRE Primer semestre

Algoritmos y Complejidad

ALGORITMO DE ORDENACIÓN

Algoritmos de ordenación básicos

IN34A - Optimización

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

Tema 9. Algoritmos sobre listas. Programación Programación - Tema 9: Algoritmos sobre listas

Análisis de Algoritmos

Análisis de Algoritmos

Universidad Autónoma del Estado de Hidalgo Instituto de Ciencias Básicas e Ingeniería Área Académica de Computación y Electrónica

Análisis de algoritmos

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

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

UNIVERSIDAD TECNOLOGICA DE PEREIRA FACULTAD DE INGENIERIAS

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

Algorítmica y Lenguajes de Programación. Eficiencia y notación asintótica (i)

Tema: Métodos de Ordenamiento. Parte 3.

GUÍA DOCENTE ABREVIADA DE LA ASIGNATURA

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

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

Guía docente de la asignatura

Demostrando cotas inferiores: Arboles de decisión

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

La eficiencia de los programas

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

Complejidad computacional. Algoritmos y Estructuras de Datos I. Complejidad computacional. Notación O grande

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

Tema 10: Árbol binario de búsqueda

FICHEROS Y BASES DE DATOS (E44) 3º INGENIERÍA EN INFORMÁTICA. Tema 4. Técnicas de Dispersión. Definición y Manejo.

UNIVERSIDAD TECNOLÓGICA DE PEREIRA FACULTAD DE INGENIERÍAS MAESTRÍA EN INGENIERÍA DE SISTEMAS Y COMPUTACIÓN ALGORITMIA

FICHEROS Y BASES DE DATOS (E44) 3º INGENIERÍA EN INFORMÁTICA. Tema 3. Estructuras de Almacenamiento. Básicas. Definición y Manejo.

Informe Tarea II. Estructura de Datos VPT (Vintage Point Tree)

ANX-PR/CL/ GUÍA DE APRENDIZAJE

Muchas de las ecuaciones de recurrencia que vamos a usar en este curso tienen la siguiente forma: ( c n =0 T (n) = a T (b n b.

DISEÑO DE UN ANIMADOR DE ALGORITMOS DE BÚSQUEDA Y ORDENACIÓN ( ID2012/055 )

Tema 2. Divide y vencerás.

1. Definiciones previas

EVALUACIÓN DE MÉTODOS DE ORDENACIÓN: QuickSort vs. QuickSort con pseudomediana

2. Con una lista ordenada, aunque la localización y eliminación es rápida el problema es en la inserción de datos pues puede ser del orden de O(n).

ESTIMACIÓN DE TIEMPO Y COSTO DE PRODUCTOS SOFTWARE

Transcripción:

Algoritmos de ordenación (II) Todos sabemos que los ordenadores, entre otras cosas, sirven para ordenar. Pero Cómo lo hacen? Existen distintos modos de hacerlo? Depende de lo que tengamos que ordenar? Es tan crítico elegir correctamente el método de ordenación? En este artículo divulgativo se pretende dar respuesta a estas y a otras preguntas, mostrando como funcionan los algoritmos de ordenación más importantes y discutiendo las claves a tener en cuenta para seleccionar el algoritmo más apropiado para un problema concreto. Introducción En la primera parte de este artículo, publicado en el número anterior de esta revista (Vol. LXXVIII, Fascículo II, pp. 28-32), se ha argumentado la importancia de los algoritmos de ordenación; explicándose por qué es crítico seleccionar correctamente el algoritmo de ordenación y discutiendo las claves a tener en cuenta para realizar dicha elección correctamente. En computación los algoritmos de ordenación se pueden clasificar atendiendo a distintos criterios. Una posible clasificación consiste en distinguir entre algoritmos simples y sofisticados. Anteriormente se ha mostrado como funciona Inserción Directa, uno de los algoritmo simples más utilizados. En esta segunda parte del artículo se describen Selección Directa y la Burbuja, otros dos algoritmos simples, así como los dos algoritmos sofisticados más importantes: y. Finalmente se analiza el tiempo de ejecución de estos algoritmos desde un punto de vista teórico y práctico. Eugenio Francisco Sánchez Úbeda Doctor Ingeniero del ICAI Instituto de Investigación Tecnológica y Departamento de Sistemas Informáticos de la Universidad Pontificia Comillas de Madrid, donde es coordinador del Área de Sistemas Inteligentes (ASI) E-mail: Eugenio.Sanchez@iit.upco.es Algoritmos Este algoritmo utiliza otra forma de ordenar que también la empleamos con frecuencia en la vida cotidiana y que, en cierta a 8 anales

Selecciona la carta siguiente FIGURA 6. SELECCIÓN DIRECTA Hay dos zonas: una zona desordenada (en azul) y una zona ordenada (en naranja). En cada paso se selecciona de la zona desordenada el elemento menor y se inserta al final de la secuencia. 7 9 6 Cartas por ordenar 5 Inserta al final 23 Cartas ya ordenadas manera, es la inversa u opuesta a como trabaja Inserción Directa. Nuevamente los elementos se dividen en dos secuencias, una ordenada y otra desordenada. En cada paso se selecciona de la zona desordenada el elemento con clave menor y se inserta al final de la secuencia ordenada. El nombre de este algoritmo hace referencia al paso más costoso del mismo: la búsqueda o selección en la zona desordenada del elemento más pequeño. Esta búsqueda se realiza de forma exhaustiva recorriendo sistemáticamente toda la secuencia desordenada. Lógicamente, ahora los elementos de la zona desordenada siempre tienen una clave mayor o igual que los elementos de la zona ordenada. Si tenemos que ordenar pocos datos y no tenemos conocimiento alguno sobre el grado de desorden que presentan; o bien, son pocos datos y tenemos la certeza de que están muy desordenados, entonces debemos utilizar Selección Directa. Burbuja (el peor) Selección Directa(A) For i= to Tamaño(A) - k=i; x = A[i]; 2 For j=i+ to Tamaño (A) % selección if (A[j]<x) then k=j; x=a[j]; end 2 A[k]=A[i]; % inserta al final A[i]=x; A [i]: clave i: Posición en el vector A Elementos de la zona ordenada Elementos de la zona desordenada Este algoritmo simple explota otra idea básica de ordenación, el intercambio de elementos. Si dos elementos están mal colocados, se intercambian. Es necesario hacer repetidas pasadas sobre el vector para conseguir ordenar los datos. Aunque este algoritmo aparece frecuentemente en la literatura, a parte del interés didáctico que pueda tener, nunca debe emplearse en la práctica. De he- aanales 9

cho, un análisis sencillo del mismo demuestra de forma teórica y contundente que es inferior a otros algoritmos simples como Inserción o Selección Directa. FIGURA 7. HEAPSORT Hay dos zonas: una zona desordenada (en azul) y una zona ordenada (en naranja). En cada paso se selecciona de la zona desordenada el elemento mayor y se inserta al final de la secuencia ordenada. Una estructura montículo en la zona desordenada permite una selección muy rápida del elemento mayor. Algoritmos sofisticados Ya se ha comentado que Selección Directa se basa en ir seleccionando y sacando repetidamente el mínimo de la secuencia desordenada. Si en un momento dado hay N elementos en la zona desordenada, para encontrar el mínimo Selección Directa recorrerá dicha secuencia realizando N- comparaciones. En la siguiente iteración la zona desordenada tendrá N- elementos, siendo necesarias N-2 comparaciones para encontrar el nuevo mínimo. 7 4 6 3 2 7 4 6 3 2 Fin nace como una sofisticación de Selección Directa. La idea sigue siendo la misma (buscar en la zona desordenada e insertar en la ordenada), pero con una mejora sustancial en el proceso de búsqueda de la zona desordenada. consigue acelerar búsquedas sucesivas del elemento siguiente a insertar guardando en la búsqueda anterior mucha más información de la zona desordenada que meramente la posición del elemento a insertar (como se hace en Selección Directa). Para ello, el algoritmo emplea una estructura especial denominada montículo ( heap en inglés, de ahí el nombre del algoritmo). a 2 anales (A) ConstruyeMonticuloinicial (A); Fin = Tamaño(A); % montículo de a Fin For i = N to 2, step - intercambiar A[] con A[i]; Fin = Fin - ; Monticuliza (A, Fin, ); Construyemonticuloinicial (A) Fin = N; For i = floor (N/2) to, step - Monticuliza (A, Fin, i); Monticuliza (A, Fin, i) iz=2*i ; de = 2*i+; if (iz Fin & A[iz]>A[i]) then mayor = iz; else mayor = i; 2 if (de Fin & A[de]>A[mayor]) then mayor = de; end 2 3 if (mayor =/ i) then intercambiar A[i] con A [mayor]; Monticuliza (A, Fin, mayor); end3

Un montículo es una estructura en donde cada elemento (nodo) está relacionado con otros elementos, formando un árbol. Cada nodo puede tener un padre y como mucho dos hijos. El nodo inicial o raíz se caracteriza por no tener padre. Además, en un montículo cada nodo debe ser mayor que todos sus descendientes. Para determinar rápidamente cuál es el elemento siguiente a insertar, el algoritmo mantiene actualizada la información de la zona desordenada (montículo) con un coste computacional muy bajo. (A, iz, de) if (iz < de) then d = Divide (A, iz, de); (A, iz, d); (A, d+, de); Divide (A, iz, de) r= numero_aleatorio_entre (iz, de); intercambiar A[iz] con A [r]; pivote = A[iz]; i = iz ; j = de; repetir while (A[i] < pivote) i = i+; end; while (pivote < A[j]) j = j- ; end; 2 if (i<j) then intercambiar A[i] con A[j]; i=i+; j=j-; else return j; end 2 Empezar con (A,, Tamaño(A)) FIGURA 8. QUICKSORT Basado en la estrategia divide y vencerás, es el algoritmo de ordenación preferido. En cada paso genera un subgrupo con todos los elementos menores al pivote y otro con los mayores a él. Colocando los elementos del primer subgrupo (en naranja) a la izquierda de los del segundo (en azul) y repitiendo el proceso recursivamente se ordenan todos los datos. Pivote Zona izquierda iz de Zona derecha Además, ordena in situ ya que el montículo se puede construir directamente sobre la zona desordenada, utilizando la posición en el vector para determinar cuál es el nodo padre y los hijos derecha e izquierda. Dado que ahora los pasos del algoritmo son más complejos, con un manejo de los datos mucho más laborioso, puede no compensar emplear si son pocos los datos a ordenar. Un algoritmo simple como Inserción o Selección Directa puede ser más rápido. Por otro lado, si tenemos bastantes datos a ordenar, seguramente será más interesante utilizar. En 962 Hoare publicó un nuevo algoritmo, al que bautizó con el nombre de ( ordenación rápida ). Han pasado casi 4 años y continúa siendo el algoritmo de ordenación preferido, a pesar del esfuerzo realizado durante este tiempo para diseñar algoritmos más rápidos. Hay varias razones para tal supremacía: es muy eficiente en la mayoría de las situaciones, no emplea espacio adicional para realizar la ordenación (es in situ) y trabaja muy bien incluso en entornos de memoria virtual. emplea la estrategia divide y vencerás para resolver el problema de ordenación. Esta estrategia la utilizamos con frecuencia en la vida cotidiana. Por ejemplo, si tene- aanales 2

mos muchas facturas de varios años y las queremos ordenar por fecha, uno puede dividir las facturas en varios montones, uno por año. De este modo, podemos ordenar cada montón con independencia del resto, sabiendo que, una vez ordenados todos los montones, tendremos ordenadas todas las facturas. Para ordenar el montón de facturas de un año se puede repetir la misma estrategia, dividiendo ese montón en varios subgrupos, uno por trimestre. Nuevamente, podríamos dividir cada trimestre en meses y éstos a su vez en días. Ordenados todos meses de un trimestre, tendríamos el trimestre ordenado, y ordenados todos los trimestres de un año, el año completo. Ahora bien, Qué ocurre si al separar las facturas por años, todas menos una son del mismo año? y si al intentar clasificar estas últimas por meses, todas menos una son del mismo mes? Evidentemente algo no va bien. Hemos revisado dos veces todas las facturas (con el tiempo que esto supone) y sólo tenemos dos ordenadas. Esta estrategia de ordenación sólo es interesante si al dividir un grupo de elementos se consiguen subgrupos con un número similar de elementos, es decir, cuando obtenemos subproblemas de complejidad claramente inferior a la del problema original. El éxito de radica en su capacidad para dividir rápidamente un conjunto de datos en dos particiones bastante equilibradas. Para ello emplea un pivote, generando una partición o subgrupo con todos los elementos menores al pivote y la otra con los mayores a él. Colocando los elementos del primer subgrupo a la izquierda de los del segundo se consigue avanzar en la ordenación. Repitiendo recursivamente este proceso con cada subgrupo de elementos se consigue ordenar finalmente todos los datos. Lógicamente, el proceso de división termina cuando tengamos un conjunto con dos elementos. La selección del pivote es determinante para asegurar la rapidez del algoritmo. Idealmente el pivote debería ser la mediana, pues garantizaría una partición óptima (dos grupos de igual tamaño). Desgraciadamente en el cálculo de la mediana hay implícita una ordenación, por lo que su cálculo exacto está descartado. Existen varias formas de seleccionar un pivote razonable, entre las que destacan la estimación de la mediana con tres muestras (primer elemento, central y último), o la selección aleatoria de un elemento entre el primero y el último del grupo a dividir. Por último comentar que las versiones sofisticadas de no aplican la estrategia de partición hasta el final. Cuando el número de elementos es inferior a un cierto umbral, se emplea un algoritmo simple como Inserción Directa para terminar la ordenación de ese subconjunto. Un umbral razonable, basado en la experiencia, puede ser elementos. Análisis de los algoritmos El tiempo necesario para ejecutar un algoritmo de ordenación depende, entre otras cosas, de la cantidad de datos a ordenar. El sentido común nos dice que ordenar más datos debe ser más costoso que ordenar menos Pero cuánto? Existe una herramienta matemática que permite expresar de forma rigurosa el tiempo de ejecución de un algoritmo, la llamada notación asintótica. Como su nombre indica, esta notación sólo es apropiada para una situación asintótica en la que el número N de elementos a ordenar sea suficientemente grande. Por ejemplo, si decimos que el tiempo de ejecución de un algoritmo es O(N 2 ), significa que, en el peor de los casos y para N suficientemente grande, el tiempo de ejecución del algoritmo crecerá de forma cuadrática con N. Para N pequeño no tiene por qué ser así. Utilizando esta herramienta matemática, se han realizado numerosos estudios teóricos que permiten comparar el comportamiento asintótico de los distintos algoritmos de forma abstracta y en distintos casos hipotéticos (típicamente en el caso mejor, caso medio y peor). En estos estudios no se tiene en cuenta consideraciones prácticas importantes como la calidad del compilador utilizado o la gestión de memoria que en la actualidad realizan los ordenadores (denominada caching ). Además, Esta técnica de gestión de la memoria hace que sea más rápido acceder a posiciones consecutivas de un vector de datos. a 22 anales

Datos ya ordenados Coincide con el Caso Mejor para los algoritmos naturales. es el más rápido ya que sólo comprueba que los datos están ordenados. Datos aleatorios Coincide con el Caso Medio para los algoritmos naturales. es el más rápido para N suficientemente grande. Datos inversamente ordenados Coincide con el Caso Peor para los algoritmos naturales. tiene un comportamiento un poco antinatural.,25,2,5,,5,25 FIGURA 9. ANÁLISIS PRÁCTICO Pocos datos Datos ya ordenados 2 3 4 5 6 7,2,5,,5,25,2,5,,5 Datos aleatorios 2 3 4 5 6 7 Datos inversamente ordenados 2 3 4 5 6 7 5 5 Bastantes datos Datos ya ordenados 5 5 2 5 5 Datos aleatorios 5 5 2 5 5 Datos inversamente ordenados 5 5 2 suele ser difícil determinar para un algoritmo complejo cuáles son los casos peor, medio y peor. Todo ello hace que sea práctica común el analizar los algoritmos de forma experimental, midiendo el tiempo de ejecución necesario para ordenar vectores de datos de distinto tamaño y diferente nivel de desorden. Típicamente se suele estudiar el comportamiento en tres situaciones diferentes: Vector ya ordenado Vector desordenado (datos aleatorios) Vector inversamente ordenado Aunque es de esperar que estas tres situaciones coincidan con los casos mejor, medio y peor del algoritmo, puede ocurrir que no sea así, en cuyo caso se dice que el algoritmo es antinatural. es un poco antinatural ya que tarda más cuando los datos están ya ordenados. Inserción Directa es un ejemplo claro de algoritmo natural. En general los algoritmos simples son O (N 2 ), mientras que los algoritmos sofisticados son O (N log N). Por tanto, para N suficientemente grande (un valor relativamente pequeño en la práctica) los algoritmos simples no pueden competir en velocidad con los sofisticados. Una excepción es Inserción Directa; si los datos están ya ordenados (o casi), entonces el algoritmo es O (N), por lo que es superior incluso a. Sin embargo, si tenemos que ordenar muy pocos datos, entonces los algoritmos simples pueden ser más veloces que los sofisticados. En esta situación la notación asintótica no refleja el comportamiento del algoritmo. aanales 23

Además, también se puede observar que Selección Directa es preferible a Inserción Directa, salvo que los datos estén ordenados. En cuanto a los algoritmos sofisticados, es un poco más rápido que. Conclusiones Aunque se ha mostrado el funcionamiento de algunos de los algoritmos de ordenación más importantes, existen otros muchos que pueden resultar muy útiles en determinadas circunstancias. Por ejemplo, existen algoritmos especiales que para ordenar no realizan ningún tipo de comparación entre elementos. Estos algoritmos son extremadamente rápidos (de orden lineal) si se tiene la seguridad de que los datos a ordenar cumplen ciertos requisitos (unos exigen que las claves sean números enteros menores que una determinada cantidad, otros que sean valores distribuidos uniformemente entre y, etc.). Por otro lado, los algoritmos de ordenación presentados pertenecen a la categoría de los llamados algoritmos de ordenación interna. Sin embargo, también existen otros algoritmos, denominados de ordenación externa, especialmente diseñados para cuando la masa de datos a ordenar no cabe en memoria RAM. Estos algoritmos dependen sensiblemente de la tecnología de almacenamiento externo empleada (cintas, discos duros, CDs, etc.). Para mayor información, se recomienda consultar la bibliografía que se adjunta, en donde se puede encontrar abundante información sobre el tema. a Bibliografía [] T.H. Cormen, C.E. Leiseron y R.L. Rivest, Introduction to Algorithms, The MIT Press, 994. [2] C.A.R. Hoare,, The Computer Journal, Vol. 5, No., pp. -5, Abril 962. [3] J. Jaja, A perspective on, Computing in Science and Engineering, pp. 43-49, Enero-Febrero 2. [4] D.E. Knuth, El arte de programar ordenadores. Volumen 3: Ordenación y búsqueda, Editorial Reverté, 986. [5] R. Sedgewick, Algoritmos en C++, Editorial Díaz de Santos, 995. [6] M.A. Weiss, Estructuras de datos en Java, Addison Wesley, 2. [7] N. Wirth, Algoritmos + estructuras de datos = programas, Ediciones del Castillo, 985.