Está en la página 1de 8

REGLAS PRÁCTICAS

4.3. Bucles

Ciclo mientras: La complejidad de un ciclo de la forma:

Mientras <no condicion> hacer


<instrucciones> #se ejecuta k-1 veces
FMientras
donde:

k= número de iteraciones del ciclo


= Es la complejidad en tiempo de <instrucciones> en la iteración i-esima
)= Es la complejidad para evaluar la condición de parada( generalmente de igual complejidad en cada iteración)
Si es el mismo en todas las iteraciones y es constante, entonces podemos reducir la fórmula de la siguiente manera:

Si es el mismo en todas las iteraciones en toda slas iteraciones y es constante, entonces podemos reducir
la fórmula de la siguiente forma:

Ejemplo Solución:
j=n;
Mientras( j>1) hacer //To(n)=C1; =
módulo A; //T1(n)=M;
j=j/2; //T2(n)=C3; Para saber cuántas iteraciones realiza el algoritmo analizamos el
FMientras comportamiento del mencionado
Suponga que la ejecución
del módulo A es una constante M Ejemplo:
Valores de j
j Cantidad de Valor Comportamiento
iteraciones
16 1 =8 =
8 2 =4 = =

4 3 =2

Luego para n se tiene que:


>=1 => n=> => k=log2(n)
= *(T1(n)+T2(n))+ To(n)
= C2+ M+ C1
= O(Max( C2, M, )) // por regla suma
= O(Max( , , )) //por regla producto
= O( ) //por concepto de dominancia de funciones
Repetir
La complejidad de un ciclo repetir que se ejecuta k veces es:

Repetir
<instrucciones>
hasta <condicion>
donde:

k= número de iteraciones del ciclo


= Es la complejidad en tiempo de <instrucciones> en la iteración i-esima
)= Es la complejidad para evaluar la condición de parada( generalmente de igual complejidad en cada iteración)
=

Si es el mismo en todas las iteraciones en toda slas iteraciones y es constante, entonces podemos reducir
la fórmula de la siguiente forma:

Ejercicio01: Solución
Repetir T(n)= TRepetir(n)
i=1; //T1(n)= C1 TRepetir(n)= )
Repetir
j=1; //T2(n)// C2 TRepetir(n)= T2(n)+TRepetir(n)
Repetir
k=1; //T3(n) = C3 TRepetir(n)=
modulo A;//T4(n) = C4 = n*(T3(n)+T4(n))+nC5
hasta k=j; //T5(n)=C5 = n*(C3+M)+nC5
hasta j=l; //T6(n)=C6 = nC3+nM+nC5
hasta i=n; //T7(n)=C7 => TRepetir(n)=
= n*(T2(n)+TRepetir(n))+n.C6
Suponga que la ejecución =n*(C2+nC3+nM+nC5)+n.C6
del módulo A es una constante M =nC2+ C3+
=>TRepetir(n)=
=n*(T1(n)+TRepetir(n))
=n*(C1+ nC2+ C3+ )+nT7(n)
=n*(C1+ nC2+ C3+ )+nC7
=nC1+ C2+ c3+ + + +nC7
=O(Max(nC1, C2 c3, nC7)) //regla suma
=O(Max(n, , , , )) // por regla producto

=> TRepetir(n)=O( ) //por concepto de dominancia de funciones

Ejemplo01: K es una constante


Para i<-1 hasta k hacer T(n)= kC+2kC= 3kC
#algo de O(1); =>T(n)= O(1)
FPara
Ejemplo02: Si el tamaño N aparece como límite de
iteraciones T(n)= Cn+2Cn= 3Cn
Para i<-1 hasta n hacer => T(n)= O(n) // por regla producto
#algo de O(1);
FPara
Ejemplo03: Ciclos anidados. Su complejidad se calcula Calculamos primero la complejidad del Para más
desde el ciclo más interno hasta el más externo. interno(con n=iteraciones)
Para i <-1 hasta n hacer
Para j <-1 hasta n hacer C+2nc= 3nc
#algo de O(1);
FPara
FPara =

Luego //por regla suma


