Está en la página 1de 7

Sistemas y Algoritmos 2 Segundo Semestre, 2015

Clase 3: Ordenamiento IV
Instructor: Diego Villamizar

3.1. Costo

En términos de programación y de manejo de algoritmos hay dos cosas esenciales.

Correctitud
Como es bien sabido un algoritmo son una serie de pasos conectados entre sí, que dada
una entrada producen una salida acorde a la solución de algún problema particular. Si
el algoritmo no resuelve el problema, simplemente no es considerado como tal.

Eciencia
Hay ciertos requerimientos que un algoritmo debe cumplir dado el problema que quiere
resolver. Si, por ejemplo, usted crea un algoritmo que resuelve un problema, pero el
algoritmo requiere mucha más memoria de la cual usted dispone, no podrá correr el
algoritmo y eso hará que no tenga sentido el mismo. Así mismo, si un algoritmo es
correcto pero demora mucho más tiempo del que se dispone, no tiene sentido correrlo.
Eso lleva a que sea útil entender y clasicar, en términos de requerimientos, lo que
cuesta un algoritmo.

En esta clase tendremos más en cuenta el tiempo que el espacio y cualquier otro requer-
imiento de eciencia, para eso supondremos que las operaciones elementales dentro de un
código cuestan una constante de tiempo cualquiera y será representada como comentario en
cada linea que se necesite en el código.
Veamos el siguiente código.
1 for i in range (0,n): # c_1
2 for j in range (0,n): #c_2
3 print " * ", #c_3
4 print "" #c_4
o su correspondiente en Java (sin la construcción usual de main y clase)
1 for(int i = 0;i<n;i++, System .out. println (""))//#c_1 c_2
2 for(int j = 0;j<n;j++) System .out. print (" * ");//#c_3 c_4

1
2 Clase 3: Ordenamiento IV

Luego si quisiera ver cuánto se tarda el algoritmo en términos de los tiempos constantes y
la entrada n, tendría que resolver lo siguiente
n−1
X n−1
X
(c1 + (c2 + c3 ) + c4 ).
i=0 j=0

Donde la primera sumatoria representa el recorrido del primer for y respectivamente la


segunda. Haciendo las cuentas se llega a
n−1
X n−1
X n−1
X
(c1 + (c2 + c3 ) + c4 ) = (c1 + n(c2 + c3 ) + c4 ) = n(c1 + c4 ) + n2 (c2 + c3 ).
i=0 j=0 i=0

Lo que dice que ese algoritmo corre proporcional a un tiempo cuadrático(n2 ) sobre la variable
n que le entre.
Consideremos ahora el siguiente código:
1 for i in range (0,n): # c_1
2 for j in range (0,i): #c_2
3 print " * ", #c_3
4 print "" #c_4
o su correspondiente en Java (sin la construcción usual de main y clase)
1 for(int i = 0;i<n;i++, System .out. println (""))//#c_1 c_2
2 for(int j = 0;j<i;j++) System .out. print (" * ");//#c_3 c_4
Si se hace el mismo análisis, se llegaría a una expresión como
n−1
X i−1
X
(c1 + (c2 + c3 ) + c4 ),
i=0 j=0

que al resolverla termina en  


n
n(c1 + c4 ) + (c2 + c3 ) .
2
Lo que quiere decir que el algoritmo crece proporcionalmente al combinatorio.

3.2. Algoritmo de Inserción

Considere un mazo de cartas donde, cada carta, tiene en su supercie un elemento y en


conjunto hacen parte de un conjunto linealmente ordenado.
El objetivo es ordenar esas cartas en su forma creciente. El algoritmo de inserción se basa
en la idea intuitiva en que uno va insertando una a una las cartas de una mano(roja) en la
otra (verde) de forma en que queden ordenadas las cartas que lleva. Veamos un ejemplo:
Algoritmo de Inserción 3

4 4
2 2
3 3
5 5
3 3

Figura 3.1: La echa negra es el apuntador a la primera carta en la mano roja, de desorde-
nadas. La linea roja y la verde representan las cartas en su respectivas manos. Se ven los dos
primeros pasos en las dos primeras cartas, ya ordenadas

4 4
2 2
3 5
5 3
3 3

Figura 3.2: Se ve el movimiento de la carta a la segunda posición. La linea puntada representa


el movimiento de cartas.
4 Clase 3: Ordenamiento IV

4 4
2 5
5 3
3 3
3 2

