Está en la página 1de 14

4

Anlisis de Algoritmos y Estructura de Datos




Jacqueline Khler C.
1 ANLISIS DE ALGORITMOS

1.1 COMPLEJIDAD DE ALGORITMOS

Un algoritmo es una secuencia de instrucciones que se debe seguir para resolver un determinado
problema, que adems garantiza la obtencin de una respuesta al terminar. Debe ser preciso y
detallado, es decir, no usa intuicin ni creatividad, ni tampoco requiere de decisiones subjetivas. Los
algoritmos se remontan hasta muy atrs en la historia. El ms antiguo conocido, el algoritmo para
determinar el mximo comn divisor de dos nmeros, se atribuye a Euclides.

En el prrafo anterior se mencion que los algoritmos garantizan la obtencin de una respuesta al
terminar de seguir sus pasos para resolver un problema dado. Esto se traduce, entonces, en que los
algoritmos ofrecen una solucin general para un problema dado que est acotado a un dominio
determinado. Se denomina instancia de un problema a un caso particular de ste, y un algoritmo debe
funcionar correctamente para todas las instancias del problema, sin considerar las restricciones propias
de la implementacin: capacidad de memoria, rangos de valores, etc.

En muchas ocasiones ocurre que un problema puede ser resuelto por muchos algoritmos. Entonces
surge el problema de escoger cul de ellos utilizar. Si solo se requiere resolver unas pocas instancias
sencillas del problema, no importa cul sea el algoritmo seleccionado. No obstante, si la instancia a
resolver es muy difcil o bien se requiere resolver muchas instancias, es importante escoger el mejor.
Existen dos enfoques para determinar cul algoritmo escoger:
Emprico (a posteriori): consiste en programar todas las alternativas, probarlas con diversas
instancias y comparar su desempeo. Por supuesto, este enfoque resulta muy poco prctico.
Terico (a priori): consiste en determinar matemticamente cuntos recursos se necesitan para cada
algoritmo. Esta tarea se denomina estudio de la complejidad y consiste en la obtencin de una
expresin matemtica que refleja el comportamiento del algoritmo en funcin de los datos de
entrada.

La complejidad o eficiencia de un algoritmo debe ser estudiada con respecto a algn recurso crtico: el
tiempo de computacin (cunto tiempo toma ejecutar la implementacin de un algoritmo), la cantidad
de espacio necesaria para almacenar los datos requeridos, la cantidad de procesadores necesarios, etc.
En general, la complejidad de tiempo es mayor que la complejidad de espacio ya que cualquier
informacin almacenada debe ser leda o guardada en algn instante. Por ese motivo, generalmente se
trabaja con la complejidad de tiempo.

Se seal anteriormente la complejidad de un algoritmo se determina en funcin de los datos de
entrada. En efecto, se debe buscar una expresin matemtica en funcin del tamao de estos datos.
Formalmente, el tamao de un dato se refiere a la cantidad de bits necesarios para su almacenamiento.
No obstante, esa nocin depende de la implementacin del algoritmo, por lo que no es adecuada para
una evaluacin terica. En consecuencia, se considera simplemente que el tamao es un nmero natural
que indica la cantidad de elementos de un objeto, por ejemplo, la cantidad de elementos de un arreglo o
bien el nmero de nodos y aristas de un grafo.

El comportamiento real de un algoritmo depende de muchos factores propios de su implementacin.
Entre ellos se encuentran las restricciones de arquitectura, es decir, el compilador o intrprete utilizado,
5
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.
el lenguaje de programacin y la mquina en que se ejecute. Tambin influyen algunos factores
humanos, como la forma de escribir el cdigo fuente o las estructuras de datos seleccionadas. En
consecuencia, se hace necesario evaluar el comportamiento del algoritmo en forma independiente de
factores humanos y de mquina.