=> //por regla producto
=> //por dominancia funciones
Solución 02:
Otra forma de verlo es:

=>
Que el ciclo +interno realiza n iteraciones
Que el ciclo + externo realiza n iteraciones
Por lo que tendremos N * N * O(1) = O(n2)

Solución03:
el bucle exterior se realiza N veces, mientras que el interior se
realiza 1, 2, 3, ... N veces respectivamente. En total,
1 + 2 + 3 + ... + N = N*(1+N)/2 -> O(n2)

A veces aparecen bucles multiplicativos, donde la evolución de


la variable de control no es lineal (como en los casos anteriores)
2). Aplicación a un algoritmo sencillo.

Calcular la complejidad del segmento que obtiene el mínimo elemento de un arreglo.


min = A[0]; //C1
for(i=1; i<n; i++){ //Tcond(n)=C1
if(A[i] < min){ //T1(n)=C2
min = A[i]; //T2(n)=//C3
}
}
Si la comparación y la asignación son de costo O(1), entonces el if, en peor caso, es de costo
O(1) + O(1) = O(1).
El for se realiza (n-1) veces, su costo es: (n-1) O(1) = O(n-1) = O(n).
La concatenación de la asignación con el for es de costo: O(1) + O(n) = O(n)
Finalmente el segmento es de orden de complejidad O(n).

Una manera formal de resolver el ejercicio es utilizando las fórmulas

T(n)= (n-1)*(C2+C3)+2(n-1)*C
= c2n+c3n-c2-c3+2nc-2c
= O(Max(c2n,c3n,-c2,-c3,2nc,2c)) // por regla de la suma
= O(Max(n,n,-c2,-c3,n,2c)) // por regla del producto
= O(n) // por concepto de dominancia de funciones

public static booblean esPrefijoIt(int[]a, int[] b){


if( a.length>b.length ){ //T1(n)=C1;
return true; //T2(n)=C2;
}else{
for(pos=0; pos<a. length && a[pos]==b[pos]; pos++){
return pos=a.length; //T3(n)=C3;
}
}
Solución:

El T(n)por definición es la complejidad en tiempo del algoritmo en el peor caso cuando se utiliza la notación big O
En este caso el T(n) es la suma de la complejidad de la instrucción del if + la complejidad del return true; + la complejidad
en tiempo asociada al ciclofor

T(condición)= T1(n)= C1; //El t1 de n de la condición es una constante C1


T( return true) = T2(n)=C2; // El t2 de n de la instrucción asociada a la instrucción del if es una constante C2 por ser una
instrucción simple
T(ciclo for))= es la cantidad de veces que se ejecuta el ciclo , multiplicada por la complejidad de la instrucción que está
dentro del ciclo.
De acuerdo a las reglas prácticas colocadas arriba debemos determinar cuantas veces se ejecuta el ciclo: En este caso el
ciclo se ejecuta desde 0 hasta n, es decir itera n+1 veces
Por otro lado la instrucción que esta dentro del for es T3(n)= C3
Luego:
T(ciclofor)= n+1 * C3
Luego la complejidad en tiempo de todo el algoritmo es:
T(n)= T1(n)+T2(n)+T (ciclofor)= C1+C2+ (n+1)* C3= C1+C2+C3*N+C3= 2C3+C1+C2+ C3*N

Luego por regla de la suma T(n)= O(Max(2C3, C1,C2,C3*N)) = T(n)= O(C3*N)

Luego por regla del producto la constante C3 es despreciable lo que implica que
T(n)=O(n)

En los bucles con contador explícito, podemos distinguir dos casos, que el tamaño N forme parte de los límites o que no. Si
el bucle se realiza un número fijo de veces, independiente de N, entonces la repetición sólo introduce una constante
multiplicativa que puede absorberse.

Ejemplo04
c= 1; Valores de n y c
while (c < N) {
algo_de_O(1) N C
c= 2*c; 1 2
}
2 2*2
3 2*2*2
n
k
El valor inicial de "c" es 1, siendo "2 " al cabo de "k" iteraciones. El número de iteraciones es tal que
2k >=N =>k=(log2 (N)), [el entero inmediato superior]
y, por tanto, la complejidad del bucle es O(log n).