4 5
5 4
3 3
3 3
2 2

De esa forma, es fácil notar que tenermos que llevar un apuntador para la echa negra,
que sea la carta a poner en la mano verde. Ese puntero, como va secuencial, lo podemos
llevar con la estructura de control for. Además de eso, necesitamos una estructura de control
que nos permita hacer el movimiento de las cartas, que se hace mientras que el apuntador
sea menor que la carta en otro apuntador en la mano verde.
1 X = [34 ,2 ,4 ,3 ,6 ,3 ,56 ,6 ,7 ,4 ,5 ,7 ,4]
2 print X
3 for i in range (1, len(X)): #apuntador negro
4 k = X[i]
5 j = i−1;
6 while j>−1 and k<X[j]: #i r corriendo l a s cartas en la mano verde .
7 X[j+1]=X[j]
8 j−=1
9 X[j+1]=k #poner la carta apuntada
10 print X

Ahora que se tiene el algoritmo, es interesante ver qué costo en tiempo tiene. Para eso
Algoritmo de Inserción 5

analizaremos 3 casos. El mejor, el peor y el promedio (todos en Sn , bajo la función es-


tandarización que respeta el orden).
Mejor caso.
Sin duda el mejor caso es en el que no se hace ningún intercambio. Luego en el que el
arreglo ya está, como tal, ordenado(i.e., Id ∈ Sn ). Note que como nunca entra al while,
el costo es de una constante c por el tamaño de la permutación, luego c ∗ n.
Peor caso.
El peor caso es cuando se entra siempre al while, esto sucede siempre que X[i] >
X[j] con i < j , lo que implica que es la permutación n(n − 1) · · · 21 ∈ Sn . Por un
razonamiento igual a un código pasado, el costo sería c ∗ n2 (Por qué?).
Caso esperado.
Denición Dada una permutación σ ∈ Sn , se dene el conjunto de inversiones de la
misma como
Inv(σ) = {() : i < j ∧ σi > σj }.

Ejemplo 3.1 Calculemos las inversiones en Sn


Inv(123) = ∅, Inv(132) = {(2, 3)}, Inv(213) = {(1, 2)}, Inv(231) = {(1, 3), (2, 3)},

Inv(312) = {(1, 2), (1, 3)}, Inv(321) = {(1, 2), (1, 3), (2, 3)}.

De los casos anteriores, no es difícil darse cuenta de la siguiente proposición.

Proposición 3.2 Sea X un arreglo, la cantidad de veces que entra el algoritmo de


inserción en el while es |Inv(St(X))|.
ˆ

Dada esa estadística, podemos preguntarnos cuál es el valor esperado de las veces que
el algoritmo entrará en el while dado un arreglo de longitud n.
que es lo mismo que denir una distribución en el conjunto de permutaciones (i.e., Sn ),
para
P eso denimos Ai,n = |{σ ∈ Sn : |Inv(σ)| = i}|,luego por el principio de la suma
i∈[(n)] Ai,n = 1. Luego el valor esperado sería
1
n! 2

(n2 )
X
Ai,n ∗ i.
i=0
6 Clase 3: Ordenamiento IV

Ejercicios para el taller.


1. Qué costo, en términos de {ci }i∈[k+1] y de n tendrá el siguiente código?
1 for a_1 in range (0,n):#c_1
2 for a_2 in range (0, a_1 ):#c_2
3 for a_3 in range (0, a_2 ):#c_3
4 ...
5 for a_k in range (0,a_{k−1}):#c_k
6 print " * " # c_{k+1}

2. Cree un algoritmo que, dada una permutación σ ∈ Sn , encuentre Inv(σ).


3. Cree un algoritmo que, dados números n, i, calcule Ai,n .
Bibliografía
[1] M. Aigner, A course in Enumeration, GTM (2007).
[2] N. Biggs, Discrete Mathematics, Oxford Press (2009).
[3] T. Cormen, C. Leiserson, R. Rivest, C. Stein, Introduction to Algorithms, 3rd Edition,
MIT Press (2009).
[4] D. Knuth, The art of computer programming, Addison-Wesley (1968).
[5] C. Papadimitriou, K. Steiglitz, Combinatorial Optimization, Dover (1998).
[6] R. Sedgewick, K. Wayne, Algorithms, 3rd Edition, Addison-Wesley (2011).
[7] D. Welsh, Matroid Theory, Dover (2005).

También podría gustarte