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


tema2, Apuntes de Informática

Asignatura: Metodologia de la Programación, Profesor: , Carrera: I. T. Infor. Sistemas, Universidad: UCA

Tipo: Apuntes

Antes del 2010

Subido el 30/08/2008

josellle
josellle 🇪🇸

4.4

(60)

148 documentos

1 / 5

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
1
Metodología de la Programación
Ingeniería Técnica en Informática de Gestión
Ingeniería Técnica en Informática de Sistemas
Guión de Prácticas Nº 2
ANÁLISIS DE ALGORITMOS 1
Objetivos
Conocer los fundamentos del análisis empírico o experimental de algoritmos.
Comparar los tiempos de ejecución de dos algoritmos de ordenación y extraer
conclusiones sobre la eficiencia temporal de ambos.
Explicar los resultados experimentales justificándolos mediante la teoría
estudiada.
En las prácticas de este tema, sería conveniente que el alumno:
- Realizara el problema y cuestiones que se le plantea.
Medida del tiempo de ejecución
clock_t clock (void);
La función de la biblioteca estándar de C clock() (declarada en el fichero de
cabecera time.h) devuelve el tiempo aproximado (en pulsos o ciclos) que se ha estado
ejecutando el programa que la llama. El tiempo correspondiente a un pulso depende del
sistema (arquitectura, sistema operativo, compilador, etc.), pero se puede transformar en
segundos dividiéndolo por la constante CLOCKS_PER_SEC (también definida en
time.h).
El siguiente código calcula el tiempo (en segundos) que tarda en ejecutarse una
función llamada fun():
clock_t t1, t2 ;
double tiempo;
t1 = clock();
fun();
t2 = clock();
tiempo = (double)(t2 – t1) / CLOCKS_PER_SEC;
printf("Tiempo de ejecución de fun(): %Lf segundos\n", tiempo);
Si el tiempo de ejecución de la función fun() es menor que la resolución de la
función clock(), es decir, menos de un pulso, entonces no es posible obtener el tiempo
real de ejecución. Para solventar este problema podemos realizar una medida indirecta,
ejecutando varias veces fun() y dividiendo el tiempo total empleado por el número de
veces que se haya ejecutado la función.
1 Última modificación: Viernes, 23 de Febrero de 2007
pf3
pf4
pf5

Vista previa parcial del texto

¡Descarga tema2 y más Apuntes en PDF de Informática solo en Docsity!

Metodología de la Programación

Ingeniería Técnica en Informática de Gestión Ingeniería Técnica en Informática de Sistemas

Guión de Prácticas Nº 2

ANÁLISIS DE ALGORITMOS

1

Objetivos

  • Conocer los fundamentos del análisis empírico o experimental de algoritmos.
  • Comparar los tiempos de ejecución de dos algoritmos de ordenación y extraer conclusiones sobre la eficiencia temporal de ambos.
  • Explicar los resultados experimentales justificándolos mediante la teoría estudiada.

En las prácticas de este tema, sería conveniente que el alumno:

  • Realizara el problema y cuestiones que se le plantea.

Medida del tiempo de ejecución

clock_t clock (void); La función de la biblioteca estándar de C clock() (declarada en el fichero de cabecera time.h ) devuelve el tiempo aproximado (en pulsos o ciclos) que se ha estado ejecutando el programa que la llama. El tiempo correspondiente a un pulso depende del sistema (arquitectura, sistema operativo, compilador, etc.), pero se puede transformar en segundos dividiéndolo por la constante CLOCKS_PER_SEC (también definida en time.h ).

El siguiente código calcula el tiempo (en segundos) que tarda en ejecutarse una función llamada fun() :

clock_t t1, t2 ; double tiempo;

t1 = clock(); fun(); t2 = clock(); tiempo = (double)(t2 – t1) / CLOCKS_PER_SEC; printf("Tiempo de ejecución de fun(): %Lf segundos\n", tiempo); Si el tiempo de ejecución de la función fun() es menor que la resolución de la función clock() , es decir, menos de un pulso, entonces no es posible obtener el tiempo real de ejecución. Para solventar este problema podemos realizar una medida indirecta, ejecutando varias veces fun() y dividiendo el tiempo total empleado por el número de veces que se haya ejecutado la función.

(^1) Última modificación: Viernes, 23 de Febrero de 2007

Generación de números pseudoaleatorios

int rand (void); Esta función, declarada en stdlib.h , genera una secuencia de números pseudoaleatorios. Cada vez que se llama, devuelve un entero entre 0 y RAND_MAX.

Se llaman números pseudoaleatorios porque la serie generada depende del valor inicial, el cual se denomina semilla. Esto quiere decir que los números no se obtienen realmente al azar, sino que se puede obtener la misma serie tantas veces como se quiera, siempre que se parta de la misma semilla. Sin embargo, cada serie generada parece ser aleatoria porque el orden de los números no aparenta seguir ninguna ley.

void srand (unsigned semilla); Con esta función se establece la semilla del generador de números pseudoaleatorios utilizado por la función rand(). Si no se llama a srand() , el generador actúa como si la semilla fuese 1.

Para obtener una serie diferente de números en cada ejecución del programa, basta con partir de una semilla distinta cada vez. Una forma de conseguir esto es establecer la semilla a partir de la hora del sistema, la cual devuelve la función time() (declarada en time.h), como se muestra a continuación:

srand((unsigned)time(NULL));

