Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


Análisis de la complejidad de un bucle for() en Java, Ejercicios de Sistemas de Información Gerencial

En este documento se analiza el número de veces que se realizan los procesos en un bucle for() en Java, considerando diferentes casos de incremento y límite. Se calcula la complejidad de cada caso y se compara con el caso base. Se incluyen ejemplos de cómo modificar el límite y el incremento del bucle.

Tipo: Ejercicios

2020/2021

Subido el 11/07/2021

tucoman
tucoman 🇪🇨

4 documentos

1 / 21

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
OBJETOS Y ABSTRACCIÓN DE DATOS
DOCENTE:
TATIANA ZAMBRANO SOLÓRZANO
Periodo: Noviembre 2020 – Marzo 2021
CONTENIDO A TRATAR HOY:
Análisis algorítmico.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15

Vista previa parcial del texto

¡Descarga Análisis de la complejidad de un bucle for() en Java y más Ejercicios en PDF de Sistemas de Información Gerencial solo en Docsity!

OBJETOS Y ABSTRACCIÓN DE DATOS

DOCENTE:

TATIANA ZAMBRANO SOLÓRZANO

Periodo: Noviembre 2020 – Marzo 2021

CONTENIDO A TRATAR HOY:

Análisis algorítmico.

Retroalimentación: Interrogantes de la clase anterior, el estudiante debe contestar estas preguntas con sus propias palabras y ejemplos, subirlos al aula virtual en el repositorio de actuaciones “Actuación de clase 4”:

  1. ¿Cómo se insertan los elementos en una lista doblemente enlazada (LDE)?
  2. ¿Cuáles son las consideraciones para recorrer una LDE?
  3. ¿Cuáles son las operaciones que se realizan o se pueden realizar con una LDE?
  4. ¿Cómo se describe el proceso de extracción de datos en una LDE?
  5. ¿En qué situaciones se usa null en una LDE?
  6. ¿Cómo se insertan elementos al inicio y al final en una lista circular doblemente enlazada(LCD)?
  7. ¿ Cómo se insertan elementos después de un nodo LCD?
  8. ¿Qué operaciones se pueden realizar con una LCD?
  9. ¿Cómo se describe el proceso de extracción de datos en una LCD?
  10. ¿Cuáles son los elementos básicos de una estructura LCD?
  11. ¿En qué situaciones se usa null en una LCD?

Análisis, Tratamiento y Estrategias de Algoritmos

Un algoritmo es la descripción precisa de los pasos a seguir para alcanzar la solución de un problema determinado, es decir, son

los pasos o conjunto de acciones u operaciones que se deben realizar sobre ciertos objetos para obtener un resultado.

Un algoritmo debe ser capaz de resolver una clase de problemas lo más ampliamente posible.

Se considera un algoritmo eficiente cuando utiliza menos recursos en tiempo (consumo de procesadores) y optimización de

almacenamiento (memoria).

CUALIDADES DE UN ALGORITMO:

Por lo general es difícil encontrar un algoritmo que reúna ambas cualidades por lo que se debe procurar satisfacer lo mejor

posible los requisitos propios del problema.

Los avances tecnológicos en la actualidad han tomado énfasis en el ilimitado recurso lógico, por lo que el estudio de la calidad de los algoritmos se enfocan en la administración de los recursos físicos que devuelvan resultados de forma rápida y confiable.

El objetivo de este tema es sentar las bases que permitan determinar qué algoritmo es mejor (más eficiente) dentro de una

familia de algoritmos que resuelven el mismo problema.

Recordemos que La tecnología tiene dos tipos de recursos: Físicos y Lógicos: Los recursos físicos , son aquellos componentes electrónicos, mecánico–electrónico y de comunicación que realizan una actividad que se manifiesta en mostrar u obtener un resultado o movimiento que el ser humano puede evidenciar. Los recursos lógicos , son las instrucciones que permiten el funcionamiento de los recursos físicos, estas instrucciones pueden ser eficientes o requieren de mejoras para optimizar su funcionamiento.

Análisis, Tratamiento y Estrategias de Algoritmos

Eficiencia: En análisis de algoritmos es una Medida en el uso de recursos que necesita el algoritmo para llevar a cabo su tarea.

El medir la eficiencia de un algoritmo se basa en la cantidad de recursos que se requiere para obtener una solución al