Ahora surge el problema de determinar la eficiencia de un algoritmo de algn modo estndar. Si el
tiempo de ejecucin depende de la implementacin, no es posible medirlo en segundos, pues no todos
los computadores tardan lo mismo en ejecutar un mismo programa. Este problema puede ser resuelto
gracias al principio de invariancia, que indica que dos implementaciones diferentes de un mismo
algoritmo no difieren en su eficiencia ms que en una constante multiplicativa . As, es posible
expresar la complejidad en trminos del tamao de la entrada como . Ms adelante, con el
estudio de la notacin asinttica, se ver que es posible ignorar la constante y decir, simplemente, que
el algoritmo est en el orden de . En algunos casos, la complejidad recibe un nombre especial. Un
algoritmo es:
Lineal si est en el orden de .
Cuadrtico se est en el orden de

.
Polinomial si est en el orden de

.
Exponencial si est en el orden de

.

Otro aspecto importante al evaluar la complejidad de un algoritmo es que frecuentemente los
problemas tienen diversas instancias de un mismo tamao y el tiempo que tarda un algoritmo en
resolverlas puede variar mucho. En consecuencia, no tiene sentido evaluar la eficiencia de un algoritmo
solo en funcin del tamao de la instancia, pues el algoritmo debe funcionar correctamente para todas
las instancias. En el mejor escenario, el tiempo requerido suele ser poco. Sin embargo, si el tiempo de
respuesta es crtico, es necesario considerar el tiempo requerido para el peor escenario posible.
Tambin puede ser til analizar el caso promedio, aunque resulta muy difcil pues esto requiere conocer
a priori la distribucin de los casos a resolver. En consecuencia, el anlisis de la complejidad del caso
medio no ser considerado en este curso.


1.1.1 LA BSQUEDA DE LA EFICIENCIA

Es sabido que los computadores son cada vez ms rpidos. Esto podra conducir a la idea de que la
eficiencia de los algoritmos es cada vez menos importante. Sin embargo, no necesariamente es as.
Suponga que se tiene un algoritmo exponencial

para resolver un problema y una mquina

que
tarda 10

segundos en resolver una instancia de tamao :


Para una instancia de tamao 10 se necesitan 0,1024 segundos.
Para otra de tamao 20, 104,8576 segundos (cerca de 2 minutos).
Para una tercera de tamao 38, algo ms de 318 das.

Si

es reemplazada por una mquina

que tarda 10

segundos en resolver una instancia de


tamao , se tiene que:
Para una instancia de tamao 10 se necesitan 0,001024 segundos.
Para la de tamao 20, 1,048576 segundos.
Para la de tamao 38, algo ms de 76 horas.

6
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.
Considere ahora un algoritmo cbico

y suponga que

tarda 10

segundos en resolver una


instancia de tamao :
Para una instancia de tamao 10 se necesitan 10 segundos.
Para la de tamao 20, 80 segundos.
Para la de tamao 38, algo ms de 9 minutos.

Si ahora se evala el algoritmo

en la mquina

, que tarda 10

segundos en resolver una


instancia de tamao , se tiene que:
Para una instancia de tamao 10 se necesitan 0,1 segundos.
Para la de tamao 20, 0,8 segundos.
Para la de tamao 38, 5,4872 segundos.

La figura 1.1 refleja el anlisis anterior.



FIGURA 1.1: Comparacin del desempeo de dos algoritmos.

Se puede concluir que para instancias pequeas es mejor el algoritmo original

, pero para instancias


grandes, el algoritmo cbico (

) es muchsimo mejor. En ocasiones, dependiendo del tipo de


instancias con las que se requiera trabajar, resulta adecuado proponer un tercer algoritmo que los
combine a ambos.


1.1.2 CLCULO DE LA COMPLEJIDAD

Se denomina operacin elemental o instruccin bsica a una instruccin cuyo tiempo de ejecucin est
acotado superiormente por una constante que solo depende de la implementacin usada (la mquina
que ejecute el programa, el lenguaje de programacin empleado, etc.), por lo que se asume que tienen
un tiempo de ejecucin unitario. El ejemplo 1.1 muestra una justificacin para esta simplificacin.

