Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
+ + =
n
1 l
1) t(n 1) - t(l (1/n) an t(n)
A partir de esta ecuacin puede demostrarse que el quicksort puede ordenar un array de n
elementos distintos en un tiempo promedio en O(n log n). Como adems puede demostrarse
que la constante oculta es en la practica menor que la correspondiente del heapsort o de la
ordenacin por mezcla, si ocasionalmente puede tolerarse un tiempo de ejecucin grande,
ste es el algoritmo de ordenacin preferible entre todos los presentados en estos temas.
Aritmtica con Enteros Grandes
En muchos de los anlisis anteriores hemos supuesto que la suma y la multiplicacin eran
operaciones elementales, es decir, que el tiempo requerido para ejecutar estas operaciones
estaba acotado superiormente por una constante que slo depende de la velocidad de los
circuitos del ordenador que se est usando. Esto slo es razonable si el tamao de los ope-
randos es tal que pueden ser manejados directamente por el hardware.
Pero, para algunas aplicaciones tenemos que considerar enteros muy grandes. La repre-
sentacin de estos nmeros en coma flotante no es til salvo que estemos interesados slo
en el orden de magnitud y en algunas de las ms importantes cifras de nuestros resultados.
Si los resultados tienen que ser calculados exactamente y valen todas las cifras, estamos
obligados a implementar las operaciones aritmticas en el software. Esto fue, por ejemplo,
necesario cuando se calcularon los primeros 134 millones de dgitos de en 1987.
Sean X e Y dos enteros de n dgitos decimales para multiplicar. Recordemos que el algorit-
mo para la multiplicacin de esos dos enteros de n bits (dgitos) que usualmente emplea-
mos, supone calcular n productos parciales de tamao n, y as es un algoritmo O(n
2
), si con-
tamos las multiplicaciones simples y las adicionales como una etapa:
Un enfoque Divide y Vencers para este problema supondra romper X e Y en dos enteros
de tamaos n/2 cada uno (suponiendo por simplicidad que n es par), de la siguiente forma
n
A B
X
C D
n/2 n/2
Y
con lo que quedara
X = A2
n/2
+ B
Y = C2
n/2
+ D
Por ejemplo, si X = 13, entonces
13 = 11 01 n = 4
3 1 .
es decir A = 3 y B = 1, con lo que
13 = A2
n/2
+ B = 32
4/2
+ 1 = (11)
10
2
2
+ (01)
10
As,
XY = AC2
n
+ (AD + BC)2
n/2
+ BD (1)
Si evaluamos XY de este modo directo tenemos que hacer 4 multiplicaciones de enteros de
n/2 bits (AC, AD, BC, BD), tres adiciones de enteros con, a lo sumo, 2n bits, y dos multipli-
caciones por 2
n
y 2
n/2
. Como estas adiciones y multiplicaciones por potencias de dos son
etapas en O(n), podemos escribir la siguiente recurrencia para T(n), el nmero total de ope-
raciones que son necesarias para multiplicar dos enteros de n bits de acuerdo con (1).
T(1) = 1
T(n) = 4T(n/2) + cn (2)
Para resolver la recurrencia, tomando c = 1 sin prdida de generalidad, se deduce que T(n)
es O(n2), o resolvindola por expansin,
En caso de que la frmula (1) se use para multiplicar enteros, la eficiencia asinttica no es
mayor que la del mtodo elemental que generalmente empleamos. Pero recordemos que
para ecuaciones como la (2), tendremos una mejora asinttica si disminuimos el nmero de
subproblemas. Puede resultar increble que podamos hacer eso, pero consideremos la si-
guiente frmula para multiplicar X e Y,
XY = AC2
n
+ [(A-B)(D-C) + AC + BD)]2
n/2
+ BD (3)
de donde es fcil deducir que T(n) es O(n
lg3
), es decir, T(n) es O(n
1,59
). Un algoritmo que
lleva a cabo esta multiplicacin puede ser el siguiente,
funcion mult (X, Y)
s = signo (X) signo (Y)
X = Abs(X); Y = Abs(Y)
si n= 1 entonces
si (X = 1) y (Y = 1) entonces devolver (s)
si no devolver (0)
si no begin
A = n/2 bits de la parte izquierda de X; B = n/2 bits de la parte derecha de X
C = n/2 bits de la parte izquierda de Y; D = n/2 bits de la parte derecha de Y
M1 = mult(A, C, n/2); M2 = mult(A-B, D-C, n/2); M3 = mult(B, D, n/2)
return (s(M12
n/2
+ (M1 + M2 + M3) 2
n/2
+ M3))
Como ejemplo, si
Hemos demostrado por tanto cmo es posible multiplicar dos enteros de n dgitos en un
tiempo O(n
lg3
), es decir, O(n
1,59
). Pero las constantes ocultas son tales que este algoritmo
slo es interesante en la practica cuando n es bastante grande. Una buena implementacin
probablemente no usara la base 2, si no ms bien la mayor base para la que el hardware
permitiera que dos "dgitos" se multiplicaran directamente.
La multiplicacin no es la nica operacin interesante con nmeros enteros. La divisin en-
tera, las operaciones de mdulo y los clculos de partes enteras de una raz cuadrada pue-
den llevarse a cabo todas ellas en un tiempo cuyo orden es el mismo que el requerido para
la multiplicacin. Algunas otras operaciones importantes, tales como el clculo del mximo
comn divisor, de modo inherente pueden ser ms duras de manejar: Aqu no las tratare-
mos.
Multiplicacin de Matrices
Sean A y B dos matrices nxn que queremos multiplicar, y sea C su producto. El algoritmo
clsico se hace directamente a partir de la definicin,
=
=
n
1 k
kj
B
ik
A
ij
C
Cada elemento en C se calcula en un tiempo en (n), supuesto que la adicin y multiplica-
cin de escalares son operaciones elementales. Como hay n
2
elementos que calcular para
obtener C, el producto de A y B puede calcularse en un tiempo en (n
3
). El algoritmo, efecti-
vamente, no seria mas que un anidamiento de tres lazos de longitud n.
Desde el punto de vista del Divide y Vencers la multiplicacin puede hacerse como se
muestra a continuacin:
Como se ve, esta formulacion divide una matriz nxn en dos matrices de tamaos n/2 x n/2,
con lo que se divide el problema en 8 subproblemas de tamaos n/2. As la eficiencia del
mtodo se calculara a partir de la siguiente recurrencia
b si n = 1
T(n) =
8T(n/2) + bn
2
si n> 1
A partir de la cual, es evidente que T(n) sigue siendo O(nP
3P
) y que no ganamos nada con la
aplicacin de esta tecnica de diseo.
Hacia finales de los 60, Strassen mejor este algoritmo. La idea bsica es similar a la usada
en el algoritmo de divide y vencers para multiplicar enteros grandes. Vamos a mostrar pri-
mero que dos matrices 2x2 pueden multiplicarse usando menos de las ocho multiplicacio-
nes escalares aparentemente requeridas por la definicin. Sean,
=
b b
b
b
a a
a a
A
22 21
12
11
B y
22 21
12 11
dos matrices que queremos multiplicar. Consideremos las siguientes operaciones,
)
b
11
b
12
b
22
)(
a
11
a
22
a
21
(
m
1
+ + =
b
11
a
11
m
2
=
b
21
a
12
m
3
=
)
b
12
b
22
)(
a
21
a
11
(
m
4
=
)
b
11
b
12
)(
a
22
a
21
(
m
5
+ =
b
22
)
a
22
a
11
a
21
a
12
(
m
6
+ =
)
b
21
b
12
b
22
b
11
(
a
22
m
7
+ =
Es fcil verificar que el producto pedido de A y B est dado por la siguiente matriz,
+ + + + +
+ + + +
5
m
4
m
2
m
1
m
7
m
4
m
2
m
1
m
6
m
5
m
2
m
1
m
3
m
2
m
Por tanto es posible multiplicar dos matrices 2x2 usando slo siete multiplicaciones escala-
res. A primera vista, este algoritmo no parece muy interesante: usan un gran nmero de
sumas y restas en comparacin con el algoritmo clsico que usa cuatro adiciones, pero
como su eficiencia se calcula a partir de
b si n = 1
T(n) =
7T(n/2) + bn
2
si n> 1
resulta que
y comprobamos como el mtodo de Strassen, efectivamente, rebaja el tiempo de ejecucin
para la multiplicacin de matrices.
Si ahora reemplazamos cada elemento de A y B por una matriz nxn, obtenemos un algorit-
mo que puede multiplicar dos matrices 2nx2n llevando a cabo siete multiplicaciones de ma-
trices nxn, as como un numero de sumas y restas de matrices nxn. Esto es posible porque
el algoritmo bsico no tiene en cuenta la conmutatividad de la multiplicacin escalar. Dado
que las adiciones de matrices pueden ejecutarse mucho ms rpidamente que las multipli-
caciones de matrices, las pocas ms sumas adicionales comparadas con el algoritmo clsi-
co estn ms que compensadas ahorrando una multiplicacin, dado que n es suficiente-
mente grande.
A partir de aqu es fcil demostrar que es posible multiplicar dos matrices nxn en un tiempo
en O(n
2.81
), teniendo en cuenta que cuando el tamao de las matrices no es potencia de 2,
podemos orlarlas para conseguir el tamao apropiado.
Un buen nmero de investigadores han intentado mejorar la constante tal que es posible
multiplicar dos matrices nxn en un tiempo en O(n