Ordenamiento

Anuncio
Orden en la sala!
Herman Schinca
Clase 17
24 de Mayo de 2011
Todos los lenguajes todos
Hoy veremos algoritmos. ¿Y eso qué es?
Son independientes del lenguaje en que se
implementen.
Son independientes de la existencia de las
computadoras.
Orden: ingredientes
Un tipo de dato
(int, char, float, bool)
+
Una relacion de orden sobre ese tipo
(menor, mayor, más lindo, R(x,y))
Ordenando arreglos
Problema:
Tengo un arreglo de números enteros y los quiero
ordenar siguiendo algún criterio. Por ejemplo, de
menor a mayor.
¿Ideas?
Vago Sort
Me fijo si ya está ordenado.
Si lo está, genial.
Sino, aduzco que hubo un problema con el
sistema operativo :-P.
Bogo Sort
Me fijo si ya está ordenado.
Si lo está, genial.
Sino, lo mezclo al “azar” y vuelvo a empezar.
¿Termina?¿Es un “buen” algoritmo?
¿Qué significa que sea bueno?
¿Cuál es la moral de los algoritmos?
3 Ejes
A la hora de pensar un algoritmo debo tener en
cuenta (al menos) 3 cuestiones imprescindibles:
1. Terminación
2. Correctitud
3. Complejidad/Eficiencia
Hay diversas técnicas particulares pero, en
general, se trata de problemas ¡no decidibles!
3 Ejes
En la materia no veremos en profundidad dichas
técnicas formales.
Sin embargo, es una buena práctica el pensar si
el algoritmo que tenemos en mente satisface
nuestras necesidades: termina, hace lo que
queremos que haga y puedo predecir su
“rapidez”.
Selection Sort
En cada paso elijo el elemento más chico de lo
que queda por ordenar, y lo coloco en su lugar
definitivo, es decir, a continuación del que elegí
en el paso anterior.
Selection Sort: Ejemplo
[5,4,2,1,3] →
[1,4,2,5,3] →
[1,2,4,5,3] →
[1,2,3,5,4] →
[1,2,3,4,5] →
Fin
Selection Sort: Código
void ordenar (int* a, int tam){
for (int i = 0; i < tam-1; i++) {
int k = i;
for (int j = i+1; j < tam; j++) {
if (a[j] < a[k]) {
k = j;
}
}
int aux = a[i]; a[i] = a[k]; a[k] = aux;
}
}
Selection Sort: Terminación
¿Termina?
¿Siempre?
¿Por qué?
Selection Sort: Correctitud
¿Qué habría que ver?
1. Termina (slide anterior).
2. Tengo exactamente los mismo elementos que
al inicio, ni más, ni menos, ni otros.
3. El arreglo está ordenado.
Selection Sort: Correctitud
El Selection Sort es...
Selection Sort: Contando
Operaciones
Vamos a suponer que las operaciones básicas
tienen el mismo costo computacional:
+,-,*,/,==,=,etc.
Vamos a contar cuántas operaciones realiza el
algoritmo en el peor caso.
Va a depender del tamaño de la entrada.
Selection Sort: Contando
Operaciones
void ordenar (int* a, int tam){
for (int i = 0; i < tam-1; i++) {
int k = i;
for (int j = i+1; j < tam; j++) {
if (a[j] < a[k]) {
k = j;
}
}
int aux = a[i]; a[i] = a[k]; a[k] = aux;
}
}
2 op
1 op
2*(tam-1-i) op
(tam-1-i) op
(tam-1-i) op
3 op
Selection Sort: Contando
Operaciones
Insertion Sort
En cada paso coloco el elemento en que estoy
parado en su posición definitiva, relativa a lo
elementos ya visitados.
Insertion Sort: Ejemplo
[5,4,2,1,3] →
[5,4,2,1,3] →
[4,5,2,1,3] →
[2,4,5,1,3] →
[1,2,4,5,3] →
[1,2,3,4,5] →
Fin
Insertion Sort: Código
void insertionSort (int *a, int tam){
for (int i=0; i < tam; i++) {
for (int j=i; 0 < j && a[j] < a[j-1]; j--) {
int aux = a[j]; a[j] = a[j-1]; a[j-1] = aux;
}
}
}
Insertion Sort: Ejercicio
Razonar acerca de su terminación.
Mostrar informalmente su correctitud.
Contar la cantidad de operaciones aproximada y
comparar con Selection Sort. ¿Es mejor? ¿Por
qué? ¿Existen casos en donde convenga usar
Insertion en vez de Selection?
Bubble Sort
En cada paso recorro el arreglo “desde atrás”
para seleccionar el elemento más pequeño que
aún no ha sido ordenado.
Bubble Sort: Ejemplo
[5,4,2,1,3] →
[1,2,5,4,3] →
[1,2,3,5,4] →
[1,2,3,4,5] →
[1,2,3,4,5] →
Fin
Bubble Sort: Ejemplo Zoom In
¿Pero cómo hace para ir de
[5,4,2,1,3]→[1,2,5,4,3]?
[5,4,2,1,3] →
[5,4,2,1,3] →
[5,4,1,2,3] →
[5,1,4,2,3] →
[1,5,4,2,3] →
...
Bubble Sort: Código
void bubbleSort (int *a, const int tam){
for (int i=0; i < tam-1; i++) {
for (int j=tam-1; i < j; j--) {
if (a[j] < a[j-1]) {
int aux = a[j]; a[j] = a[j-1]; a[j-1] = aux;
}
}
}
}
Bubble Sort: Ejercicio
Razonar acerca de su terminación.
Mostrar informalmente su correctitud.
Contar la cantidad de operaciones aproximada y
comparar con Selection e Insertion Sort. ¿Es
mejor? ¿Por qué? ¿Existen casos en donde
convenga usar Bubble Sort?
Tomar tiempos
Antes de ejecutar la función que ordena:
unsigned long comienzo = clock();
Luego de la llamada:
unsigned long fin = clock();
Para mostrar la diferencia:
printf("t: %d\n",fin-comienzo);
Experimentos
Generar arreglos de 10, 100, 10000 y 100000
elementos.
Ordenados de menor a mayor; de mayor a menor;
desordenados.
Tomar tiempos para los 3 algoritmos y sacar
concluciones.
Experimentos: aleatoreidad
Para generar valores “aleatorios” usar la función
rand() que devuelve un entero entre 0 y 215-1.
Pueden utilizar % para restringir los valores.
Por ejemplo, quiero valores entre 0 y 9:
int valor = rand() % 10;
Experimentos: más aleatoreidad
La función rand() utiliza una semilla. Por defecto
es siempre la misma. Para generar nuevas
semillas, antes de usar rand, llamamos a:
srand (time(NULL));
Optimizaciones
Luego de analizar los resultados de los
experimentos, pensar e implementar ideas para
mejorar alguno/s de los algoritmos vistos sin
perder “el concepto” del mismo.
Analizar su corrección y comparar tiempos para
comprobar si optimizaron.
Desafío
Se tienen N pares, donde la primera componente
es un número y la segunda es un color (rojo, azul
y ámbar). Además, se encuentran ordenados
según el número. Dar un algoritmo que los ordene
por color (según rojo-azul-ámbar) pero
manteniendo el orden entre los números de un
mismo color. La cantidad de operaciones del
algoritmo debe ser del orden de N.
¡Justificar TODO!
Desafío: Ejemplo
R=Rojo, Z=Azul, A=Ámbar
(1,Z), (3,R), (4,Z), (6,A), (9,R)
→
(3,R), (9,R), (1,Z), (4,Z), (6,A)
Descargar