Ejemplo 1.1:
Considere que un algoritmo requiere efectuar operaciones de adicin, operaciones de
multiplicacin y operaciones de asignacin. Adems, se sabe que una suma nunca requiere
ms de

microsegundos, una multiplicacin nunca requiere ms de

microsegundos y una
asignacin nunca requiere ms de

segundos.
7
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.
Por la definicin anterior se tiene que el tiempo de ejecucin del algoritmo est acotado por

. Esto quiere decir que max

+ +. Pero se sabe
que el tiempo requerido por cada operacin elemental no es importante pues se descartan las
constantes, por lo que se asume que pueden ser ejecutadas en tiempo unitario. Por tanto, se
puede afirmar que el algoritmo en cuestin es del orden de + +.

Formalizando la idea del ejemplo 1.1, se tiene que, para un algoritmo dado, la complejidad de tiempo
queda determinada por el tiempo de ejecucin de cada instruccin bsica y el nmero de veces que se
ejecuta esa instruccin.

Sea:
: un algoritmo para resolver un problema dado,

, ,

: una secuencia de instrucciones bsicas del algoritmo ,


: el tiempo de ejecucin de la instruccin

, 1 ,

: el nmero de veces que se ejecuta

, 1 .

La complejidad de tiempo del algoritmo A est dada por:



Como todas las instrucciones bsicas requieren un tiempo constante, se puede suponer que esos
tiempos son iguales, es decir:

= =

= 1. Luego, se tiene:



Es decir, la complejidad de tiempo corresponde al nmero total de instrucciones bsicas necesarias de
ejecutar para una computacin completa del algoritmo.

Ejemplo 1.2:
El problema de la suma de matrices consiste en, dadas ,

, calcular = +

. Podemos resolver este problema usando el siguiente algoritmo.



Dadas ,

:
Para 1 a hacer:
Para 1 a hacer:


Devolver .

Complejidad:
Aqu se observan dos ciclos Para y una asignacin, que es una instruccin bsica.
El primer ciclo Para se ejecuta veces.
Adems, el ciclo Para anidado dentro del primero se ejecuta veces.
8
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.
Luego, la instruccin bsica anidada en los dos ciclos se ejecuta veces (por el segundo
ciclo) por las veces que se ejecuta el primer ciclo.
La asignacin tiene lugar en un tiempo .

La complejidad de tiempo del algoritmo dado queda definida por:

=

Asumiendo = 1:

=

En particular, si = :



Del ejemplo 1.2 se desprenden las siguientes conclusiones, que se resumen en la figura 1.2:
Las instrucciones simples se ejecutan en un tiempo constante que se aproxima a 1.
Las instrucciones condicionales se consideran como una instruccin simple.
Los ciclos iterativos se ejecutan la cantidad de veces que tienen establecido repetirse. Esto es, si el
ciclo Para repite sus instrucciones desde 1 a , su tiempo es .
Los ciclos iterativos anidados se ejecutan en su tiempo correspondiente, multiplicado por las veces
que se repita el ciclo en el cual estn anidados.



FIGURA 1.2: Resumen para el clculo de complejidad computacional.

Ejemplo 1.3:
Problema: buscar un valor en un arreglo de enteros.
Entrada: el arreglo A y el valor c.
Salida: la posicin del valor en el arreglo.

Buscar(A, c):
j 1
Mientras A[j] < c y j < n hacer:
j j+1
Si A[j] = c hacer:
devolver j
9
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.
En otro caso hacer:
devolver 0

Para determinar el tiempo de ejecucin del algoritmo, es necesario calcular la cantidad de
operaciones elementales que se realizan:
En la lnea 1 se ejecuta 1 operacin (asignacin).
En la lnea 2 se ejecuta la condicin del ciclo, conformada por un total de 4 operaciones:
dos comparaciones, un acceso al arreglo y un y lgico.
La lnea 3 cuenta con dos operaciones: un incremento y una asignacin.
La lnea 4 est conformada por una comparacin y un acceso al vector arreglo (2
operaciones).
La lnea 5 contiene una operacin de retorno si la condicin se cumple.
Anlogamente, la lnea 7 contiene una operacin de retorno si la condicin no se cumple.

