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 Algoritmos: Complejidad Temporal y Espacial, Guías, Proyectos, Investigaciones de Programación Java

ejercicios, evaluacion,. trabajo, colaborativo

Tipo: Guías, Proyectos, Investigaciones

2019/2020

Subido el 07/10/2020

yefred
yefred 🇨🇴

4.2

(6)

9 documentos

1 / 14

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
Palabras clave: eficiencia, orden, complejidad, notación.
Contenido
1
2
3
4
5
Complejidad temporal y espacial
Reglas para el cálculo de complejidad
Otras notaciones asintóticas diferentes a la O grande
Notación asintótica y notación O grande
Principales órdenes de complejidad
Análisis de algoritmos
Unidad 1 / Escenario 2
Lectura fundamental
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe

Vista previa parcial del texto

¡Descarga Análisis de Algoritmos: Complejidad Temporal y Espacial y más Guías, Proyectos, Investigaciones en PDF de Programación Java solo en Docsity!

Palabras clave : eficiencia, orden, complejidad, notación.

Contenido

Complejidad temporal y espacial

Reglas para el cálculo de complejidad

Otras notaciones asintóticas diferentes a la O grande

Notación asintótica y notación O grande

Principales órdenes de complejidad

Análisis de algoritmos

Unidad 1 / E scenario 2

Lectura fundamental

Toda persona que haya trabajado suficiente tiempo desarrollando programas, se habrá preguntado alguna vez: ¿qué tan demorado será mi programa? ¿Cuál solución será más eficiente, la mía o la de mi amigo? ¿Qué tantos recursos consumirá mi programa? ¿De qué manera depende el consumo de tiempo respecto al tamaño del problema a resolver? ¿Habrá algoritmos más eficientes que el que acabé de desarrollar?

Es conocido que la ejecución de todo algoritmo demanda recursos computacionales, entre estos:

  • Procesador: se refleja en el consumo de tiempo utilizado para ejecutar las instrucciones del programa.
  • Memoria RAM: se refleja en el consumo de espacio ocupado por las variables del programa.
  • Disco duro.
  • Recursos de red.

Respecto a un recurso computacional, la complejidad de un algoritmo representa la cantidad del

recurso que el programa demanda para su ejecución. La demanda de procesador se mide por

medio de la complejidad temporal, mientras que la demanda de memoria RAM se mide mediante

la complejidad espacial. No solamente estas dos medidas pueden llevarse a cabo, pero son las más

relevantes y las más usuales. Es mucho más frecuente el análisis de tiempo que el de espacio,

por ello, cuando se encuentren ejemplos en textos y otras fuentes, se debería asumir que se habla

de complejidad temporal, a menos que se indique lo contrario.

Cómo mejorar...

En este punto, es muy importante tener claros los conceptos de problema y algoritmo que se propusieron en el módulo de Pensamiento Algorítmico. De la misma forma, se deben conocer los fundamentos y las estructuras de control que fueron cubiertas en el módulo de Programación de Computadores. Le sugiero repasar los puntos que estime podrían necesitar un refuerzo, de esa forma, el tema que aquí se introduce será comprendido con mayor facilidad.

B. Encuentre una función que relacione el tamaño del problema con el número de variables declaradas en el programa. Esta función refleja la complejidad espacial porque entre más variables se declaren, más espacio en memoria RAM requeriría el algoritmo para ejecutarse.

En pocas palabras, la complejidad temporal mide el tiempo empleado y la complejidad espacial mide el espacio requerido.

2. Notación asintótica y notación O grande

La notación asintótica es una forma de representación que permite describir la eficiencia de un algoritmo en función de su tasa de crecimiento, es decir, proyecta el comportamiento del algoritmo conforme al aumento del tamaño de sus entradas. El término asintótica se deriva del hecho de que proyecta el comportamiento de cada solución a entradas de gran tamaño. Su uso principal es la comparación de un conjunto de algoritmos para determinar niveles de complejidad.