Ejemplo05

for (int i= 0; i < N; i++) {


c= i;
while (c > 0) {
algo_de_O(1)
c= c/2;
}
}
tenemos un bucle interno de orden O(log n) que se ejecuta N veces, luego el conjunto es de orden O(n log n)
Ej.- c= N; Valores de n y c
while (c > 1) {
algo_de_O(1) N C
c= c / 2; 1
}

Un razonamiento análogo nos lleva a log2(N) iteraciones y, por tanto, a un orden O(log n) de complejidad.

Revisar adicionalmente en la carpeta:


parcial01-> 10-12-2014. Introducción a la notacion 0-> material adicional- >ND-Scalise_Carmona.pdf

Página 12 y 13 del paper del material que esta en google drive

Hay un ejercicio adicional de càlculo de complejidad en tiempo


Complejidad de algoritmos recursivos
Ejercicio01

Funcion factorial(entero n){


Si(n<=1) entonces
<-- 1;
sino
<-- n * factorial(n-1);
fsi
Ffuncion

¿Cómo resolverlos?
1- Suponer una solución f(n) y usar la recurrencia para demostrar que T(n)=f(n).
La fórmula se hace generalmente por inducción sobre n.

Paso1: Sea
T(n)= C1 si n<=1 //este es el caso base
T(n-1)+C2 si n>1 //este es el caso cuando el algoritmo ejecuta la llamada recursiva

En este caso

C1 SI n<=1:Se define como el caso base de la función. Y se denomina C1 porque cuando n<=1 retorna un número <=1
T(n-1)+C2: Representa la llamada recursiva a la función con factorial(n-1)

Si n=0: => T(n)=T(n-1)+C2 = T(n-1)+C2


Si n=1: => T(n-1)=(T(n-2)+C2)+C2 =T(n-2)+2C2
Si n=2: => T(n-2)=((T(n-3)+C2)+C2)+C2 = T(n-3)+3C2

Haciendo esto por inducción suponemos para n=k


=>

Si n=k : => T(n-k)+KC2

2) Sustituimos las recurrencias por su igualdad hasta llegar a cierto

Sea T(n-k)+KC2 =>T(n)= T(n-k)+kC2 =