En el mejor caso, solo se ejecuta la lnea 1 y la primera mitad de la condicin de la lnea 2, es
decir, solo 2 operaciones. A continuacin se ejecutan las lneas 5 a 7. As, para el mejor caso:

= 1 +2 +3 = 6

En el peor caso, se ejecuta la lnea 1 y el ciclo se repite hasta que se cumple la segunda
condicin. Cada iteracin del ciclo est dada por las instrucciones de las lneas 2 y 3 ms una
ejecucin adicional de la lnea 2 (para salir del ciclo). La ejecucin termina con la lnea 7. As,
para el peor caso se tiene que:

= 1 +4 +2

+4 +2 +1 = 6 +2


1.2 MODELO DE MQUINA

Se utiliza el modelo RAM (Mquina de Acceso Aleaotrio, Random Access Machine en ingls),
definido por el esquema de la figura 1.3.

Se denomina entrada a los datos del problema que se entregan al algoritmo y salida a la respuesta
entregada por ste.




FIGURA 1.3: Modelo RAM.
10
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.
El anlisis de complejidad de un algoritmo se hace respecto al mejor caso (sus entradas ms favorables
en cuanto al tiempo requerido), al peor caso (las entradas menos favorables) y al caso medio.
Antes de seguir adelante, es necesario conocer algunas definiciones:
Paso: tiempo de una instruccin bsica.
Complejidad local: nmero total de pasos de la ejecucin completa del algoritmo para una entrada
dada.
Complejidad asinttica: menor cota superior de la complejidad local.
Complejidad del mejor caso: tiempo para ejecutar el algoritmo con la entrada ms favorable.
Complejidad del peor caso: tiempo en ejecutar el algoritmo con la entrada ms desfavorable.
Complejidad del caso medio: tiempo promedio en ejecutar el algoritmo con todas las entradas
posibles.

Dado un algoritmo A para resolver un problema , sean:

, . . . ,

todas las posibles entradas,

, . . . ,

tiempo de ejecutar para la entrada , 1 ,

, . . . ,

probabilidad de que ocurra la entrada , 1 .



La complejidad del mejor caso es

/ 1 ,

La complejidad del peor caso es

/ 1 ,

La complejidad del caso medio est dada por:



La complejidad ms utilizada para confrontar los rendimientos de los algoritmos es la del peor caso.
Una de las razones es que da una cota para todas las entradas, incluyendo aquellas muy malas, que el
anlisis del caso promedio no puede ofrecer. Otra razn es que la complejidad del caso medio es ms
difcil de calcular, dado que es necesario conocer todas las posibles entradas del algoritmo y sus
probabilidades.


1.3 NOTACIN O

Dadas :

y :

, se dice que es del orden de de , ( ) si existen constantes


y

tales que

(figura 1.4). En otras palabras, est acotada inferiormente


por para todo valor

. La figura 1.4 muestra un ejemplo.



Ejemplo 1.4:
3 +1
3


10 2



11
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.


FIGURA 1.4: Ejemplo de notacin O.

Propiedades de la notacin O:
1. + = + Regla de la suma
2. = = , . Constantes multiplicativas
3. = Regla de la multiplicacin
4. + = Cotas
5. Transitividad

Observaciones:
La notacin O desprecia las constantes aditivas y multiplicativas.
La medida de la complejidad es una aproximacin al tiempo real que el algoritmo requiere para
encontrar la solucin. Por ello aparece el smbolo ~ en lugar de =.


1.4 OTRAS NOTACIONES

Adems de la notacin O, existen otras notaciones asintticas que ayudan a acotar la complejidad de un
algoritmo:
Notacin : Dadas :

y :

, se dice que es omega de , denotado por ,


si existen constantes y

tales que

. En otras palabras, est acotada


inferiormente por para todo valor

.

Notacin : Dadas :

y :