La notación asintótica O grande (es la letra O del alfabeto, no un cero) se centra en un análisis del peor caso (Cormen, Leiserson, Rivest, & Stein, 2009), es decir, en el escenario más adverso imaginable, que haga que la función ejecute el máximo número de operaciones posible. Puede usarse para describir tanto complejidad temporal como espacial.

¿Sabía que...?

En ciencias de la computación y en general en ingeniería, muchas veces se utilizan los conceptos sin traducir del inglés. En este caso particular, algunos textos mostrarán el término Big O a pesar de estar escritos en español. Esta situación es recurrente y por ello el estudiante debería tener una preparación fuerte en el idioma inglés o al menos dominar los términos asociados a su programa de estudio.

Dada una función f(n) se dice que un algoritmo tiene complejidad temporal O(f(n)) si la cantidad de operaciones que ejecuta siempre está por debajo de un múltiplo constante de f(n), para un valor grande de n. Similarmente, se define para la complejidad espacial, pero sobre la cantidad de variables declaradas.

Como es más costoso el recurso de tiempo que el de espacio, resulta más valioso realizar el cálculo de la complejidad temporal, por lo tanto, de aquí en adelante se hará énfasis en él.

3. Reglas para el cálculo de complejidad

El cálculo de la complejidad es un proceso que puede realizarse de forma relativamente sencilla si se atiende al siguiente conjunto de reglas:

A. Para calcular la complejidad temporal de una secuencia de instrucciones en Java como la mostrada en la figura 1, se debe hallar la complejidad de cada instrucción por separado y tomar la más grande de estas.

Figura 1. Representación de un conjunto instrucciones secuenciales Fuente : elaboración propia

B. Para calcular la complejidad temporal de una asignación en Java como la ilustrada en la figura 2, hay que hallar la complejidad del cálculo de la expresión que está siendo asignada.

Figura 2. Representación de una asignación Fuente : elaboración propia

C. Para calcular la complejidad temporal de un condicional en Java como en la figura 3, hay que hallar la complejidad de evaluar la condición de cada instrucción por separado y tomar la más grande de estas.

instrucción 1; instrucción 2; instrucción 3; ... instrucción x;

Variable=expresión;

4. Principales órdenes de complejidad

Existen múltiples órdenes para clasificar la complejidad de los algoritmos; sin embargo, hay un

conjunto de ellos que es más común que los demás. A continuación, se realiza su presentación en

orden creciente, es decir, entre más cerca del final de la lista esté el orden de complejidad, es menos

eficiente respecto a los órdenes que le preceden. Es importante notar la forma en que las reglas

expuestas en el apartado anterior son aplicadas.

4.1. Orden constante O(1)

Representa la complejidad de un algoritmo que se ejecutará siempre en el mismo tiempo o espacio,

sin importar el tamaño de las entradas. La figura 5 es un ejemplo de un algoritmo con complejidad O(1).

static double calcularArea( double r) { return Math. PI * r * r; }

Figura 5. Método en Java con complejidad de orden constante Fuente : elaboración propia

4.2. Orden logarítmico O(log n)

Representa la complejidad de un algoritmo cuyo tiempo de ejecución se incrementará más lentamente

a medida que el tamaño del conjunto de entradas aumente. La figura 6 es un ejemplo de un algoritmo

que realiza una búsqueda binaria. Como el algoritmo hace divisiones sucesivas de dos para fraccionar

el arreglo, se vuelve comparativamente más eficiente a medida que el tamaño del arreglo aumenta.

static int busquedaBinaria( int arreglo[], int x) { int centro,inferior=0,superior=arreglo.length-1; while (inferior<=superior){ centro=(superior-inferior)/2+inferior; if (arreglo[centro]==x) return centro; else if (x < arreglo[centro]) superior=centro-1; else inferior=centro+1; } return -1; }

Figura 6. Método en Java con complejidad de orden logarítmico Fuente : elaboración propia

4.3. Orden lineal O(n)

Representa la complejidad de un algoritmo que se ejecutará en un tiempo que crecerá linealmente, en proporción directa con el tamaño del conjunto de entradas. Se asume el peor caso, que en la figura 7 consistiría en la ejecución del máximo número de iteraciones posible.