Sabemos que n-k=1 ( valor del caso base) =T(n-(n-1))+(n-1)C2
=> -k=1-n = T(n-n+1)+nC2-C2
=> k=n-1 = T(1)+nC2-C2
= C1+nC2-C2
(T(1) es C1 , porque es equivalente a preguntar cuál es el
valor cuando n es igual a 1, que en este caso es el valor del
caso base

=>T(n)= O(Max(C1,nC2,-C2)
=>T(n)= O(Max(C2,n,-C2) por regla del producto
=>T(n)= O(n) // por concepto de dominancia de funciones
En este caso se toma cual es la función que crece más
rápido para n. Entre la función C2, la función n, y la función
-C2, la que crece más rápido es n
Ejercicio02

Funcion Rec3 (entero n){


Si(n<=1) entonces
<-- 1;
sino
<-- 2 * Rec(n/2);
fsi
Ffuncion

Solución
- Suponer una solución f(n) y usar la recurrencia para demostrar que T(n)=f(n).
La fórmula se hace generalmente por inducción sobre n.

Paso1: Sea
T(n)= C1 SI n<=1 //este es el caso base
T(n/2)+C2 si n>1 //este es el caso cuando el algoritmo ejecuta la llamada recursiva

En este caso

C1 SI n<=1:Se define como el caso base de la función. Y se denomina C1 porque cuando n<=1 retorna un número <=1

T(n/2)+C2: Representa la llamada recursiva a la función con Rec3 (n/2). Esto se traduce como que es una función que
llama de forma genérica a una función que recibe por parámetro n/2 ( T(n/2)), y el C2 representa el tiempo que
adicionalmente se tarda el algoritmo en multiplicar *2. Por esto se escribe el caso como:
T(n/2)+C2

Si n=0: => T(n) =T(n/2)+C2 = T(n/2)+C2


Si n=1: => T(n-1) =(T(n/2/2)+C2)+C2 =T(n/4)+2C2
Si n=2: => T(n-2) =((T(n/2/2/2)+C2)+C2)+c2 = T(n/8)+3C2

Haciendo esto por inducción suponemos para n=k


=>

Si n=k : => T( )+KC2

Igualamos el valor que recibe el T(n) al valor del caso base( igual a 1)

=1 => n= => k=

=>T(n)= T( )+

=>T(n)= O(Max( ), ) por regla de la suma

=>T(n)= O(
Ejercicio03

Funcion Rec33 (entero n){


Si(n<=1) entonces
<-- 1;
sino
<-- Rec33(n-1)+ Rec33(n-1);
fsi
Ffuncion

Solución

Sea
T(n)= C1 SI n<=1 //este es el caso base
2*T(n-1)+C2 si n>1 //este es el caso cuando el algoritmo ejecuta la llamada recursiva

T(n)=2*T(n-1)+C2

Si T(n) = 2*T(n-1)+C2 = 2*T(n-1)+C2 = 2*T(n-1)+C2


Pero T(n-1)= 2(T(n-2)+C2 = 2*(2(T(n-2)+C2)+C2 = +3C2
T(n-2)= 2*T(n-3)+C2 =2*(2*(2*T(n-3)+C2)+C2)+C2= +7C2

Para n=k
=> T(n)= + *C2

Cuando n-k=1 => k=n-1

=> T(n) = + *C2


=> T(n) = + *C2
=> T(n) = + *C2
=> T(n) = //T1 es C2 porque es equivalente a preguntar cuando n es igual a 1 cuál es el valor( ver
ecuación de recurrencia)

=>T(n)= O(Max( )) // Por regla de la suma


=>T(n)=O( ) por concepto de dominancia de funciones

Ejercicio04
Funcion Recursivo (entero n){
Si(n<=1) entonces
<-- 1;
sino
<-- Recursivo(n-1)+ Recursivo (n-1)+ Recursivo(n-1);
fsi
Ffuncion

Sea
T(n)= C1 SI n<=1 //este es el caso base
3*T(n-1)+C2 si n>1 //este es el caso cuando el algoritmo ejecuta la llamada recursiva

T(n)=3*T(n-1)+C2

Si T(n) = 3*T(n-1)+C2 = 3*T(n-1)+C2 = 3*T(n-1)+C2


Pero T(n-1)= 3(T(n-2)+C2 = 3*(3(T(n-2)+C2)+C2 = +3C2+C2
T(n-2)= 3*T(n-3)+C2 =3*(3*(3*T(n-3)+C2)+C2)+C2= +9C2+3C2+C2
T(n-3)= 3*T(n-4)+C2 =3*(3*(3*(3*T(n-4)+C2)+C2)+C2)+C2= +27C2+9C2+3C2+C2

Observe el comportamiento de lo que esta subrayado:


De ese comportamiento se desprende se comporta como:
Para n=k
=> T(n)= +

Pero necesitamos expresar toda la ecuación T(n) en función de n, por lo que necesitamos saber la fórmula general para la
sumatoria expresada a continuación:

Para determinar la fórmula determinamos el comportamiento de la sumatoria:


+

Multiplicamos por -3 la ecuación dada:


+

Restamos las 2 ecuaciones:


- =

Quedando esto:
=

=> =

De la ecuación anterior de T(n)= + , se tiene que:

T(n)= +
La ecuación esta expresada en función de 2 variables( n y k) y necesitamos colocarla en función
de n por definición de complejidad en tiempo
por eso calcularemos en valor de k:
n-k=1 => k=n-1
=> T(n)= +

=> T(n)= +

=> T(n)= +

=> T(n)= +

=> T(n)= + // T(1) es 1 por que cuando n<=1 retorna 1

=> T(n)= +

=> T(n)= O(Max( , )) por regla de la suma

=> T(n)=O(Max( , ))

=> T(n)=O( ) por regla del producto

RECOMENDACIONES:

Practicar recurrencia
Aprenderse o deducir las fórmulas más comunes por inducción sobre n( ver apuntes de matemáticas discretas I)

También podría gustarte