problema y por lo tanto se define que un algoritmo es eficiente mientras utilice menor cantidad de recursos.

Una vez más, el objetivo de este tema es sentar las bases que permitan

determinar qué algoritmo es mejor (más eficiente) dentro de una familia

de algoritmos que resuelven el mismo problema.

Por ahora se asumirá que todos los algoritmos tratados van a ser eficaces , es decir, resuelven adecuadamente el problema para

el que se han diseñado

Análisis de Algoritmos Es el estudio teórico de la^ eficiencia^ de un algoritmo.

  • (^) Tiempo de ejecución
  • (^) Espacio de almacenamiento

A la medida se le denomina complejidad del algoritmo.

¿Cuáles son los recursos más importantes?

ORIENTACIÓN 1:

Se define la medida , coste o complejidad temporal de

un algoritmo, como el tiempo empleado por éste para

ejecutarse y proporcionar un resultado a partir de los

datos de entrada.

ORIENTACIÓN 1:

Se define la medida , coste o complejidad temporal de

un algoritmo, como el tiempo empleado por éste para

ejecutarse y proporcionar un resultado a partir de los

datos de entrada.

ORIENTACIÓN 2:

Se define la medida , coste o complejidad espacial de un

algoritmo como cantidad de memoria requerida(suma

total del espacio que ocupan las variables del algoritmo)

antes, durante y después de su ejecución

ORIENTACIÓN 2:

Se define la medida , coste o complejidad espacial de un

algoritmo como cantidad de memoria requerida(suma

total del espacio que ocupan las variables del algoritmo)

antes, durante y después de su ejecución

¿Cómo se puede evaluar la eficiencia de un algoritmo? Si, se aplican dos orientaciones:

for (int i=1; i<=5; i++){ System.out.println(“ ”+ i); } Definición de complejidad y su medida

¿Cómo expresar los valores y medidas en una o varias instrucciones?

Para explicarlo, se empezará analizando la estructura de un for() al desarrollar una serie de ciclos, estas acciones generarán una serie de valores como el número de asignaciones, el número de comparaciones y el número de cálculos o incrementos que se realizarán para cumplir su propósito, se deberá entender que estos procesos tendrán el mismo valor o peso. Por ejemplo, se desea mostrar del 1 al 5: for (int i=1; i<=5; i++){ System.out.println(“ ”+ i); }

Recordemos el funcionamiento del for

1.- El contador tomará el valor inicial 2.- Se evaluará la condición de repetición, si el resultado es verdadero ingresará para realizar las instrucciones del ciclo. 3.- Aplicará las instrucciones del ciclo 4.- Finalizada las instrucciones del ciclo, realiza el incremento del contador 5.- Vuelve a realizar desde el segundo paso hasta que la condición sea falsa y saltará a la siguiente instrucción fuera del ciclo repetitivo Asignaciones Comparaciones Incrementos Resultado a mostrar Considerando esta mecánica del for(), analicemos el número de veces que se realizan los siguientes procesos: (^1 1 ) 2 3 4 5 6 2 3 4 5 1 2 3 4 5 Al analizar el proceso se podría indicar lo siguiente:  (^) Se realizó 1 asignación  (^) Se realizó 6 comparaciones, 1 más que el límite  (^) Se realizó 5 incrementos En este ejemplo del for() el límite de ciclos es 5 pero tenga en cuenta que puede ser cualquier valor, por lo que, para encontrar el total de procesos en un formato calculable, este límite será reemplazado por la variable (n) quedando de la siguiente forma: = 1 asignación + (n + 1 comparaciones) + n incrementos  “recuerde que n reemplaza al 5 de este ejemplo” = 1+n+1+n  Esta expresión de calculo se la puede simplificar = 2n+2 Se puede expresar que 2n+2 es la complejidad del for()

