tiempo de ejecucion de particiones (quicksort)
TRANSCRIPT
Particiones de método de
ordenamiento quicksort
Oliver a. vilca huayta
COLQUEHUANCA RODRIGO, Linio
091161
2
PARTICIONES DE ORDENAMIENTO QUICKSORT
I. INTRODUCCION
Los computadores se emplean frecuentemente para almacenar y recuperar
grandes volúmenes de datos. Con su velocidad y facilidad de acceso, los
computadores aventajan a otros medios de almacenamiento como el papel
y las microfichas.
Es importante estudiar la forma en que los computadores pueden
almacenar los datos, de modo que su recuperación (búsqueda) sea rápida.
Para lograr esto, y puesto que usualmente los usuarios requieren que los
datos recuperados cuenten con algún orden particular, también es
importante estudiar algoritmos para ordenar los datos almacenados.
Para el caso del ordenamiento, el problema consiste en ordenar el vector
en forma ascendente (de menor a mayor). Si se quisiera trabajar con
ordenamiento descendente los cambios serían mínimos.
En este trabajo se verá el algoritmo de ordenamiento Quicksort
especialmente sus PARTICIONES que pueden ser implementadas de
diferentes formas que difieren entre sí en cuanto a su complejidad y
eficiencia.
3
II. ORDENAMIENTO
Uno de los procedimientos más comunes y útiles en el procesamiento de
datos, es la clasificación u ordenación de los mismos. Se considera ordenar
al proceso de reorganizar un conjunto dado de objetos en una secuencia
determinada. Cuando se analiza un método de ordenación, hay que
determinar cuántas comparaciones e intercambios se realizan para el caso
más favorable, para el caso medio y para el caso más desfavorable.
La colocación en orden de una lista de valores se llama Ordenación. Por
ejemplo, se podría disponer una lista de valores numéricos en orden
ascendente o descendente, o bien una lista de nombres en orden
alfabético. La localización de un elemento de una lista se llama búsqueda.
Tal operación se puede hacer de manera más eficiente después de que la
lista ha sido ordenada.
Existen varios métodos para ordenamiento, clasificados en tres formas:
Intercambio
Selección
Inserción.
En cada familia se distinguen dos versiones: un método simple y directo,
fácil de comprender pero de escasa eficiencia respecto al tiempo de
ejecución, y un método rápido, más sofisticado en su ejecución por la
complejidad de las operaciones a realizar, pero mucho más eficiente en
cuanto a tiempo de ejecución. En general, para arreglos con pocos
elementos, los métodos directos son más eficientes (menor tiempo de
ejecución) mientras que para grandes cantidades de datos se deben
emplear los llamados métodos rápidos.
4
III. QUICKSORT
El método Quicksort basa su estrategia en la idea intuitiva de que es más
fácil ordenar una gran estructura de datos subdividiéndolas en otras más
pequeñas introduciendo un orden relativo entre ellas. En otras palabras, si
dividimos el array a ordenar en dos subarrays de forma que los elementos
del subarray inferior sean más pequeños que los del subarray superior, y
aplicamos el método reiteradamente, al final tendremos el array inicial
totalmente ordenado. Existen además otros métodos conocidos, el de
ordenación por montículo y el de shell.
El algoritmo Quicksort fue desarrollado en 1962 por C.A.R. Hoare, antes de
que se implementaran los primeros lenguajes con capacidad para ejecutar
funciones recursivas.
3.1 Complejidad computacional del Quicksort:
En el mejor de los casos tiene un costo de O(n*log (n)). Que es cuando
el pibote siempre queda al medio del arreglo.
Quicksort Mejor caso
En el peor de los casos tiene un costo de O(n^2). Cuando el pibote
siempre se inclina hacia a un lado, es decir, genera una array de sólo 1
elemento y una segunda con el resto de elementos.
Quicksort peor caso
5
En el caso promedio también tiene un costo de O(n*log (n)). Se
produce cuando el pibote se inclina más hacia un lado y los 2 subarrays
tienen distinto tamaño de elementos.
Quicksort caso promedio
Para calcular el tiempo de ejecución estoy usando la función clock() que
determina el tiempo usado por el procesador. En este caso defino 3
variables ini, final y total. 1ini=clock(); // Antes del quicksort:
2final = clock(); //Después que se ejecuta el quicksort
3total =((double)(final – ini)) /
4CLOCKS_PER_SEC; // El valor retornado por clock()
5debe ser dividido por el valor de la macro CLOCKS_PER_SEC
IV. Partición de método Cormen
Se tiene una array de n elementos, tomamos un valor del array como pivote
(usualmente el ultimo), separamos los elementos menor a este pivote a la
izquierda y los mayores a la derecha, es decir, dividimos el array en 2
subarrays.
6
int PartitionCormen(double A[], int left,int right){
double pivote;
int i,j;
pivote = A[right];
i = left - 1;
for( j=left; j<=right-1; j++){
if(A[j]<pivote){
i++;
swap(A[i],A[j]);
}
}
swap(A[i+1],A[right]);
return i+1;
}
V. Partición de método Cormen modificado
Se tiene una array de n elementos, tomamos un valor del array como pivote
el primero, separamos los elementos menor a este pivote a la izquierda y
los mayores a la derecha, es decir, dividimos el array en 2 subarrays.
int PartitionCormenModificado(double A[], int left,int right){
double pivote;
int i,j;
pivote = A[left];
i = right + 1;
for( j=right; j>=left+1; j--){
if(A[j]<pivote){
i--;
swap(A[i],A[j]);
}
}
swap(A[i-1],A[left]);
return i-1;
}
De manera que el árbol recursivo de ordenación queda más o menos así:
7
VI. Partición de método Brassard
Empezamos creando o generando un array de n elementos, por ejemplo yo
use la función rand() de c++ para generar aleatorios del 1 al 15:
a[] = {8, 1, 5, 14, 4, 15, 12, 6, 2, 11, 10, 7, 9};
izq der
0 1 2 3 4 5 6 7 8 9 10 11 12
8 1 5 14 4 15 12 6 2 11 10 7 9
Tomamos como pivote el 8 y usamos 2 índices que me indiquen la posición
del array: Uno que vaya de izquierda a derecha buscando los elementos
mayores al pivote. a[izq] Y un índice que busque de derecha a izquierda los
elementos menores al pivote. a[der] El índice izquierdo irá aumentando en
1 mientras el array en la posición izquierda sea menor o igual al pivote: 1while ((izq < der) && (array[izq] <= pibote)){
2 izq++;
3}
El índice derecho irá reduciéndose en 1 mientras el array en la posición
derecha sea mayor al pibote. 1while (array[der] > pibote){
2 der--;
3}
Si al final de estas 2 operaciones, el índice izquierdo es menor al derecho
se intercambian las posiciones a[izq] con a[der], usando una variable
temporal: En este caso, en la primer recorrido el índice izquierdo encuentra
al 14 (mayor al pivote) y el índice derecho al 7 (menor al pivote), y se
intercambian los índices:
8 1 5 14 4 15 12 6 2 11 10 7 9
8 1 5 7 4 15 12 6 2 11 10 14 9
Segundo recorrido: El índice izquierdo encuentra al 15 (mayor al pivote) y el
índice derecho al 2 (menor al pivote), se intercambian:
8 1 5 7 4 15 12 6 2 11 10 14 9
8 1 5 7 4 2 12 6 15 11 10 14 9
Tercer recorrido: El índice izquierdo encuentra al 12 (mayor al pivote) y el
índice derecho al 6 (menor al pivote), se intercambian:
8 1 5 7 4 2 12 6 15 11 10 14 9
8 1 5 7 4 2 6 12 15 11 10 14 9
8
Cuando los índices se juntan o se cruzan ponemos el pivote en el lugar que
le corresponde en el array: 1temp = array[der];
2array[der] = array[inicio]; // el pibote está en el inicio del
array
3array[inicio] = temp;
Se intercambian el 8 con el 6 y el array quedaría así:
6 1 5 7 4 2 8 12 15 11 10 14 9
int ParticionBrassard(double A[], int left, int right){
int pivote = A[left];
int izq = left - 1;
int der = right + 1;
while (izq < der){
do{
izq++;
} while (A[izq] < pivote);
do {
der--;
} while (A[der] > pivote);
if (izq < der){
swap(A[izq],A[der]);
}
}
return(der);
}
VII. Partición 4
int Particion4(int *v, int b, int t){
int i;
int pivote, valor_pivote;
int temp;
pivote = b;
valor_pivote = v[pivote];
for (i=b+1; i<=t; i++){
if (v[i] < valor_pivote){
pivote++;
temp=v[i];
v[i]=v[pivote];
v[pivote]=temp;
}
}
temp=v[b];
v[b]=v[pivote];
v[pivote]=temp;
return pivote;
}
9
VIII. Tiempo de ejecución de Particiones #include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/times.h>
#include <sys/stat.h>
#include <math.h>
#include <string.h>
#include <unistd.h> // _SC_CLK_TCK The number of clock ticks per second;
#define Max_ind 32000
struct tms ti, tf, td;
double tsegundos,tsegundos2;
clock_t ta,tb,tc;
double Temp[Max_ind];
double tmp;
void IniT(){
ta=times(&ti);
printf("INI %f %f\n", (double)(ti.tms_utime),(double)ta );
}
void FinT(){
tb=times(&tf);
printf("FIN %f %f\n", (double)(tf.tms_utime),(double)tb );
td.tms_utime = tf.tms_utime-ti.tms_utime;
tc = tb - ta;
tsegundos =((double)(td.tms_utime))/sysconf(_SC_CLK_TCK);
tsegundos2 =((double)(tc))/sysconf(_SC_CLK_TCK);
printf("Pasaron = %lf %lf %lf \n",(double)tc, tsegundos, tsegundos2);
}
int PartitionCormen(double A[], int left,int right){
double pivote,temp;
int i,j;
pivote = A[right];
i = left - 1;
for( j=left; j<=right-1; j++){
if(A[j]<pivote){
i++;
temp=A[i];
A[i]=A[j];
A[j]=temp;
}
}
temp=A[i-1];
A[i+1]=A[right];
A[right]=temp;
return i+1;
}
int PartitionCormenMod(double A[], int left,int right){
double pivote,temp;
int i,j;
pivote = A[left];
i = right + 1;
for( j=right; j>=left+1; j--){
if(A[j]<pivote){
i--;
temp=A[i];
A[i]=A[j];
10
A[j]=temp;
}
}
temp=A[i-1];
A[i-1]=A[left];
A[left]=temp;
return i-1;
}
int PartitionBrassard(double A[], int left, int right){
float temp;
int pivote = A[left];
int izq = left - 1;
int der = right + 1;
while (izq < der){
do{
izq++;
} while (A[izq] < pivote);
do {
der--;
} while (A[der] > pivote);
if (izq < der){
temp=A[izq];
A[der]=A[izq];
A[izq]=temp;
}
}
return(der);
}
int Partition4(int *v, int b, int t){
int i;
int pivote, valor_pivote;
int temp;
pivote = b;
valor_pivote = v[pivote];
for (i=b+1; i<=t; i++){
if (v[i] < valor_pivote){
pivote++;
temp=v[i];
v[i]=v[pivote];
v[pivote]=temp;
}
}
temp=v[b];
v[b]=v[pivote];
v[pivote]=temp;
return pivote;
}
main(int argc, char *argv[]){
int Nro_pruebas = 40;
int i,j,k,l;
double V1[Max_ind],V2[Max_ind],V3[Max_ind],V4[Max_ind],V5[Max_ind];
double V6[Max_ind],V7[Max_ind],V8[Max_ind],V9[Max_ind],V10[Max_ind];
double V11[Max_ind],V12[Max_ind],V13[Max_ind],V14[Max_ind],V15[Max_ind];
double V16[Max_ind],V17[Max_ind],V18[Max_ind],V19[Max_ind],V20[Max_ind];
double C1[Max_ind],C2[Max_ind],C3[Max_ind],C4[Max_ind],C5[Max_ind];
double C6[Max_ind],C7[Max_ind],C8[Max_ind],C9[Max_ind],C10[Max_ind];
11
double C11[Max_ind],C12[Max_ind],C13[Max_ind],C14[Max_ind],C15[Max_ind];
double C16[Max_ind],C17[Max_ind],C18[Max_ind],C19[Max_ind],C20[Max_ind];
for(i=0;i<Max_ind;i++){
V1[i]=random();V2[i]=random();V3[i]=random();V4[i]=random();
V5[i]=random();V6[i]=random();V7[i]=random();V8[i]=random();
V9[i]=random();V10[i]=random();V11[i]=random();V12[i]=random();
V13[i]=random();V14[i]=random();V15[i]=random();V16[i]=random();
V17[i]=random();V18[i]=random();V19[i]=random();V20[i]=random();
}
for(j=0;j<Max_ind;j++){
C1[j]=V1[j];C2[j]=V2[j];C3[j]=V3[j];C4[j]=V4[j];
C5[j]=V5[j];C6[j]=V6[j];C7[j]=V7[j];C8[j]=V8[j];
C9[j]=V9[j];C10[j]=V10[j];C11[j]=V11[j];C12[j]=V12[j];
C13[j]=V13[j];C14[j]=V14[j];C15[j]=V15[j];C16[j]=V16[j];
C17[j]=V17[j];C18[j]=V18[j];C19[j]=V19[j];C20[j]=V20[j];
}
IniT();
for(i=0;i<Nro_pruebas;i++){
k=PartitionCormen(C1,0,Max_ind-1);k=PartitionCormen(C2,0,Max_ind-1);
k=PartitionCormen(C3,0,Max_ind-1);k=PartitionCormen(C4,0,Max_ind-1);
k=PartitionCormen(C5,0,Max_ind-1);k=PartitionCormen(C6,0,Max_ind-1);
k=PartitionCormen(C7,0,Max_ind-1);k=PartitionCormen(C8,0,Max_ind-1);
k=PartitionCormen(C9,0,Max_ind-1);k=PartitionCormen(C10,0,Max_ind-
1);
k=PartitionCormen(C11,0,Max_ind-1);k=PartitionCormen(C12,0,Max_ind-
1);
k=PartitionCormen(C13,0,Max_ind-1);k=PartitionCormen(C14,0,Max_ind-
1);
k=PartitionCormen(C15,0,Max_ind-1);k=PartitionCormen(C16,0,Max_ind-
1);
k=PartitionCormen(C17,0,Max_ind-1);k=PartitionCormen(C18,0,Max_ind-
1);
k=PartitionCormen(C19,0,Max_ind-1);k=PartitionCormen(C20,0,Max_ind-
1);
}
FinT();
printf("\n");
for(j=0;j<Max_ind;j++){
V1[j]=C1[j];V2[j]=C2[j];V3[j]=C3[j];V4[j]=C4[j];
V5[j]=C5[j];V6[j]=C6[j];V7[j]=C7[j];V8[j]=C8[j];
V9[j]=C9[j];V10[j]=C10[j];V11[j]=C11[j];V12[j]=C12[j];
V13[j]=C13[j];V14[j]=C14[j];V15[j]=C15[j];V16[j]=C16[j];
V17[j]=C17[j];V18[j]=C18[j];V19[j]=C19[j];V20[j]=C20[j];
}
IniT();
for(i=0;i<Nro_pruebas;i++){
k=PartitionCormenMod(C1,0,Max_ind-
1);k=PartitionCormenMod(C2,0,Max_ind-1);
k=PartitionCormenMod(C3,0,Max_ind-
1);k=PartitionCormenMod(C4,0,Max_ind-1);
k=PartitionCormenMod(C5,0,Max_ind-
1);k=PartitionCormenMod(C6,0,Max_ind-1);
12
k=PartitionCormenMod(C7,0,Max_ind-
1);k=PartitionCormenMod(C8,0,Max_ind-1);
k=PartitionCormenMod(C9,0,Max_ind-
1);k=PartitionCormenMod(C10,0,Max_ind-1);
k=PartitionCormenMod(C11,0,Max_ind-
1);k=PartitionCormenMod(C12,0,Max_ind-1);
k=PartitionCormenMod(C13,0,Max_ind-
1);k=PartitionCormenMod(C14,0,Max_ind-1);
k=PartitionCormenMod(C15,0,Max_ind-
1);k=PartitionCormenMod(C16,0,Max_ind-1);
k=PartitionCormenMod(C17,0,Max_ind-
1);k=PartitionCormenMod(C18,0,Max_ind-1);
k=PartitionCormenMod(C19,0,Max_ind-
1);k=PartitionCormenMod(C20,0,Max_ind-1);
}
FinT();
printf("\n");
for(j=0;j<Max_ind;j++){
V1[j]=C1[j];V2[j]=C2[j];V3[j]=C3[j];V4[j]=C4[j];
V5[j]=C5[j];V6[j]=C6[j];V7[j]=C7[j];V8[j]=C8[j];
V9[j]=C9[j];V10[j]=C10[j];V11[j]=C11[j];V12[j]=C12[j];
V13[j]=C13[j];V14[j]=C14[j];V15[j]=C15[j];V16[j]=C16[j];
V17[j]=C17[j];V18[j]=C18[j];V19[j]=C19[j];V20[j]=C20[j];
}
IniT();
for(i=0;i<Nro_pruebas;i++){
k=PartitionBrassard(C1,0,Max_ind-
1);k=PartitionBrassard(C2,0,Max_ind-1);
k=PartitionBrassard(C3,0,Max_ind-
1);k=PartitionBrassard(C4,0,Max_ind-1);
k=PartitionBrassard(C5,0,Max_ind-
1);k=PartitionBrassard(C6,0,Max_ind-1);
k=PartitionBrassard(C7,0,Max_ind-
1);k=PartitionBrassard(C8,0,Max_ind-1);
k=PartitionBrassard(C9,0,Max_ind-
1);k=PartitionBrassard(C10,0,Max_ind-1);
k=PartitionBrassard(C11,0,Max_ind-
1);k=PartitionBrassard(C12,0,Max_ind-1);
k=PartitionBrassard(C13,0,Max_ind-
1);k=PartitionBrassard(C14,0,Max_ind-1);
k=PartitionBrassard(C15,0,Max_ind-
1);k=PartitionBrassard(C16,0,Max_ind-1);
k=PartitionBrassard(C17,0,Max_ind-
1);k=PartitionBrassard(C18,0,Max_ind-1);
k=PartitionBrassard(C19,0,Max_ind-
1);k=PartitionBrassard(C20,0,Max_ind-1);
}
FinT();
printf("\n");
for(j=0;j<Max_ind;j++){
V1[j]=C1[j];V2[j]=C2[j];V3[j]=C3[j];V4[j]=C4[j];
V5[j]=C5[j];V6[j]=C6[j];V7[j]=C7[j];V8[j]=C8[j];
V9[j]=C9[j];V10[j]=C10[j];V11[j]=C11[j];V12[j]=C12[j];
13
V13[j]=C13[j];V14[j]=C14[j];V15[j]=C15[j];V16[j]=C16[j];
V17[j]=C17[j];V18[j]=C18[j];V19[j]=C19[j];V20[j]=C20[j];
}
IniT();
for(i=0;i<Nro_pruebas;i++){
k=Partition4(C1,0,Max_ind-1);k=Partition4(C2,0,Max_ind-1);
k=Partition4(C3,0,Max_ind-1);k=Partition4(C4,0,Max_ind-1);
k=Partition4(C5,0,Max_ind-1);k=Partition4(C6,0,Max_ind-1);
k=Partition4(C7,0,Max_ind-1);k=Partition4(C8,0,Max_ind-1);
k=Partition4(C9,0,Max_ind-1);k=Partition4(C10,0,Max_ind-1);
k=Partition4(C11,0,Max_ind-1);k=Partition4(C12,0,Max_ind-1);
k=Partition4(C13,0,Max_ind-1);k=Partition4(C14,0,Max_ind-1);
k=Partition4(C15,0,Max_ind-1);k=Partition4(C16,0,Max_ind-1);
k=Partition4(C17,0,Max_ind-1);k=Partition4(C18,0,Max_ind-1);
k=Partition4(C19,0,Max_ind-1);k=Partition4(C20,0,Max_ind-1);
}
FinT();
}
Prueba1
Prueba2
14
Prueba3
15
IX. Conclusión
X. BIBLIOGRAFIA Fundamentos de Algoritmia-Brassard
McGraw.Hill.Introduction.To.Algorithms.segunda.Edicion
http://es.wikipedia.org/wiki/Quicksort
http://c.conclase.net/
0
5
10
15
20
25
30
35
Cormen CormenMod Brassard Particion4
Prueba 1
Prueba 2
Prueba 3
16
PARTICIONES DE ORDENAMIENTO QUICKSORT ........................................................... 2
I. INTRODUCCION ......................................................................................................... 2
II. ORDENAMIENTO ....................................................................................................... 3
III. QUICKSORT ........................................................................................................... 4
3.1 Complejidad computacional del Quicksort: ........................................................ 4
IV. Partición de método Cormen ............................................................................... 5
V. Partición de método Cormen modificado .............................................................. 6
VI. Partición de método Brassard ............................................................................. 7
VII. Partición 4 ............................................................................................................... 8
VIII. Tiempo de ejecución de Particiones ................................................................... 9
IX. Conclusión............................................................................................................ 15
X. BIBLIOGRAFIA ......................................................................................................... 15