, si ~Og y ~g a la vez se dice que ~g.


Expresado de otro modo, ~g si existen constantes

tales que

. Es decir, est acotada inferiormente por

y superiormente por

para todo valor

.

Notacin o: Dadas :

y :

, se dice que es o (tambin llamada o chica u o


minscula) de , denotado por o, si

y > 0. En otras
palabras, est acotada inferiormente por para todo valor

.


1.5 COMPLEJIDAD DE ALGORITMOS SECUENCIALES E ITERATIVOS

Anteriormente se estudi la forma de estimar el tiempo de ejecucin para un algoritmo dado mediante
la contabilizacin de las instrucciones que se ejecutan ante un escenario dado. Para determinar la
12
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.
complejidad del algoritmo, basta con aplicar las cotas descritas sobre la frmula obtenida para el
tiempo de ejecucin.

As, para el ejemplo 1.3 se tiene que:

~6 = 1

~6 +2 =

Ejemplo 1.5:
Problema: dadas

, calcular =

.
Entrada:

.
Salida:

.

Para 1 a hacer:
Para 1 a hacer:


Para 2 a hacer:



Complejidad:
Aqu se observan tres ciclos Para anidados.
El primer ciclo Para se ejecuta veces.
Por cada vez que se ejecuta el primer ciclo, el segundo ciclo Para se ejecuta veces.
Por cada vez que se ejecuta el segundo ciclo, se tiene una instruccin bsica y un tercer ciclo
que se ejecuta 1 veces.

La complejidad de tiempo queda definida por

. En particular, si = =
, entonces

.

En este caso, la complejidad del mejor caso es igual a la complejidad del peor caso y a la
complejidad del caso medio, ya que cualquiera sea la entrada el algoritmo ejecuta todos los
pasos.

Ejemplo 1.6:
El factorial de un nmero natural se define por la multiplicacin desde 1 al nmero :
! = 1 2 3 .

Problema: dado , calcular !.
Entrada: .
Salida: !.

Si = 0 = 1 entonces:
1
En caso contrario hacer:
1
Para 2 a hacer:
13
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.


Complejidad:
Para la instruccin condicional (Si) y la asignacin se considera un tiempo unitario.
Para el caso contrario de la instruccin condicional se tiene:
Asignacin con tiempo 1.
Ciclo Para que se ejecuta n-1 veces.
Dentro del ciclo Para, una asignacin con tiempo 1.

Con los tiempos de cada instruccin y por las propiedades de la notacin O, la complejidad del
algoritmo 1.3 es = 1 +1 [1 + 1 1] = 1 +1 +n 1 . Aplicando las
propiedades de la notacin O se tiene que = 1 +1 + 1. Aqu se
podra ocupar la regla de la suma, pero se debe recordar que la notacin O desprecia las
constantes aditivas y multiplicativas, por tanto:

~.

Ejemplo 1.7:
La utilidad del uso de la complejidad aparece en su mayor expresin cuando se necesita optar
por alguna alternativa entre diferentes algoritmos para resolver un problema determinado. Para
esto, se debe saber discriminar entre un algoritmo y otro, para poder tomar la mejor decisin.
Suponga que la entrada de cierto problema tiene tamao y que, para resolverlo se encuentra
en la literatura las siguientes alternativas:
a. Algoritmo de tiempo

.
b. Transformarlo en otro problema para el cual se conoce un algoritmo de tiempo . La
transformacin demora log .
c. Modelarlo en un rbol de decisin de vrtices y ejecutar por cada vrtice del rbol un
algoritmo de tiempo .

La alternativa a no tiene mayor anlisis.
En la alternativa b se encuentra una transformacin. Esto no es ms que la aplicacin de un
algoritmo seguido de otro. Se puede observar entonces que la complejidad es + log .
Entre estas dos funciones se debe determinar la mayor para que la alternativa quede acotada a su
peor caso. Por ello, la complejidad de la alternativa b es ~ log .