for (int i=5; i>0; i--){ System.out.println(“ ”+ i); } Definición de complejidad y su medida Asignaciones Comparaciones Decrementos Resultado a mostrar Considerando la mecánica del for(), analicemos el número de veces que se realizan los procesos cuando se decrementa: (^1 1 ) 2 3 4 5 6 2 3 4 5 5 4 3 2 1 Al analizar el proceso se podría indicar lo siguiente:  (^) Se realizó 1 asignación  (^) Se realizó 6 comparaciones, 1 más que el límite  (^) Se realizó 5 incrementos = 1 asignación + (n + 1 comparaciones) + n incrementos  “recuerde que n reemplaza al 5 de este ejemplo” = 1+n+1+n  Esta expresión de calculo se la puede simplificar = 2n+2 Se puede expresar que 2n+2 es la complejidad del for() for (int i=0; i<10; i+=2){ System.out.println(“ ”+ i); } Asignaciones Comparaciones Incrementos Resultado a mostrar Considerando la mecánica del for(), analicemos el número de veces que se realizan los procesos cuando el incremento es el doble: (^1 1 ) 2 3 4 5 6 2 3 4 5 0 2 4 6 8 Al analizar el proceso se podría indicar lo siguiente:  (^) Se realizó 1 asignación  (^) Se realizó 6 comparaciones, 1 más de la mitad = 1 asignación + (n/2 + 1 comparaciones) + n/2 incrementos^ ^ Se realizó^^5 incrementos, la mitad del límite = 1+n/2+1+n/2  Esta expresión de calculo se la puede simplificar = 2n/2+2  Esta expresión de calculo se la puede simplificar aún más 2 n/ 2 = n+2 Se puede expresar que n+2 es la complejidad del for() Este mismo resultado obtendríamos si modificamos la condición de repetición, por ejemplo:

