Documentos de Académico
Documentos de Profesional
Documentos de Cultura
DOCENTE:
Christian Torres Morán
O(N+N2) Esta expresión le podría indicar que existe un for() y seguido de otros dos for() anidados, para tener una expresión en Big O se
selecciona el término más dominante o dicho de otra forma el peor caso posible de toda la expresión en este caso O(N2)
O(N + log N) Para esta expresión se debe selecciona la más dominante, considerando el análisis realizado hasta ahora y tomando como
referencia la gráfica en el plano cartesiano el log N no tienden a crecer en tiempos de procesamiento al incrementar los datos de entrada, pero
la tendencia lineal N tiende a crecer más que la logarítmica, por lo tanto el peor caso posible de toda la expresión en este caso es O(N)
O(5*2N+N100) Para concluir cual es la notación Big O de esta expresión se debe analizar los elementos internos, la expresión 5*2N se podría
indicar que es 2N por simplificación asintótica, esta expresión indica que al tener N como una potencia de crecimiento (datos de entrada), el
incremento de este valor significará también el incremento del tiempo de proceso, mientras que la expresión N100 utiliza la contante 100 para
indicar que, sin importar el valor de N siempre será potencia 100 veces que se realizará dichos procesos, por lo tanto se selecciona el término
más dominante o dicho de otra forma, el peor caso posible de esta expresión es O(2N)
Para ejemplificar estas notaciones, primero considere el siguiente proceso para mostrar el contenido de 2 arreglos:
Observe que se tienen 2 arreglos y por lo Observe que se tienen 2 arreglos y por lo
for(int a: arregloA){ tanto 2 recorridos, al tratarse de for() se for(int a: arregloA){ tanto 2 recorridos anidados, al tratarse de
podría indicar que la complejidad tendría 2 for() se podría indicar que la
System.out.println(a); una relación O(N) como el ejercicio anterior for(int b: arregloB){ complejidad tendría una relación O(N2) o
} pero no es así, ya que son dos recorridos System.out.println(a + b); O(N*N) como ya se ha analizado en
for(int b: arregloB){ diferentes por ser dos arreglos diferentes } ejercicios anteriores con for anidados pero
así que, la notación del Big O quedaría así: no es así, ya que son dos recorridos
System.out.println(b); O(A+B), ya que A representa el primer
} diferentes por ser dos arreglos diferentes
} recorrido y B el segundo recorrido o así que, la notación del Big O quedaría así:
proceso. O(A*B), ya que A representa el primer
recorrido y B el segundo recorrido o
¿Cuál de los dos procesos tendría mayor peso? 🡪O(A*B) proceso anidado.
EXPRESIÓN DE COMPLEJIDAD BIG O()
Para ejemplificar la diferencia de un crecimiento lineal O(N) y un crecimiento logarítmico O(log N) considere los ejemplos de búsqueda secuencial y
binaria
En la búsqueda secuencial, se dará el peor de los casos cuando tiene que recorrer toda la estructura por ejemplo que no exista el elemento a
buscar, donde el número de procesos a realizar para encontrar el elemento será igual al número de elementos O(N)
En la búsqueda binaria para su funcionamiento requiere que el arreglo este ordenado, funciona dividiendo el arreglo en mitades cada vez más
pequeñas, es decir, se ubica en cada mitad y compara, si el elemento buscado en mayor buscará a la derecha caso contrario buscará a la
izquierda de forma sucesiva hasta encontrar el elemento, por lo tanto se fracciona de forma logarítmica O(log N), por ejemplo, suponga que
desea encontrar el valor 9:
Verifica si lo encontró, si no es así, buscará a la derecha o a la izquierda (9 >
x
2 =n 6)
Log2n = x
Lo encontró
DEFINICIÓN DE COMPLEJIDAD Y SU MEDIDA BIG O()
Otro ejemplo para aplicar una notación lineal consistiría en el llamado de una función recursiva que encuentra el factorial de un número:
Suponiendo que se desea encontrar el factorial de 5, se aplicaría la siguiente instrucción: factorial(5)
public int factorial (int n){ Llamadas:
1 5 * factorial(4) Observe que el llamado es lineal, note que el total de
if (n==0){ llamadas es igual a n + 1, por lo que al aplicar la
2 4 * factorial(3)
return 1; } 3 complejidad sería O(n), una vez que se aplica la
3 * factorial(2)
else { 4 2 * factorial(1)
simplificación asintótica
return (n * factorial(n-1)); } 5 1 * factorial(0)
}
6 1
Otro ejemplo para aplicar una notación exponencial consistiría en el llamado doble de una función recursiva que encuentra el valor de una
posición de la secuencia de Fibonacci:
Suponiendo que se desea analizar la función recursiva de la serie de Fibonacci a diferencia de la anterior realiza doble llamado, por ejemplo
si se llama F(4):
Llamadas:
public int F(int n){ 1 🡪20 F(4)
if(n <= 1){ 2 🡪21 F(3) F(3)
return 1; } 3 🡪22 F(2) F(2) F(2) F(2)
return F(n-1) + F(n-1);
4 🡪23 F(1) F(1) F(1) F(1) F(1) F(1) F(1) F(1)
}
Observe que el llamado es exponencial, note que el total de llamadas es igual a n, pero por cada llamada de incrementa el doble por lo
que al aplicar la complejidad sería O(2n), esto demuestra que este tipo de recursividad reduce la codificación pero demanda de mayor
esfuerzo computacional
DEFINICIÓN DE COMPLEJIDAD Y SU MEDIDA BIG O()
¿cómo desarrollo un análisis Big O()?
Recuerde que un análisis Big O() se basa en la aplicación de la simplificación asintótica seleccionando la carga más pesada o el peor caso posible,
ya que no esta centrada en las expresiones polinómicas como tal sino el la estimación de mayor esfuerzo computacional, por ejemplo, se analizará
los siguientes códigos sin importar su utilidad:
public void foo(int[] arreglo){ public void foo(int[] arregloA, int[] arregloB){
for (int i = 0; i < arreglo.length; i++){ for (int i = 0; i < arregloA.length; i++){
for (int j = i+1; j < arreglo.length; i++){ for (int j = 0; j < arregloB.length; i++){
System.out.println(arreglo[i]+arreglo[j]); int suma = arregloA[i] + arregloB[j];
} }
} }
} }
Esta función tiene 2 for() anidados sobre un arreglo Esta función tiene 2 for() anidados sobre dos arreglos
unidimensional o vector, como se trata de for unidimensionales o vectores diferentes, como se trata de
anidados y a pesar de que el segundo siempre for anidados se podría pensar que la complejidad Big O
empieza en la posición siguiente del recorrido del sería N*N o N2 pero no es así, ya que son vectores
primero (En forma de triángulo), la complejidad Big diferentes quedando así O(A*B) o O(AB)
O sería N*N quedando así O(N2)
CONCLUSIONES DEL BIG O
La notación del Big O utiliza la expresión que refleje la mayor carga (tendencia hacia el peor caso) de cualquier expresión de
cálculo para definir su complejidad computacional, no identifica el cálculo ya que su expresión esta basada en la identificación
de mayor tendencia en el plano cartesiano y su disposición de crecimiento al infinito tomando los datos de entrada.
Con estas expresiones se puede definir cuan eficiente en un algoritmo, por ejemplo dependiendo de la expresión se podría indicar que:
O(1) < O(log n) < O(n) < O(n log n) < O(n2) < O(nn) < O(n!)
Big O(1) no importa el valor que se encuentra entre paréntesis esta notación
representa el crecimiento que tendrá una entrada constante, se la considera la
más eficiente porque sin importar cuantos procesos se realicen siempre será la
misma carga de trabajo
Big O(n) Esta notación representa el crecimiento lineal o de tiempo de proceso
que tendrá un algoritmo, significa que a mediada crecen los datos de entrada
2
también crecerá el tiempo de proceso para Seresolver
obtieneel: O(n
algoritmo.
)
Por ejemplo, si se analiza de manera bien detallada el siguiente código se tendría el
siguiente resultado:
2n+2 tiempos de proceso
for (m = 0; m < cantidad; m++){
SumaActual+= inta[m]; 2 tiempos de proceso
if (SumaActual > MaximaSuma){ 1 tiempos de proceso
MaximaSuma =
1 tiempos de proceso 6*n
SumaActual;
else if(SumaActual < 0) 1 tiempos de proceso = 2n + 2 + 6n
SumaActual = 0; = 8n +2
1 tiempos de proceso
}
= 8n +2 🡪si aplicamos simplificación asintótica se obtiene O(n)
CONCLUSIONES DEL BIG O
Big O(n2) Esta notación representa el crecimiento de la complejidad computacional al cuadrado de las entradas que tomará un algoritmo para
procesar las instrucciones, esto quiere decir que, a mediada crecen los datos de entrada su tiempo de incrementa al cuadrado de los mismos.
for (n = 0; n < cantidad; n++){ 2n+2 tiempos de proceso = 2n + 2 + n + (2n+2)*n + n*n + n*n +
SumaActual = 0; n*n
n veces del for() externo
for (m = n; m < cantidad; m++){ = 2n + 2 + n + 2n2 + 2n + n2 + n2 + n2
SumaActual = (int)a[m]; (2n+2)*n veces del for() externo = 2n + 2 + n + 2n2 + 2n + 3n2
if(SumaActual < MaximaSuma) = 5n2 + 5n + 2
n*n veces del for() interno por las veces de for() el externo Al aplicar la simplificación asintótica
MaximaSuma = SumaActual;
n*n veces del for() interno por las veces de for() el externo =5n2 + 5n + 2
}
} n*n veces del for() interno por las veces de for() el externo Se obtiene: O(n2)
Big O(n3) Esta notación representa el crecimiento de la complejidad computacional al cubo de las entradas que tomará un algoritmo para procesar
las instrucciones, es decir, a mediada crecen los datos de entrada su tiempo de procesamiento se incrementará al cubo de los mismos, por ejemplo:
= 2n + 2 + (2n+2)*n + n*n+ (2n+2)*n*n + n*n*n + n*n + n*n
2n+2 tiempos de proceso = 2n + 2 + 2n2 + 2n + n2 + (2n+2)n2 + n3 + n2+ n2
for (n = 0; n < cantidad; n++){
(2n+2)*n veces del for() externo = 2n + 2 + 2n2 + 2n + n2 + 2n3 + 2n2 + n3 + n2+ n2
for (m = 0; m < cantidad; m++){
= 3n3 + 7n2 + 4n + 2
SumaActual = 0; n*n veces del for() intermedio y externo
for (o = n; o < m; o++){ Al aplicar la simplificación asintótica
(2n+2)*n*n veces del for() intermedio y del for() el externo
SumaActual = (int)a[o];
} n*n*n veces del for() interno, intermedio y del externo 3n3 + 7n2 + 4n +
if(SumaActual < MaximaSuma) 2
n*n veces del for() intermedio y del for() externo Se obtiene: O(n3)
MaximaSuma =
SumaActual; n*n veces del for() intermedio y del for() externo
}