Ordenación

El problema que queremos resolver consiste en ordenar un vector V de n números enteros. Para ello analizaremos dos algoritmos simples llamados ordenación por selección y ordenación por inserción.

El algoritmo de ordenación por selección se basa en una idea muy sencilla: Se recorre el vector n-1 veces, seleccionando en cada recorrido el más pequeño de los valores todavía no ordenados para colocarlo en su posición.

const n = 100000 // Por ejemplo. Valor suficiente para nuestro problema en particular. tipo vector [n] de entero: Vect_ent

procedimiento selección (E/S Vect_ent: V, E entero: nitems) var entero: i, j, i_min, temp inicio desde i ← 1 hasta nitems-1 hacer i_min ← i

Problema

El objetivo es escribir un programa que ordene dos vectores iguales de números enteros, uno mediante el algoritmo de selección y el otro con el de inserción, e imprima en pantalla el tiempo de ejecución (en segundos con 5 decimales) de ambos algoritmos.

El programa presentará un menú en pantalla con cuatro opciones:

  1. Mejor caso
  2. Caso promedio
  3. Peor caso
  4. Salir Las tres primeras opciones servirán para calcular los tiempos de ejecución de ambos algoritmos en el caso correspondiente. Una vez que el usuario haya seleccionado la opción deseada, el programa leerá de la entrada estándar el número de valores a ordenar, o lo que es lo mismo, el tamaño de los vectores, y a continuación generará un ejemplar aleatorio de estos vectores, según el caso elegido.

Los ejemplares del vector de entrada para cada algoritmo son los siguientes:

  • Mejor caso : Un vector que no requiera ningún intercambio de sus valores, es decir, un vector ya ordenado.
  • Peor caso : Para el algoritmo de selección consiste en un vector en el que ningún valor esté en su lugar según el orden que se desee (ascendente o descendente). Entre otros muchos ejemplares, puede servir, por ejemplo, un vector en orden inverso. El caso más desfavorable para el algoritmo de inserción es el que obligue a realizar el máximo número de intercambios. Éste es un vector en orden inverso.
  • Caso promedio : Es más difícil encontrar un vector de entrada adecuado para este caso. Así que lo que haremos será obtener una aproximación del tiempo medio de ejecución probando cada algoritmo n veces (por ejemplo, n = 10) con diferentes vectores de entrada (pero del mismo tamaño) y calculando la media de los n tiempos empleados. Para cada uno de los n experimentos, el programa generará los valores a ordenar de forma aleatoria.

CONSIDERACIONES:

o Cada una de las pruebas ha de repetirse un número suficiente de veces , sobre todo si el tamaño del problema es pequeño (vector de 100, 500 e incluso 1000 enteros), entonces posiblemente habrá que repetir la misma prueba del orden de 500, 1000 o más veces para poder medir el tiempo empleado en ordenar el vector, ya que puede tardar menos de un pulso del reloj. o En cada repetición de una prueba se debe ordenar exactamente el mismo vector de entrada , de lo contrario los resultados del análisis pueden no ser significativos.

o Igualmente, si lo que se desea es realizar una comparación de los tiempos que tardan en ejecutarse dos algoritmos que resuelven el mismo problema (el de ordenar un conjunto de elementos), entonces hay que probarlos exactamente sobre los mismos valores de entrada , es decir, sobre el mismo vector, no basta con hacerlo sobre entradas del mismo tamaño.

Cuestiones

1.- Escribe en tres tablas (mejor caso, caso promedio y peor caso) el tiempo empleado por ambos algoritmos para ordenar vectores de tamaño 100, 500, 1.000, 5.000, 10.000, 50.000 y 100.000.

2.- ¿Hay una diferencia clara a favor de alguno de los dos algoritmos probados? ¿En todos los casos? ¿Por qué?

3.- Calcula una estimación de las constantes de proporcionalidad c (^) s (ordenación de selección) y c (^) i (ordenación por inserción) para los casos peor y promedio, tales que t (^) s (n)c (^) s n^2 , si n ≥ 100 t (^) i (n)c (^) i n^2 , si n ≥ 100 y para el mejor caso, tales que t (^) s (n)c (^) s n^2 , si n ≥ 100 t (^) i (n)c (^) i n , si n ≥ 100 ¿Qué significa todo esto?

4.- A la vista de estos datos, realiza una estimación del tiempo necesario para ordenar un vector aleatorio de 1.000.000 de enteros.

5.- Realiza los experimentos de la pregunta 1 para el caso promedio en dos ordenadores diferentes, por ejemplo en el laboratorio y en casa, especificando las características de los equipos, sistemas operativos y compiladores usados. a. Compara los resultados obtenidos con el algoritmo de selección en ambas máquinas y observa que los tiempos de uno y otro ordenador se diferencian en un factor constante. Calcula este factor de ganancia/pérdida y explica a qué se debe que sea constante. b. Calcula el factor de ganancia/pérdida en el tiempo de ejecución de un ordenador respecto al otro para el algoritmo de inserción. ¿Es igual que el anterior? ¿Por qué? c. ¿Es significativo este factor frente al número de valores ordenados? ¿Qué influye más en los tiempos obtenidos, el ordenador o la cantidad de valores ordenados? ¿Por qué?

6.- En un problema real, ¿cuál de los dos algoritmos de ordenación escogerías pensando básicamente en sus costes en tiempo? ¿Por qué?