for (int i=0; i<n/2; i++){

System.out.println(“ ”+ i);

1 asignación n/2+1 comparaciones n/2 incrementos = 1+n/2+1+n/ = 2n/2+ = n+ = 1 asignación + n/2 + 1 comparaciones+ n/2 incrementos

Definición de complejidad y su medida c=0; for (int i=1; i<=n; i++){ for (int k=1; k<=n; k++){ c++; } } Considerando la mecánica del for(), ahora analizaremos el número de veces que se realizan los procesos cuando se trabaja con dos for() anidados: Por los análisis realizado en las anteriores diapositivas se conoce que la complejidad de un for() esta expresado por 2n+2 considerando que el incremento es de 1 en 1, parte desde 1 y llega a n. Al analizar la complejidad de los for() anidados tenemos:

Esta base me permite realizar el siguiente análisis de complejidad a 2 for() anidados:

En esta instrucción hay 1 asignación de complejidad En este for() hay 2n + 2 de complejidad En este for() hay (2n + 2) * n de complejidad, esta multiplicación por n se da ya que por cada ciclo del for() externo controlado por i se realiza el for() interno controlado por k En esta instrucción hay nn* de complejidad, tenga en cuenta que se repite n veces por el for() interno controlado por k y n veces que este for() se repite por el for() externo controlado por i 1 asignación + 2n + 2 del primer for + (2n+2)n del segundo for + nn de incremento de c = 1 + 2n + 2 + (2n+2)n + nn = 3 + 2n + 2n^2 + 2n + n^2 = 3 n^2 + 4n + 3  Este es el resultado completo del proceso expresado de forma calculable, pero si se desea encontrar la  complejidad computacional basado en el resultado del proceso (c++) se aplica una  simplificación asíntota que omite las contantes y se mantiene el de mayor tasa de crecimiento 3 n^2 = n^2 4 n = n 3 = 0 = n^2 + n  se toma el que tiene mayor tasa de crecimiento para expresar la complejidad T(c) = n^2 Se podría sustituir n^2 por 10^2 y obtendríamos 100 que es el número de veces que c se incrementaría

i=1; while (i < n) { i*=2; } Definición de complejidad y su medida Para el siguiente análisis se utilizará el control de repetición while() como instrumento de análisis y el caso de un crecimiento de control exponencial para obtener una expresión calculable de comparación (i < n), para verificar este proceso considere que n tiene un valor de 10. 1 2 4 8 16

i

Observe que el crecimiento es exponencial, por lo tanto los valores de i tendrían las siguientes expresiones: 20 21 22 23 24 La condición (i<n) por cada validación estaría estructurada de la siguiente forma (2^0 <n) (2^1 <n) (2^2 <n) (2^3 <n) (2^4 <n) (2x^ <n)

(2x)

Para trabajar con potencia se utilizan los logaritmos para generar este tipo de expresiones: 2 3 = 8  log 2 8 = 3 La base de la potencia se convierte en base del logaritmo El exponente se convierte en logaritmo (2x^ < n) se aplica logaritmo en ambos extremos de la comparación (log 2 2 x^ < log 2 n) (x < log 2 n)  esta sería la complejidad de la condición del while() conforme al ejemplo (log 2 2 x^ < log 2 n)  Se separa el exponente y se calcula log 22 el resultado es 1 21 = 2 , expresado así: x log 22 1 Si se desea mostrar la expresión matemática de todo el proceso sería así:

i=1;

while (i < n){

i*=2;

En esta instrucción hay 1 asignación de complejidad En esta instrucción hay log 2 n + 1 de comparaciones En esta instrucción hay log 2 n de multiplicaciones = 1 + log 2 n + 1 + log 2 n = 2 + log 2 n + log 2 n = 2 + 2log 2 n  esta sería la complejidad del proceso

Definición de complejidad y su medida Algunas metodologías aplican mayores detalles para desarrollar los análisis de complejidad computacional, se basan en la diferenciación de tiempos que toman los diferentes proceso para cumplir con el propósito de la instrucción, para simplificar el cálculo, se hará una estimación de los costes (valores) de los algoritmos agrupando las operaciones realizadas en tres clases diferentes y asumiendo un coste temporal único para cada uno de ellos:

 Operaciones aritméticas: t

o

 Asignaciones: t

a

 Comparaciones: t

c t representa el total Alternativa 1. El siguiente proceso se basa en dos variables y un ciclo repetitivo : y = 0; i = 1; while (i <= 100) { y = y + x; i = i + 1; } 100 *(to+ta)

= 202 ta + 10 1 tc + 200 to

Alternativa 2. En realidad el problema se puede resolver fácilmente ya que sumar cien veces la variable x es análogo a multiplicar x por 100: y = 100 * x; (^) = 1 t o + 1^ ta Para probar el análisis de complejidad computacional mediante estos tipos de métricas, asuma que se desea generar un proceso que acumule en una variable la suma de un número 100 veces 1 ta 1 ta 100*tc + 1 tc (comparaciones del bucle) 100 *(to+ta)

= 1 ta + 1 ta + 100tc+ 1 tc + 100(to+ta) + 100(to+ta)

= 2 ta + 10 1 tc+ 100 to+ 100 ta + 100 to+ 100 ta

Esta expresión se puede simplificar en una sola operación:

Si podemos llegar a una conclusión, definitivamente diríamos que el tiempo de la alternativa 2 siempre será inferior al tiempo

de la primer alternativa.

Definición de complejidad y su medida Ahora considere el mismo procedimiento de la diapositiva anterior pero utilizando n como límite de repetición: y = 0; i = 1; while (i <= n) { y = y + x; i = i + 1; } n(to+ta) 1 ta 1 ta ntc + 1 tc n*(to+ta)

= 1 ta + 1 ta + ntc+ 1 tc + n(to+ta) + n(to+ta)

= 2 ta + ntc+ tc + nto+nta + nto+nta

= 2 ta + tc+ n(tc + to+ ta + to + ta)

= 2 ta + tc+ n(tc + 2 to+ 2 ta)

Como era de esperar, el tiempo total que consumirá el algoritmo para obtener el resultado depende del valor n , que es una entrada del algoritmo. De manera que, el coste temporal del algoritmo será distinto para diferentes valores de n. El siguiente proceso se trata de una algoritmo que realiza una búsqueda secuencial, la función asume que los datos son de tipo entero y que, como resultado de la búsqueda, sólo interesa saber si elemento x está o no en el vector.

boolean BusquedaSecuencial (Vector v, int n, int x) {

int i;

boolean enc = false;

i = 0;

while (i < n) {

if (v[i] == x)

enc = true;

i = i + 1;

return enc;

// v es el vector, n es el número de elementos en el vector, x es el dato buscado ntc 1 ta ntc + 1 tc n*(to+ta) 1 ta ¿? Observe que no sabemos cuantas veces se ejecutará esta asignación porque dependerá de la condición En este punto es donde aparece el concepto de mejor caso, peor caso y caso medio ya que dependerá del valor de entrada x (dato buscado) y de los elementos almacenados en el vector Se dice que un algoritmo tiene un mejor caso cuando los parámetros del problema lleven a realizar el menor número de pasos posibles, se representará por Tm Se dice que un algoritmo tiene un peor caso cuando los parámetros del problema lleven a realizar el máximo número de pasos posibles, se representará por Tp Por último, el caso medio (o coste esperado) de un algoritmo vendrá expresado por la media de pasos realizados en función de todos los casos posibles (básicamente se deben analizar todos los casos posibles teniendo en cuenta la probabilidad de que ocurra cada uno de esos casos), el tiempo medio se representará por Tμ^.

boolean BusquedaSecuencial (Vector v, int n, int x) { int i; i = 0; while ( ( i < n ) && ( v[i] != x ) ){ i = i + 1; } if ( i == n ) return false; else return true; } Mejor y Peor Caso ( BÚSQUEDA SECUENCIAL CON PARADA) El algoritmo anterior es susceptible de ser mejorado de diferentes maneras. Una mejora obvia consiste en finalizar la búsqueda en el momento en que se encuentre el elemento buscado, ya que entonces no tiene sentido seguir con la búsqueda en el resto del vector Con esta modificación, el bucle debe controlar dos condiciones, que representan los dos motivos por los que se puede finalizar la búsqueda:  (^) Porque se ha encontrado el elemento o  (^) Porque se ha alcanzado el final del vector sin encontrarlo. Esta condición tiene 3 operaciones de comparación 1era^ (i < n) , 2da^ (v[i] != x) y la 3era^ que es la unión de la primera y la segunda mediante && El mejor caso se da cuando el elemento x se encuentra en la primera posición del vector, por lo tanto T m = 1ta + 4tc El peor caso se dará cuando el elemento x no se encuentra en el vector y, por tanto, es preciso comprobar hasta el final todos sus elementos Al realizar la primera condición dará verdadero, la segunda dará falso porque se supone que el valor de la primera posición es el buscado, es decir, el valor de la posición v[0] es igual que el valor de x , observe que la condición verifica si son diferentes, así la respuesta es falso. La tercera operación lógica (verdadero && falso) la respuesta será falso, así que la complejidad computacional será: En este caso siempre se dará verdadero en todas las comparaciones de la condición del while a excepción de la última comparación, cuando i por efecto del incremento es igual que n, en este caso el lenguaje C, C#, Java y otros lenguajes de programación, cuando existe operaciones And (&&) si la primera es falso no evalúa las otras y el resultado será falso, así que la complejidad computacional será: Tp^ = 1 ta + n(tc + tc + tc) + 1 tc + n(to+ta) + 1 tc Tp**^ = ta + n (3tc) + nto + nta + 2 tc Tp^ = (ta + nta) + (3ntc + 2 tc) + nto Tp^ = ta(1+ n) + tc(3n + 2) + nto

boolean BusquedaSecuencial (Vector v, int n, int x) { int i; i = 0; v[n] = x; while ( v[i] != x ) { i = i + 1; } if ( i == n ) return false; else return true; } Mejor y Peor Caso (BÚSQUEDA SECUENCIAL CON CENTINELA) En el algoritmo anterior se plantean condiciones que comprueban que el índice permanezca en el rango adecuado (es decir, entre 0 y n-1) para que la búsqueda no continúe fuera de este rango. Como una estrategia de desarrollo se propone que, esta comprobación no sea necesaria si se pudiera asegurar que se va a encontrar el elemento buscado. Con esta técnica se puede estar seguro de encontrar el elemento, si se ubica “manualmente” en una posición estratégica del vector, por ejemplo, en la posición n (la última posición) a esta estrategia se le conoce con el nombre búsqueda con centinela El mejor caso se da cuando el elemento x se encuentra en la primera posición del vector, por lo tanto

Tm^ = 2ta + 2tc

Al evaluar la condición del while por primera vez dará falso, así que la complejidad computacional será: El peor caso se dará cuando el elemento x no se encuentra en el vector y, por tanto, es preciso comprobar hasta ubicarse en la posición n del centinela al final de todos los elementos Tp^ = 2 ta + n (tc) + n(to+ta) + 1 tc Tp*^ = 2 ta + ntc + nto + nta + tc Tp^ = (ta + nta) + (ntc + tc) + nto Tp^ = ta(1+ n) + tc(n + 1) + nto Notará que este algoritmo en el peor de los casos es más eficiente que el algoritmo anterior Peor Caso: Para vectores de tamaño n , las entradas que hacen que el algoritmo trabaje más son aquellas en que el valor buscado no se encuentra en el vector: Tpeor( n ) = n comparaciones Tpeor(n) = máx{ T(n, entrada) } para toda entrada de Tamaño n. Mejor Caso: Las entradas que hacen que el algoritmo trabaje menos son aquellas en que el valor buscado está en la primera posición del vector. Tmejor( n ) = 1 comparación Tmejor(n) = min{ T(n, entrada) }

public int[] arrayt(int[] A) { int []B; int i, total=0; for(i=0; i<A.length; i++){ B[i]=A[i]; total+=A[i]; } for (i = 0; i< A.length; i++){ B[i] = total - A[i]; } return B; } Desarrollo de un problema Dado un arreglo A de longitud n, genere un nuevo arreglo, también de longitud n, tal que el i -ésimo elemento contenga el resultado de sumar todos los elementos de la lista excepto él mismo. Cumpliendo con el requerimiento del enunciado obtendríamos el siguiente vector resultado B: [66, 63, 53, 55, 66, 55, 51, 67] Entrada del vector A: [2, 5, 15, 13, 2, 13, 17, 1] Si realizamos la suma de los elementos de este vector expresado en función de la operación tendríamos: sum(A) = 68 2n+2 complejidad del for 1 asignación n número de veces que se ejecutará = 1 + 2n + 2 + n + n + 2n + 2 + n = 7n + 5

T(n) = an + b

Considere el siguiente proceso de eficiencia: El resultado se lo puede expresar de forma algebraica con la función lineal: n número de veces que se ejecutará 2n+2 complejidad del for n número de veces que se ejecutará

COMPLEJIDAD ALGORÍTMICA UTILIZANDO PROPIEDADES ASINTÓTICAS

Los algoritmos existen para resolver un problema particular de manera eficiente pero ¿qué significa que un algoritmo sea eficiente? o ¿bajo qué métrica podemos concluir que una solución es más eficiente que otra? o predecir la cantidad de recursos que éste ocupará durante su ejecución, como ¿cuánta memoria RAM? ¿qué tanto ancho de banda? o incluso ¿qué otras partes del hardware utilizará y en qué medida? , responder éstas preguntas es el campo de estudio del análisis de algoritmos , considere que el interés estará basado en predecir en vez de obtener resultados exactos. En computación, la notación asintótica nos permite representar la complejidad, y por ende la eficiencia, de un algoritmo, de tal manera que podemos proyectar el aumento de operaciones requeridas al aumentar el tamaño de la entrada, es decir, cuando n crece o tiende al infinito.

  1. K*n = n (K es una constante)
  2. n/k = n (K es una constante)
  3. nk+ nz^ = nk^ (solo si k>z)
  4. nk+ nz^ = nz^ (solo si z>k) Debemos considerar que cada vez que se aplica un análisis de complejidad a los diferentes algoritmos, el resultado nos dará una expresión polinómica diferente, aplicando notaciones asintótica se logra simplificar y definir la tendencia de crecimiento para concluir cuan eficiente es un algoritmo, la simplificación se logra aplicando las siguientes propiedades: f(x) = 2x^2 + 5x + 3 f(x) = x^2 + x  se eliminaron las constantes ( 1 ) f(x) = x^2 tomara la de mayor peso ya que es la tendencia de crecimiento Por ejemplo, si se desea simplificar el siguiente polinomio aplicando notaciones asíntotas: Una vez que se tiene la notación asintótica se puede analizar cuan eficiente es el algoritmo considerando la siguiente tabla de eficiencia de forma descendente en base al entradas EFICIENCIA DE UN ALGORITMO BASADO EN TIEMPOS DE EJECUCIÓN 1 Entrada con valores constantes (Más eficiente) Log n Resultados logarítmicos n Resultado con tendencia lineal N log n Logarítmico lineal n^2 Cuadrático N^3 Cúbico 2 n^ Exponencial (Menos eficiente) El análisis de los dos últimos algoritmos arrojaron los siguientes resultados: El primer algoritmo dio como resultado = 4n^2 + 5n + 3 así que al aplicar simplificación asintótica: f(n)=n^2 que significa que es cuadrática. El segundo algoritmo dio como resultado = 7n + 5 así que al aplicar simplificación asintótica: f(n)=n que significa que es lineal. Por lo tanto el segundo algoritmo es más eficiente que el primero como muestra la tabla