Академический Документы
Профессиональный Документы
Культура Документы
ordenar el vector: despus de hacer la particin, slo queda ordenar los dos subvectores. Lo haremos llamando recursivamente al mismo algoritmo de ordenacin, hasta
que lleguemos al caso base en el cual el subvector tiene como mucho un elemento.
Una primera aproximacin al algoritmo propuesto sera la siguiente:
si ini<fin entonces
hacer la particin de v[ini..fin];
{ (para todo k:ini<=k<pos_pivote:v[k]<=v[pos_pivote]) y
(para todo k:pos_pivote<k<=fin:v[k]>=v[pos_pivote]) y
ini<=pos_pivote<=fin }
Curso 2000/01
QUICKSORT(v,ini,pos_pivote-1);
{ v[izq..pos_pivote-1] est ordenado }
QUICKSORT(v,pos_pivote+1,fin)
{ v[pos_pivote+1..fin] est ordenado }
1 Introduccin
El objetivo de esta prctica es el estudio terico y experimental del algoritmo rpido
de ordenacin conocido como Quicksort. Este algoritmo fue propuesto por Hoare en
1962 [Hoare, 62], y es uno de los ms ecientes algoritmos de ordenacin conocidos.
El problema de la ordenacin se puede enunciar de la manera siguiente: dado un
vector
v[1..N ]
de
tipobase,
fsi
fQUICKSORT
tipobase
subvectores
En el caso base, cuando el vector est vaco o tiene un elemento, ste est
trivialmente ordenado.
v[ini..pos_pivote 1]
N.
Supongamos que somos capaces de establecer una particin de este subvector de
siendo
manera que:
vector de partida.
1. Dado un elemento
cin,
v[ini..f in],
v
Al elemento
fin
elementos<=p
se le llama
pivote o
elementos>=p
clave de la particin.
y todos
2 Algoritmo de particin
En este apartado presentamos un algoritmo para la particin en que se basa el
algoritmo Quicksort. A continuacin describimos la estrategia a seguir:
Grcamente:
ini
p,
un elemento de
v[ini..f in].
v[ini].
dos variables
ini + 1,
izq
der
ini
v
fin
elementos<=p
elementos>p
QUICKSORT(v,ini,der-1);
{ v[izq..der-1] est ordenado }
QUICKSORT(v,der+1,fin)
{ v[der+1..fin] est ordenado }
fsi
fQUICKSORT
der izq
ini
v
fin
elementos<=p
elementos>p
A diferencia del algoritmo de ordenacin por fusin, Quicksort puede presentar diversas instancias, debidas al comportamiento de la particin. Se puede dar que la
v[ini]
v[der].
coste(n) =
donde
coste(n ) + coste(n ) + kn,
k ,
si
n > 1, n + n = n 1;
n 1,
El
trmino
Esta recurrencia presenta dos casos extremos, segn como sea el resultado de la
particin del vector:
(n).
3 El algoritmo Quicksort
Cada vez que se realiza la particin, se obtiene un vector vaco y otro de talla
n 1,
de forma que
n = n 1
coste(n) =
si
n = 0,
para cualquier
coste(n 1) + kn,
k ,
si
si
n > 1.
En este caso,
n > 1;
n1
(n2 ).
recurrencia es de la forma:
si
si
n > 1;
n 1.
n potencia de 2, se obtiene
coste(n) = nk + kn log2 n,
y, por tanto, resulta
(n log n).
Supongamos que el
i-sima
i 1, y otro
(i = 1, 2, . . . , n)
n i.
costem (n) =
que incide en los dos aspectos indicados para obtener un algoritmo de ordenacin
n
1
(kn + costem (i 1) + costem (n i))
n
i=1
mejor.
Las dos diferencias ms signicativas entre el algoritmo de Weiss y el algoritmo
1
2costem (i 1)
= kn +
n
i=1
para
n > 1.
Por tanto,
n1
k ,
si
n > 1,
si
n 1.
Naturalmente hay unas elecciones del pivote mejores que otras. Del estudio de costes
del algoritmo Quicksort parece razonable deducir que, cuanto ms equilibrada sea la
subdivisin realizada por particin ms prximo ser el comportamiento temporal
de Quicksort al de su caso mejor, esto es, en las expresiones del coste ms prxima
ser la constante
con
n1
i ln i
i=2
a su cota inferior
k.
como pivote, ya que todos ellos tienen la misma probabilidad de quedar centrados
kr
x ln xdx <
i=2
n2
n2
ln n .
2
4
O(n2 )
(n log n).
particin.
Otra estrategia posible consiste en elegir el elemento central del vector en lugar del
trado (las
(n log n).
2(k
+ k) ln 2,
frente al trmino
kn log2 n
kr n log2 n,
con
k < kr
kr n log2 n,
kr
mediana de los tres, esto es, el elemento intermedio. Este mtodo es, frecuentemente,
mejor que una eleccin puramente aleatoria (ver cuestin 11), ya que escoge como
pivote un elemento que estar con ms probabilidad cerca de la mediana que de
haberse elegido al azar; adems el mtodo elimina el caso malo que se produce
ante una entrada ordenada.
El algoritmo que mostramos a continuacin, debido a Weiss, determina el pivote
que utilizar el algoritmo de particin, para el subvector de
y
f in.
comprendido entre
ini
mediana3
introduce en
ini
der
no se salga de rango.
izq
es menor que el de
la ltima, en la que
que es posible intercambiar un elemento mayor que el pivote con otro que tambin lo
sea (ver cuestin 4). Este intercambio es claramente ineciente y un mtodo mejor
consiste en intercambiar solamente un elemento mayor o igual que el pivote con otro
izq
der
ini
v
fin
<=p elementos>=p
>=p
6 Actividades en el laboratorio
El trabajo en el laboratorio consistir en la implementacin del algoritmo Quicksort,
el estudio experimental de su eciencia y la comparacin con un algoritmo de ordena-
cin de los llamados lentos. Tambin deberis implementar una versin renada de
Quicksort, para comparar su eciencia con la primera versin estudiada. El cdigo
ya implementado que se referencia en los siguientes puntos, lo podris encontrar en
el subdirectorio
prac2
de
/practicas/asignaturas/ad3alum.
6.1 Estudio experimental de la eciencia de Quicksort y comparacin con el algoritmo de Insercin directa
Deberis comparar el algoritmo diseado con un algoritmo de ordenacin de coste
cuadrtico, como es en promedio Insercin directa. Estos algoritmos se os proporcionarn ya implementados. El mtodo a seguir ser el siguiente:
ptimo de recursin, por debajo del cual se ordene el subvector mediante Inser-
cin directa. Una estimacin analtica de dicho umbral necesitara medidas del
Para cada talla estudiada, mediris los tiempos de ejecucin sobre un determinado nmero de instancias de prueba, que se pueden generar de forma aleatoria
con los procedimientos del mdulo
genera
ya implementado. Promediaris el
de esta medida.
La salida del programa debe ser en forma de chero de texto, de forma que en
cada lnea aparezcan los datos correspondientes a una talla
determinar las constantes que aparecen en los costes en ese rango de tallas.
Pero estos tiempos son menores que la precisin del reloj del sistema. Disead
un experimento en el que se puedan obtener tiempos de ejecucin signicativos
para tallas entre 20 y 100, basndose en repetir, para cada talla e instancia, los
n:
El mtodo pro-
puesto deber tener en cuenta que, despus de ejecutar una vez la ordenacin,
el vector queda ya ordenado.
3. Un mtodo ms directo y able para estimar el umbral ptimo de recursin,
consiste en calcularlo experimentalmente. Proponed un experimento que determine un umbral ptimo de recursin, y que al mismo tiempo indique la mejora
de tiempos que se puede obtener para tallas del orden de 5000. Como hiptesis
n tiempo_quicksort tiempo_insercin_directa
Estos datos se pueden procesar con el comando t de ajuste por mnimos
cuadrados del programa "gnuplot". Las curvas ajustadas obtenidas se pueden
representar grcamente con el comando "plot" del mismo programa
n = 25,
n = 2.
n?
Siguiendo el mtodo descrito en el apartado anterior, deberis comparar el comportamiento temporal del algoritmo Quicksort con dos versiones diferentes de la particin.
Para ello, implementaris el algoritmo Quicksort usando como particin la de
Weiss, descrita en la seccin 5.
Para ello,
Deberis comparar los tiempos de ejecucin de esta versin de Quicksort, con los
de la versin del apartado 6.1.
Considerando como entrada un vector en el que todos los elementos son iguales,
comparad el algoritmo original y el propuesto:
(a) Estudiando el nmero de intercambios realizados.
7 Cuestiones
1. Suponiendo que las curvas obtenidas para el comportamiento temporal de Insercin directa y de Quicksort (en sus dos versiones), en las actividades 6.1 y
6.2 se pudiesen extrapolar a grandes tallas, cul sera el tiempo de ejecucin
que se podra esperar en promedio para cada uno de los tres algoritmos, con
5
vectores del orden de 10 elementos?
2. Un estudio para tallas bajas (menores que 50) de Insercin directa y de Quicksort, revela que el mejor comportamiento del segundo se maniesta tempranamente. An as, se puede mejorar su comportamiento buscando un umbral
mediana3
Determinar la mediana de
v[f in].
Ejecutar particin
adems, que
v[0] = ,
como sigue:
v[centro],
en ini y der
y
intercambindola con
en
f in 1.
Suponed,
2, 3, 4, ..., n 1, n, 1,
10
n, n 1, ...4, 3, 2, 1,
f in 1
ini <
que tambin puede afectar al pivote), el algoritmo de particin se puede modicar para que el vector se particione en tres zonas: elementos menores que
y elementos mayores que
similares a las enunciadas, mostr sin embargo que el algoritmo que utilizaba la
elementos iguales a
N + 1,
(10000 instancias para cada talla), demostr que la particin de Dijkstra tena
izq f in.
un centinela en la posicin
derecha se salga de rango.
p.
p,
pos
desv
cin central.
{ v[N+1] = +infinito }
algoritmo particinD(v:vector; ini,fin:entero);
{ Particin de v entre ini y fin, segn Dijkstra }
var izq,der:entero; pivote:tipobase fvar
pivote := v[ini];
izq:=ini+1; der:=fin;
repetir
mientras v[izq]<pivote hacer izq:=izq+1 fmientras;
mientras v[der]>pivote hacer der:=der-1 fmientras;
si izq <= der entonces
intercambiar v[izq] y v[der]
izq:=izq+1; der:=der+1
fsi
hasta der < izq;
intercambiar v[ini] y v[der] { restaura el pivote }
fparticinD
talla
pos(parW)
pos(parD)
5000
10000
15000
20000
25000
30000
35000
40000
45000
50000
2516
4979
7494
9912
12489
15030
17543
19833
22751
25054
2477
4994
7506
10023
12415
14997
17508
20158
22587
24727
desv(parW) desv(parD)
1115
2235
3396
4450
5575
6708
7822
8930
10153
11104
1443
2881
4322
5788
7139
8641
10091
11536
13073
14307
Hay diferencias signicativas entre las posiciones devueltas por ambas particiones?, y entre las medidas de desviacin estndar? Qu deduces de los
resultados?
Referencias
[1] C. A. R. Hoare, Quicksort, Computer Journal, Vol. 5 (4), 1962.
11
12
A Compilacin: makefile
El comando
make
bash_> gnuplot
G N U P L O T
Linux version 3.5 (pre 3.6)
patchlevel beta 347
last modified Mon Jun 22 13:22:33 BST 1998
makefile
por defecto) en el que se denen las dependencias entre los diferentes cheros del
programa. Cada vez que se ejecuta el comando
make se examina
el chero
makefile
para determinar las dependencias entre los distintos cheros que forman el programa.
Con esta informacin, el comando
make recompilar
make
que haya sido modicado o que dependa de alguno que haya sido modicado,
Cuando lo utilices en este modo recuerda que dispones de ayuda on-line accesible
makefile,
tenido es:
modulo.o y prg.c.
make,
prg, que
gcc -o prg
se genera el ejecutable
Automticamente, se ejecuta
Si deseamos dibujar una curva a partir de las dos primeras columnas, con la primera
columna como abcisa, y la segunda como ordenada, entonces la orden apropiada
seria:
signica
using
como UNIX, MS-DOS y VMS. La documentacin sobre este programa incluye, entre
otros textos, un manual de referencia on-line.
13
0.01
0.02
0.02
0.05
0.07
0.08
0.11
En esta orden,
Por ltimo, las columnas donde se indican las rdenes a ejecutar deben comenzar
modo interactivo.
0.07
0.30
0.75
1.37
2.26
3.32
4.51
100
200
300
400
500
600
700
nom = prg
$(nom): modulo.o $(nom).c
gcc -o $(nom) $(nom).c modulo.o
modulo.o: modulo.c
gcc -c modulo.c
gnuplot
gnuplot
suele utilizarse en
gnuplot>
gnuplot>
gnuplot>
gnuplot>
gnuplot
se ilustra en la
gura 1.
El programa
gnuplot
junto de datos. Por ejemplo, si deseamos hacer una ajuste por mnimos cuadrados
de los datos anteriores, podemos hacer:
14
Algorithm A
Algorithm A
5
kk u 1:2
f(x)
f1.dat u 1:2
4.5
4.5
3.5
3.5
3
2.5
Time
Time
3
2.5
2
1.5
1.5
0.5
0.5
0
100
200
300
400
Size
500
gnuplot>
gnuplot>
...
gnuplot>
gnuplot>
gnuplot>
gnuplot>
600
700
gnuplot.
gnuplot.
cl1:=clock;
S;
cl2:= clock;
cl3:=cl2-cl1;
donde
{instruccin 1}
{instruccin 2}
clock().
cl1
cl2
cl3
clock
(de la librera
(en ticks) .
15
700
Una llamada a esta funcin (sin argumentos), devuelve un entero que es propor-
600
cional a la cantidad de tiempo de procesador utilizado por proceso en curso. As, sea
...
500
etc
400
Size
del lenguaje C). En el caso de Pascal, se debe incluir en el espacio del programa
300
200
f(x)=a*x+b
fit f(x) 'f1.dat' via a,b u 1:2
realizar el ajuste es
-0.5
100
time.h
16