La alternativa c del ejemplo 1.7 presenta un modelamiento con un rbol, por cada vrtice del
rbol se ejecuta un algoritmo de tiempo . Ahora bien, siendo los vrtices del rbol y
utilizando la regla de la multiplicacin, la alternativa c queda con complejidad ~

.

Se tiene entonces:
a.


b. log
c.

.

Se debe elegir la alternativa cuyo valor de funcin sea menor, esto es, porque el algoritmo
elegido debe ser el ms rpido, es decir que ocupe menor tiempo de ejecucin. Luego, en el
ejemplo 1.7 la alternativa elegida es la b.

14
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.
Ahora que ya se tienen las herramientas para analizar la complejidad de un algoritmo, es pertinente dar
algunas definiciones adicionales relativas a la eficiencia de algoritmos:
Un algoritmo es eficiente si su complejidad es un polinomio de la entrada, es decir, es de la forma
~ , donde es una constante.
Para algunos problemas es posible determinar el lmite inferior del problema que corresponde al
tiempo mnimo para resolverlo. Este lmite es una caracterstica del problema y refleja su dificultad
intrnseca para resolverlo. Cualquier algoritmo que lo resuelva utilizar por lo menos ese tiempo.
Un algoritmo es ptimo si su complejidad es ~, donde es el lmite inferior del problema.

Una observacin importante

Hay un aspecto del clculo de la complejidad que suele dar origen a confusin, y est ligado a la nocin de
instruccin bsica. Haba quedado establecido que las instrucciones bsicas son aquellas cuyo tiempo de
ejecucin est acotado superiormente por una constante que solo depende de la implementacin usada. En
otras palabras, pueden asociarse a las operaciones unarias y binarias que incorpora el procesador (asignacin,
cambio de signo, operaciones aritmticas, operaciones lgicas, comparaciones, etc.). Sin embargo, en los
ejemplos anteriores pareciera que no se hubiese considerado la condicin de la sentencia Si o de los ciclos
Para y Mientras, o bien que se hubiese considerado como instruccin simple a alguna sentencia que en
realidad contiene varias operaciones.

En efecto, si se tiene una sentencia como:
= 3 5 + / 6

Al momento de compilar o interpretar el programa se traduce en una serie de sentencias (los trminos


corresponden a variables temporales creadas por el compilador o intrprete):

= 5 +

= 3

6
=



No obstante, como se asume que cada una de ellas tiene un tiempo de ejecucin unitario y la notacin
asinttica descarta las constantes aditivas y multiplicativas, es posible ignorar este aspecto.

En el caso de las comparaciones y operaciones lgicas se observa el mismo fenmeno. Considere la
expresin:

3 < 8

Cuando se compila o interpreta el programa, esto se traduce en una secuencia de operaciones de la forma (los
nmeros agregados al comienzo de cada instruccin simplemente permiten identificar cada lnea para dirigir
los saltos):

0: si 3 3
1:

= falso
2: 4
3:

= verdadero
4: si < 8 7
5:

= falso
6: 8
7:

= verdadero
8:


15
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.
1.6 COMPLEJIDAD DE ALGORITMOS RECURSIVOS

Se denomina recursin al proceso de resolver un problema grande descomponindolo en uno o ms
subproblemas que son de estructura idntica a la del problema original pero ms simples de resolver
que aquel. Cada subproblema se resuelve de forma similar, repitiendo la descomposicin hasta generar
subproblemas tan simples que se resuelven sin necesidad de descomponerlos. La solucin del problema
original se obtiene combinando las soluciones de los subproblemas en un proceso inverso a la
descomposicin realizada.

La recursin est muy ligada a la recurrencia matemtica, que en cuando se define una funcin f en
trminos de ella misma. Dos ejemplos clsicos de recurrencia matemtica son el clculo del factorial y
los nmeros de Fibonacci, que se muestran en los ejemplos 1.8 y 1.9, respectivamente.

Ejemplo 1.23: Funcin recurrente para el factorial.
=
1! 1
1 = 0


