Tema 2 busqueda_ordenacion_grupo_21
-
Upload
carlos-a-iglesias -
Category
Technology
-
view
825 -
download
0
description
Transcript of Tema 2 busqueda_ordenacion_grupo_21
Análisis y Diseño de Software
Departamento de Ingeniería de Sistemas Telemáticoshttp://moodle.dit.upm.es
Tema 2. Búsqueda y Ordenación
Carlos A. Iglesias <[email protected]>
G21
Búsqueda y Ordenación 2
Teoría
Ejercicio práctico en el ordenador
Ampliación de conocimientos
Lectura / Vídeo / Podcast
Práctica libre / Experimentación
Legenda
Búsqueda y Ordenación 3
Bibliografía
● Data Structures & Algorithms in Java, Robert Lafore, 2nd Edition, SAMS, 2002
● Capítulos 3, 7
●http://www.informit.com/store/product.aspx?isbn=0672324539
Búsqueda y Ordenación 4
Biblografía
● The Art of Computer Programming: Sorting and Searching, v.3, Donald E. Knuth, 3rd edition, 1998
Búsqueda y Ordenación 5
Bibliografía
● Applets de visualización http://www.informit.com/store/product.aspx?isbn=0672324539
● http://www.sorting-algorithms.com/
● http://math.hws.edu/eck/jsdemo/sortlab.html
Búsqueda y Ordenación 6
Temario
● Introducción a búsqueda y ordenación
● Búsqueda– Búsqueda lineal
– Búsqueda binaria
●Ordenación– Clasificación
– Algoritmos: selección, inserción, quicksort
● Colecciones ordenadas
● Inserción ordenada
Búsqueda y Ordenación 7
Objetivos
● Entender qué son los algoritmos, por qué son importantes, y cómo se pueden comparar
● Entender los problemas de ordenación y búsqueda
● Entender algunos algoritmos de ordenación y búsqueda, sus propiedades, y cómo se implementan
Búsqueda y Ordenación 8
Buscar... ordenar...
Búsqueda y Ordenación 9
“La búsqueda es una herramienta básica que cada programador debería conocer para utilizar en un gran número de ocasiones” Donald Knuth, “El Arte de Programación de Ordenadores”, Vol. 3, 1973.
Búsqueda
10
Búsqueda
●int busca(int val, int [] tabla)– Devuelve i tal que x== tabla[i]
– -1 si no lo encuentra
●Búsqueda lineal– Sobre cualquier array
– Recorremos el array hasta que lo encontramos
●Búsqueda binaria– Sobre arrays ordenados
11
Pruebas funcionales
● Comprobamos que un método / clase / … funciona como es esperado
● Probamos casos de diferentes clases de equivalencia: representantes de casos diferentes (válidos, inválidos, ...)
● Probar casos límite de cada clase de equivalencia: 0, 1, n, n+1
● Usamos JUnit para hacer pruebas funcionales unitarias
12
Pruebas de prestaciones● Medimos recursos que
consume nuestra implementación
● Nos permite comparar qué implementación (que funciona) es mejor, y en qué condiciones es razonable usarla
● Medimos (p.ej. tiempo o memoria o …) antes y después de ejecutar la función
13
Ejercicio
● Programa SearchTest
● P.ej.– Pruebas sobre un
array [1, 2, 3, 4, 5]
14
Búsqueda lineal
● Buscamos hasta encontrarlo
● Ejercicio. Implementar
● int buscaLineal (int val, int [] tabla)– Devuelve i tal que x== tabla[i]
– -1 si no lo encuentra
● ¿Cuántas comparaciones haremos en media?
● Se dice que tiene complejidad O(n)
15
Vamos a medir...
● Test de prestaciones– Método para crear un array de tamaño n de longs
aleatorios• private long [] fillRandomArray(long n)
– Método que mida tiempos, buscando un valor aleatorio en un array de tamaño n, y que lo busque muchas veces (1M)• private long calculateTimes(Search s, int n)
– Método que imprima los tiempos, probando para diferentes tamaños de array (100, 500, 1000, ...)• private void showTimes(Search s)
16
Adivina un número entre 0 y 50 ...
¿Quépreguntaríamos?
17
Búsqueda binaria – Arrays.binarySearch()
●Si sabemos que está ordenado,
– Dividimos el array por su elemento medio.
– Comparamos con el elemento del centro. Si coincide, terminamos. Si el elemento es menor, debe estar en el subarray de la izda, y si es mayor en el de la derecha. Seguimos haciendo esto hasta encontrarlo• Ej. [1,2,3,4,5,6,7,8,9] y busco el 3
• [1,2,3,4]-5-[6,7,8,9] como 3 es menor que 5
• [1]-2-[3 ,4] como 3 es menor que 2 → []-3-[4] → Encontrado
18
Búsqueda binaria - Ejercicios
● Programar versión iterativa● Programar versión recursiva
19
Prestaciones...
● Comparar tiempos de las tres implementaciones:– Búsqueda lineal– Búsqueda binaria iterativa– Búsqueda binaria recursiva
Búsqueda y Ordenación 20
Ordenación
“Pero no puedes comprobar a tiempo todos los carnets de conducir” - objetó Drake. “No lo necesitamos, Paul. Simplemente los ordenamos y buscamos los duplicados”
– Perry Mason, El caso de la Amiga Histérica, 1951
Búsqueda y Ordenación 21
● En cualquier problema con una pequeña base de datos, nos enfrentamos a la ordenación: alfabética, alumnos por curso, pedidos, …
● La ordenación puede ser un paso previo a la búsqueda
Ordenación (Sorting)
Búsqueda y Ordenación 22
¿Por qué estudiamos algoritmos de ordenación?
● Ordenar es muy habitual y puede requerir mucho tiempo (= ¡consumo en un móvil!)
● Se han diseñado algoritmos que permiten optimizar esta tarea
● Vamos a ver– Algoritmos básicos (poco optimizados):
• selección, inserción, burbuja
– Algoritmos más avanzados• Quicksort, búsqueda binaria
Búsqueda y Ordenación 23
El problema...
Búsqueda y Ordenación 24
Algoritmos de ordenación sencillos
● sort(int [] tabla)
● Burbuja– Voy permutando hasta que no hay cambios
● Selección – Voy seleccionando el menor
● Inserción– Voy insertando en su lugar
Búsqueda y Ordenación 25
Algoritmos
Búsqueda y Ordenación 26
Algoritmos básicos: estrategia
● En muchas pasadas– Comparo dos
elementos– Los intercambio si
no están en orden, o copio uno
Búsqueda y Ordenación 27
Ordenación por Burbuja (Bubble Sort)
● Es muuuuuuuuuuuuy lento, pero muy sencillo de entender– Comparamos de dos en 2, e intercambiamos si
no están ordenados– Cuando en una iteración no hay cambios,
hemos terminado– Los más pequeños flotan a la izda
http://en.wikipedia.org/wiki/Bubble_sort
28
Ordenación: burbuja
●Comparamos un elemento con el siguiente, y si es mayor los intercambiamos
●Seguimos comparando con el siguiente, e intercambiando, hasta que en la primera pasada habrá quedado el mayor a la derecha.
●Seguimos haciendo esto hasta que no hay cambios
Búsqueda y Ordenación 29
Invariantes
● Para analizar un algoritmo, podemos fijarnos en los invariantes
● Invariante: condición que se cumple siempre a medida que procede el algoritmo– Facilitan depurar el algoritmo
● Burbuja: en cada pasada, el elemento que queda a la derecha, está ordenado
Búsqueda y Ordenación 30
Programación - Burbuja
?
Búsqueda y Ordenación 31
Análisis complejidad – notación O
● Si analizamos cuántas comparaciones hacemos
● P. ej para n = 10– 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 = 45
● En general, para N:– (N – 1) + (N – 2) + … + 1 = N * (N-1)/2
● Si N es grande, el número será N2
● La notación O : O(N2)
Búsqueda y Ordenación 32
Complejidad intercambios
● Si analizamos intercambios, si suponemos que el conjunto es aleatorio, podemos suponer que sólo estarán desordenados la mitad– Si había N2/2 comparaciones, habría N2/4
intercambios
● Tanto comparaciones como intercambios son O(N2)
Búsqueda y Ordenación 33
Burbuja...
“El algoritmo de ordenación de la burbuja sólo tiene de bonito el nombre”, Donald Knuth, El Arte de la Programación de Ordenadores, vol. 3., 1973.
Búsqueda y Ordenación 34
Burbuja
Búsqueda y Ordenación 35
Danzas húngaras
●Puedes aprender los algoritmos mirando danzas húngaras...
http://www.youtube.com/watch?v=lyZQPjUT5B4
Búsqueda y Ordenación 36
Selección (Selection sort)
● Buscamos el mínimo de la lista
– Lo intercambiamos con el primero
● Buscamos el mínimo del resto de la lista
– Lo intercambiamos con el segundo
…
● En general
– Busco el mínimo entre i y la posición final de la lista
– Intercambio el mínimo con el elemento en la posición i
37
Selección
38
Análisis
● Invariante: los elementos de la izquierda que ya hemos intercambiado, están siempre ordenados
● Complejidad:
– Hacemos las mismas comparaciones que en la burbuja: N * (N – 1) /2 → O(N2)
– Hacemos menos intercambios, menos que N (una pasada) → O(N)
● Para grandes valores de N, pesará más el término de comparaciones, y la complejidad será O(N2)
● Para N pequeño, será más rápido que la burbuja
● En general: no es un algoritmo adecuado
● Puede ser bueno si los tiempos de intercambio son altos
39
Inserción (insertion sort)
● Como con las barajas
● En cada pasada, cogemos un elemento y lo dejamos 'colocado', y vamos a por el siguiente
40
Inserción
41
Análisis
● Invariante: los elementos que ya hemos analizado están ordenados entre sí
● Complejidad: – En la primera pasada, comparamos con 1 carta, en la
segunda con 2, en la tercera con 3, … → 1 + 2 + 3 + … + N – 1 = N * (N – 1) / 2
– En media, compararemos con la mitad de cartas ordenadas → N * (N – 1) / 4 → O(N2)
– Número de copias similar al de comparaciones, pero una copia requiere menos tiempo que un intercambio
– Si los datos ya están ordenados (o casi), sería O(N)
42
Estabilidad
● Se dice que dos algoritmos son estables si mantienen el orden original, y sólo cambian el orden si hace falta
● P. ej. tenemos alumnos ordenados por apellidos, y queremos ordenarlos por notas
● Burbuja y selección son estables
● Selección es inestable, aunque se puede hacer una implementación estable
43
Quicksort(Hoare, 1960)
● Sigue estrategia “divide y vencerás”
● Pasos – Toma un elemento (pivote de la lista)– Partición: Reordena → elementos menores a
la izda de pivote, mayores a la derecha, el pivote queda en su sitio
– Recursión: ordena sublista de menores y de mayores
44
QuickSort
● Divide y vencerás
<= p > pp
<= p > pp <= p > pp
<= p > p
se ordenan los casos triviales, y queda ordenado el conjunto
<= p > p <= p > p <= p > p
45
Implementación
46
Análisis
● Invariante: – la parte izda < pivote– la parte dcha > pivote
● Complejidad:– En la mayor parte de los casos es el más
rápido: O(n * log(n))
47
Análisis complejidad
Mejor Medio PeorSelección O (n2) O (n2) O (n2)Inserción O (n) O (n2) O (n2)
Burbuja O (n) O (n2) O (n2)Quick sort O (n log n) O (n log n) O (n2)
48
● Tiempo en ms, en Pentium 100 con 16MRam
Comparación
N selección inserción burbuja QuickSort Quick + Insert1 0 0 0 0 02 0 0 0 0 05 0 0 0 0 0
10 0 0 0 0 020 0 0 0 0 050 0 0 6 0 0
100 5 0 11 0 0200 22 11 39 0 6500 109 61 236 11 11
1.000 417 253 956 27 282.000 1.654 1.005 3.817 55 555.000 10.309 6.207 23.898 165 159
10.000 41.375 24.816 96.042 352 33620.000 165.710 99.152 381.415 807 758
49
Comparación
050.000
100.000150.000
200.000250.000
300.000350.000
400.000450.000
100
200
500
1.00
02.
000
5.00
0
10.0
00
20.0
00
L
T (
ms
)
burbuja
selección
inserción
QuickSort
Quick + Insert
50
Caso mejorN selección inserción burbuja QuickSort Quick + Insert
1 0 0 0 0 02 0 0 0 0 05 0 0 0 0 0
10 0 0 0 0 020 0 0 0 0 050 0 0 0 0 0
100 6 0 0 0 0200 17 0 0 0 0500 115 0 0 6 5
1.000 473 0 0 17 162.000 1.890 0 0 39 275.000 11.820 6 11 109 83
10.000 47.428 22 11 242 18120.000 189.140 39 27 522 390
51
Caso mejor
100
500
2.00
0
10.0
00
inserción
Quick + Insert0
200
400
600
T (m
s)
L
inserción
burbuja
Quick + Insert
QuickSort
52
Ordenar objetos en Java
● En Java para ordenar, usamos al interfaz Comparable
● int c = a.compareTo(b)
● Orden:
– c < 0 → a < b
– c == 0 → a == b
– c > 0 → a > b
● Al implementar Comparable, tenemos que cumplir:
– x.compareTo(y) == 0 ↔ x.equals(y)
– Transitividad. Si x.compareTo(y) > 0 && y.compareTo(z) > 0 → x.compareTo(z) > 0
– Si x.compareTo(y) == 0 → signo(x.compareTo(z)) == signo(y.compareTo(z)), para todo z
interface Comparable<T> { int compareTo(T o);}
53
Ejemplo
public class Persiona implements Comparable {private String nombre;private String apellido;int edad;
public int compareTo(Persona otra) {int c1 = apellido.compareTo(otra.apellido);if (c1 != 0) { return c1;}int c2 = nombre.compareTo(otra.nombre);if (c2 !=0) {return c2;}return otra.edad – edad;
}}
54
Inserción: búsqueda + ordenación
● Si vamos a insertar y buscar objetos comparables, podemos...
● Inserción ordenada + búsqueda binaria● Inserción (como venga) + búsqueda lineal● Inserción + ordenación + búsqueda binaria●¿qué hacemos?
• → según lo que tarde cada operación
55
Inserción ordenada
● Si sabemos que el array ya está ordenado...
●Hay variantes como 'binary insertion sort' que hace una búsqueda binaria (en vez de lineal) para determinar dónde insertar
56
Ordenación perezosa (lazy sorting)
● Puede ser interesante ordenar sólo cuando hace falta (dependerá de cómo sea de costoso!)
● Insertar sin preocuparnos del orde
●Ordenar al sacar un elemento
dato[pos++] = nuevoDato;ordenado = false;
if (!ordenado) { sort(datos, 0, pos); ordenado = true;}return binarySearch(datos, dato);
Búsqueda y Ordenación 57
Resumen
● Tenemos diferentes algoritmos para ordenar y buscar
● Las pruebas de prestaciones nos permiten medirlos– Es difícil (elementos externos como la máquina
o GC en Java)
● Hemos visto dos algoritmos de búsqueda: lineal y binaria (para arrays ordenados)
Búsqueda y Ordenación 58
Resumen
● Los algoritmos sencillos de ordenación (burbuja, inserción, selección) tienen complejidad media O(N2)
● Quicksort tiene complejidad O(nlog(n)) y puede ser inestable, según la implementación