static int busquedaSimple( int arreglo[], int x) { for ( int i=0; i<arreglo.length; i++){ if (x==arreglo[i]) { return i; } } return -1; } Figura 7. Método en Java con complejidad de orden lineal Fuente : elaboración propia

4.5. Orden cuadrático O(n2)

Representa la complejidad de un algoritmo que se ejecutará en un tiempo que crecerá en proporción directa con el cuadrado del tamaño del conjunto de entradas. Como siempre, para la notación O, se asume el peor caso, que en la figura 9 sería la ejecución del máximo número de iteraciones posible.

static boolean busquedaSimpleMatrizCuadrada( int matriz[][], int x) { for ( int i=0; i<matriz.length; i++){ for ( int j=0; j<matriz.length; j++){ if (x==matriz[i][j]) { return true ; } } } return false ; } Figura 9. Método en Java con complejidad de orden cuadrático Fuente : elaboración propia

4.6. Orden exponencial O(an)

Representa la complejidad de un algoritmo que se ejecutará en un tiempo que crecerá en un factor

de a con cada adición al conjunto de datos de entrada. Proporción directa con el cuadrado del tamaño

del conjunto de entradas. El ejemplo de la figura 10 representa un algoritmo de complejidad O(2n)

pues cada nueva entrada dobla el tiempo de ejecución.

static int fibonacci( int n) { if (n==1 || n==2) { r eturn 1; } else { return fibonacci (n-1) + fibonacci (n-2); } } Figura 10. Método en Java con complejidad de orden exponencial Fuente : elaboración propia

5. Otras notaciones asintóticas diferentes a la O grande

En muchas situaciones, el peor caso de un algoritmo ocurre solo en situaciones extraordinarias. Tómese por ejemplo un algoritmo cualquiera con complejidad temporal O(n2), que el 99.999% de las veces se comporta como si tuviera complejidad temporal O(n), pero, que en el 0.001% restante alcanza su peor caso y adquiere la complejidad temporal de O(n2). Parece como si se estuviera castigando excesivamente la medida de eficiencia de un algoritmo por algo que ocurrirá con poca probabilidad. Por esta razón, hay otros dos tipos de análisis que se pueden hacer sobre los algoritmos y que son válidos tanto para el tiempo de ejecución como para el espacio en memoria empleado.

5.7. Notación asintótica Ω grande

La notación asintótica Ω grande (la letra griega Omega), se centra en analizar el mejor caso (Cormen, Leiserson, Rivest, & Stein, 2009), es decir, en el escenario que se ejecuta el mínimo número de operaciones posible. Dada una función f(n) se dice que un algoritmo tiene complejidad temporal Ω (f(n)) si la cantidad de operaciones que ejecuta siempre está por encima de un múltiplo constante de f(n) , para un valor grande de n.

5.8. Notación asintótica Θ grande

La notación asintótica Θ grande (la letra griega Theta) se usa para describir la tasa de crecimiento en

el mejor y el peor caso del tiempo de ejecución, o el espacio de memoria empleado, de un algoritmo

cuando la tasa es la misma. Dada una función f(n) se dice que un algoritmo tiene complejidad

temporal Θ (f(n)) si y solo si el orden de complejidad en el mejor escenario es Ω (f(n)) y el orden de

complejidad en el peor escenario es O(f(n)).

Referencias

Cormen, T ., L eiserson, C ., Rivest, R., & S tein, C. ( 2009). Introduction to algorithms. Cambridge: The MIT Press.

Sotelo Arévalo, A. (s.f.). Análisis de algoritmos. Bogotá, Colombia.

INFORMACIÓN TÉCNICA

Módulo: Estructura de Datos

Unidad 1: Fundamentos de estructuras de datos

Escenario 2: Análisis de algoritmos

Autor: Javier Fernando Niño Velásquez

Asesor Pedagógico: Heidy Liliana Moncada

Diseñador Gráfico: Nicolás Jiménez O.

Asistente: Ginna Quiroga

Este material pertenece al Politécnico Grancolombiano. Prohibida su reproducción total o parcial.