Ejemplo 1.24: Funcin recurrente para los nmeros de Fibonacci.
=
1 + 2 2
1 = 1
1 = 0



Cabe destacar que la recursividad es una propiedad de la estrategia para resolver un problema y no del
problema en s. As pues, se dice que un algoritmo es recursivo si corresponde a un procedimiento que
se invoca a s mismo hasta recibir como entrada un caso base.

En programacin, la recursin puede darse de dos formas:
1. Directa: en algn paso del conjunto de instrucciones aparece una invocacin al propio
procedimiento.
2. Indirecta: el procedimiento llama a otro procedimiento, y este ltimo llama a su vez al primero.
Asimismo, si un procedimiento llama a otros y, en algn momento, alguno de ellos llama al
primero, tambin es un caso de recursin indirecta.

En toda definicin recursiva de un problema se debe establecer una condicin de borde, es decir, una
condicin que no requiera otra definicin recursiva para su resolucin. sta condicin determina el
criterio de parada del algoritmo recursivo.

Para el ejemplo 1.23, por definicin se tiene que:
0! = 1
1! = 0! 1 = 1 1
2! = 1! 2 = 1 1 2
3! = 2! 3 = 1 1 2 3
etc.

Al definir 3! estamos usando 2!, y as hasta llegar al 0. En este caso, la condicin de borde es el
factorial de cero (0! = 1). En este punto se observa que la funcin ya no se llama a s misma, sino que
entrega el resultado y se detiene. En otras palabras, se asigna un valor directamente.
16
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.
Dado
1
Devolver Factorial.

Procedimiento
Si = 0 1 entonces:
Devolver 1
En caso contrario hacer:
Devolver 1.

La complejidad de un algoritmo recursivo se expresa mediante una ecuacin de recurrencia. Por
ejemplo, sea el tiempo para calcular !. Entonces:
=
1 +1 > 0
1 = 0



Si se resuelve esa ecuacin por sustitucin se encuentra:

= 1 +1 =
= 2 +1 +1 = 2 +2 =
= 3 +1 +1 +1 = 3 +3 =

= + =

= 1 + 1 =
= 0 + = +1

Luego, la complejidad del Algoritmo Factorial Recursivo es ~.

Una observacin importante es que, en este caso, la complejidad del algoritmo iterativo es igual a la del
algoritmo recursivo. No obstante, esto no siempre es as. Para algunos problemas es ms eficiente el
algoritmo recursivo; para otros, el algoritmo iterativo es mejor. Ms an, existen problemas para los
cuales es imposible desarrollar un algoritmo iterativo que no sea una simulacin de la recursin. La
secuencia de Fibonacci del ejemplo 1.9 es un caso en que el algoritmo iterativo es ms eficiente.

Complejidad:
Dado que un algoritmo recursivo se invoca a s mismo, al expresar el orden de su complejidad se
obtiene una ecuacin de recurrencia. Esta ecuacin depende del proceso de descomposicin del
problema en subproblemas.

Reduccin por sustraccin: si el tamao del problema decrece en una cantidad constante en cada
llamada, se realizan llamadas recursivas y las operaciones correspondientes a la parte no recursiva
del algoritmo toman un tiempo

, entonces:

= +

si .

17
Anlisis de Algoritmos y Estructura de Datos


Jacqueline Khler C.
Una observacin importante es que se considera un tiempo polinomial para la resolucin de un
problema solamente porque interesa que la solucin recursiva sea eficiente. Un tiempo exponencial,
por ejemplo, sera mucho ms costoso que un caso iterativo.

La solucin de esta ecuacin de recurrencia es de la forma:

=

< 1

= 1

> 1


Reduccin por divisin: si el algoritmo con un problema de tamao realiza llamadas recursivas con
subproblemas de tamao

y las operaciones correspondientes a la parte no recursiva, que corresponde


a descomponer el problema en los subproblemas y luego combinar las soluciones de stos, toman un
tiempo

entonces:

=

si .

La solucin de esta ecuacin de recurrencia es de la forma:

=

<

log =

>

También podría gustarte