Vous êtes sur la page 1sur 12

Prctica 1_Eficiencia de Algoritmos

FAA_1 Grado Ingeniera Informtica_Curso 2014-15

1.

Objetivo. ............................................................................................................................ 2

2.

Introduccin. Anlisis de algoritmos. ................................................................................. 2

3.

Enunciado. ........................................................................................................................ 2

4.

Estudio prctico. ............................................................................................................... 2


4.1.

Clculo del Tiempo Terico ....................................................................................... 2

4.1.1.

4.1.1.1.

Caso mejor. ............................................................................................... 3

4.1.1.2.

Caso peor. ................................................................................................. 3

4.1.1.3.

Caso medio. ............................................................................................... 3

4.1.1.4.

Conclusin: ................................................................................................ 3

4.1.2.

4.2.

ALGORITMO DE BSQUEDA SECUENCIAL. .................................................. 2

ALGORITMO DE ORDENACIN POR BURBUJA ............................................ 4

4.1.2.1.

Caso mejor. ............................................................................................... 4

4.1.2.2.

Caso peor .................................................................................................. 5

4.1.2.3.

Caso medio. .............................................................................................. 5

4.1.2.4.

Conclusin: ................................................................................................ 5

Clculo del Tiempo de la Eficiencia Emprica ............................................................ 6

4.2.1.

Clculo del tiempo. ............................................................................................ 6

4.2.2.

Cmo Mostrar los Datos .................................................................................... 8

4.3. Definicin de la Clase base ConjuntoInt. ................................................................ 9


4.3.1.
4.4.

Programa Principal .......................................................................................... 10

Conclusiones. .......................................................................................................... 11

5.

Entrega de la prctica ..................................................................................................... 11

6.

Consideraciones para la implementacin ........................................................................ 12

1/12

Prctica 1_Eficiencia de Algoritmos


FAA_1 Grado Ingeniera Informtica_Curso 2014-15

1.

Objetivo.

El objetivo de estas sesiones es comprender la importancia de analizar la eficiencia de los algoritmos y


familiarizarse con las formas de llevarlo a cabo.
La prctica consiste en la programacin de una aplicacin que calcule el tiempo de ejecucin de dos
algoritmos.

2.

Introduccin. Anlisis de algoritmos.

Para analizar la eficiencia se mostrar como realizar un anlisis del algoritmo mediante estudio terico y
emprico. Este estudio ser requerido en el resto de prcticas de la asignatura.
El anlisis del algoritmo conlleva:
Estudio terico: En vista de la implementacin, habr que obtener la expresin de la funcin
complejidad temporal (T(n)) correspondiente al algoritmo.
Estudio Emprico: estudiar experimentalmente el comportamiento del algoritmo. Para ello mediremos
el tiempo para cada tamao dado de las entradas, obteniendo los puntos de la funcin complejidad para
los casos peor, mejor y medio (o nico si no es por casos).
Conclusin: para finalizar el anlisis habr que realizar una grfica para cada una de las tres funciones
obtenidas en el estudio emprico, si el anlisis es por casos (sino slo una), y comentarlas, es decir, si
son coherentes el resultado emprico con el terico obtenido, justificando la respuesta.

3.

Enunciado.

En esta prctica realizaremos el estudio terico y prctico para los algoritmos de Bsqueda Lineal
(secuencial) y Ordenacin por Burbuja vistos en clase.

4.

Estudio prctico.

4.1. Clculo del Tiempo Terico


A partir de la expresin del algoritmo, se aplicarn las reglas conocidas para contar el nmero de
operaciones que realiza un algoritmo. Este valor ser expresado como una funcin de T(n) que dar el
nmero de operaciones requeridas para un caso concreto del problema caracterizado por tener un
tamao n. El anlisis lo realizaremos para los casos mejor, peor y medio.
4.1.1. ALGORITMO DE BSQUEDA SECUENCIAL.
Para determinar el tiempo de ejecucin, calculamos primero el nmero de operaciones elementales
(OE) que se realizan:
lneas

1)
2)

int BusquedaSecuencial (int T[ ], int n, int valor)


{
int i=0;
while (T[i] != valor && i<n) {

n OE
1
4

3)
4)
5)

}
if (T[i]==valor)

6)
7)

return i;
else return -1;

1
1

i=i+1;

asignacin
Cond.Bucle(2comp.,1 acceso
vector, 1 lgica)
incremento y asignacin
1 condicin y 1 acceso al
vector
si la condicin se cumple
cuando la condicin
es falsa.

2/12

Prctica 1_Eficiencia de Algoritmos


FAA_1 Grado Ingeniera Informtica_Curso 2014-15
El tiempo de ejecucin del algoritmo ser:

TBSecuencial (n)= TAsig(1) + TBucle(2) + TSi(5) Para calcularlo lo haremos por partes:
TAsig(1) = 1
TSi(5) =

TcondSi+ TcuerpoSi = 1+mx/mn/medio(Treturn(67) )=2+1=3

TBucle(2) = TcondB + TsaltoB + (i=1;?) TcicloBucle


TcicloBucle = TcondB +TcuerpoB (=0slo instruccin de incremento del bucle)+ TincrementoB + TsaltoCicloB = 4+ 2 + 1 = 7
TBucle(2) = TcondB + TsaltoB + (i=1;?) TcicloBucle = 4+1+(i=1;?) 7=5+7(i=1;?)
TBSecuencial (n)= TAsig(1) + TBucle(2) + TSi(5) = 1+5+7 (i=1;?) +3= 9+7(i=1;?)
4.1.1.1. Caso mejor.
En el caso mejor para el algoritmo, se efectuar la lnea (1) y la lnea (2) que supone 4 OE Tras ellas la
funcin acaba ejecutando las lneas (5) a (7). En consecuencia, el ciclo del bucle no se ejecuta nunca:
(i=1;0) = 0 y por tanto,
TBSecuencial (n)= 9+7(i=1;0) =9
4.1.1.2. Caso peor.
En el caso peor sucede cuando el valor no se encuentra en el vector. Se efecta la lnea (1), el bucle se
repite n veces hasta que se cumple la segunda condicin, despus se efecta la condicin de la lnea
(5) y la funcin acaba al ejecutarse la lnea (7). Cada iteracin del bucle est compuesta por las lneas 2
(4OE) y 3(2OE), junto con una ejecucin adicional de la lnea (2) que es la que ocasiona la salida del
bucle. En consecuencia, el ciclo del bucle se ejecuta n veces:
(i=1;n)=n

y por tanto,

TBSecuencial (n)= 9+7(i=1;n) = 7n+9


4.1.1.3. Caso medio.
En el caso medio el bucle se ejecutar un n de veces entre 1 y n, y suponemos que cada una de ellas
tiene la misma probabilidad de suceder. En consecuencia, el ciclo del bucle se ejecuta n/2 veces:
(i=1;n/2) = n/2 y por tanto,
TBSecuencial (n)= 9+7(i=1;n/2) =9+7(n/2)= (7/2)n+9
4.1.1.4. Conclusin:

Su caso mejor se da cuando el elemento est en la primera posicin del vector O(n).

El caso peor se produce cuando el elemento no est en el vector.

El caso medio ocurre cuando consideramos equiprobables cada una de las posiciones en las
que puede encontrarse el elemento dentro del vector (incluyendo la posicin especial -1, que
indica que el elemento a buscar no se encuentra en el vector) pero ambos son de O(n).

3/12

Prctica 1_Eficiencia de Algoritmos


FAA_1 Grado Ingeniera Informtica_Curso 2014-15
4.1.2. ALGORITMO DE ORDENACIN POR BURBUJA
Para obtener el tiempo de ejecucin, calcularemos
elementales (OE) que se realizan:
lneas

1)

void burbuja(int T[],int n)


{
int i, j;
int aux;
for (i = 0; i < n 1 ; i++) {

2)
3)
5)
6)

2,2,1

if (T[j] < T[j-1]) {


aux = T[j] ;
T[j] = T[j-1] ;
T[j-1] = aux ;
}
} // bucle j
} // bucle i

4)

el

nmero

de operaciones

n OE

1,2,1

for (j = n-1; j > i ; j-- ) {

primero

en cada iteracin del bucle (ciclo i):


(2condicin+2incremento+1salto)
en cada iteracin del bucle (ciclo j):
1condicin+ 2incremento+ 1salto
1 resta, 2 accesos a un vector, 1 comparacin

2
4
3

4) a 6) slo se ejecutan si se cumple la condicin y realizan un


total de 9 OE

2,1,1

por la salida del bucle( inicializacin+condicin+salto)

1,2,1

por la salida del bucle(inicializacin+condicin+salto)

}
El tiempo del algoritmo ser el de ejecucin de la nica instruccin que tiene, el bucle para i:
TBurbuja (n)= TBi (n). Para calcularlo lo haremos por partes:

TcuerpoSi =2+4+3=9 (si se cumple la condicin sumarlo!!)


TcondSi= 4
TSi =TcondSi+ TcuerpoSi
TcuerpoBj = TSi = TcondSi+ TcuerpoSi = 4 + TcuerpoSi (es cte!!)
TcicloBj = TcondBj +TcuerpoBj + TincrementoBj + TsaltoCicloBj = 1+ TcuerpoBj +2 + 1 = 4+ TcuerpoBj
TBj = TiniBj + TcondBj + TsaltoBj + (j=n-1;i) TcicloBj = 2 + 1 +1 + (j=n-1;i) (4+TcuerpoBj)= 4+(n-i)(4+TcuerpoBj)
T cuerpoBi = TBj =4+(n-i)(4+TcuerpoBj)
TcicloBi = Tcondi + TcuerpoBi + TincrementoBi + TsaltoCicloBj =2+[4+(n-i)(4+TcuerpoBj)]+2+1=
= 9 + (n-i)(4+TcuerpoBj)= 9+(n-i)(4+TcondSi+ TcuerpoSi) = 9+(n-i)(8+ TcuerpoSi)
TBi = TiniBi + TcondBi + TsaltoBi + (i=0;n-1) TcicloBi =
=1+2+1+(i=0;n-1) (9+(n-i)(8+ TcuerpoSi))=3+9n+ (i=0;n-1) (n-i)(8+ TcuerpoSi)
=3+9n + n*n(8+ TcuerpoSi )- (8+ TcuerpoSi)(i=0;n-1) i =
2
2
2
2
=3+9n+n (8+TcuerpoSi)- (8+TcuerpoSi)(n(n-1)/2)= 3+9n + 8n + n TcuerpoSi - 4n +4n- n(n-1)/2TcuerpoSi
2
2
2
= 4n +3n+3+(n -n(n-1)/2)TcuerpoSi= 4n +3n+3+ n(n+1)/2TcuerpoSi
2

TBurbuja (n)= 4n +3n+3+ n(n+1)/2TcuerpoSi


4.1.2.1. Caso mejor.
En el caso mejor para el algoritmo la condicin de la lnea (3) ser siempre falsa, y no se
ejecutarn nunca las lneas (4), (5) y (6).
TcuerpoSi=0

TBurbuja (n)= 4n2+3n+3+ n(n+1)/2TcuerpoSi = 4n2+3n+3

4/12

Prctica 1_Eficiencia de Algoritmos


FAA_1 Grado Ingeniera Informtica_Curso 2014-15
4.1.2.2. Caso peor
En el caso peor, la condicin de la lnea (3) ser siempre verdadera, y las lneas (4), (5) y (6) se
ejecutarn en todas las iteraciones.
TcuerpoSi=9

TBurbuja (n)= 4n2+3n+3+n(n+1)/2TcuerpoSi =4n2+3n+3+9n(n+1)/2= 13/2 n2+6n+3


4.1.2.3. Caso medio.
En el caso medio, la condicin de la lnea (3) ser verdadera con probabilidad 1/2. As, las lneas (4),
(5) y (6) se ejecutarn en la mitad de las iteraciones del bucle ms interno, y por tanto realiza un total
de OE:
TcuerpoSi=9(1/2)

TBurbuja (n)= 4n2+3n+3+n(n+1)/2TcuerpoSi =4n2+3n+3+(9/2)n(n+1)/2 = (13/4) n2+3n+3


4.1.2.4. Conclusin:
Sus casos mejor, peor y medio se producen respectivamente cuando el vector est inicialmente
ordenado de forma creciente, decreciente y aleatoria pero como los tiempos de ejecucin en los tres
2
casos son polinomios de grado 2, la complejidad del algoritmo es cuadrtica O(n ), independientemente
de qu caso se trate.

5/12

Prctica 1_Eficiencia de Algoritmos


FAA_1 Grado Ingeniera Informtica_Curso 2014-15

4.2. Clculo del Tiempo de la Eficiencia Emprica


Se trata de llevar a cabo un estudio puramente emprico, es decir, estudiar experimentalmente el
comportamiento del algoritmo. Para ello mediremos los recursos empleados (tiempo) para cada tamao
dado de las entradas.
En el caso de los algoritmos de bsqueda y ordenacin el tamao viene dado por el nmero de
componentes del vector a ordenar (n).
4.2.1.

Clculo del tiempo.

Para obtener el tiempo emprico de una ejecucin de un algoritmo lo que vamos a hacer es
calcular el tiempo de CPU. El tiempo que toma una funcin es muy simple:
1. tomamos el valor del reloj antes de realizar la llamada (t_ini),
2. llamamos a la rutina en cuestin, y
3. tomamos nuevamente el valor del reloj (t_fin).

La diferencia entre t_fin - t_ini nos da el total de tiempo que tom:


1. hacer la llamada a la rutina,
2. que esta haga su trabajo,
3. que devuelva el resultado.

Ahora hay algunos pequeos detalles de implementacin. Por ejemplo, qu funcin usar para tomar el
tiempo del reloj? Y ms importante, qu precisin obtenemos con dicha funcin?.
Para tomar el tiempo podemos usar la rutina clock(), que devuelve el tiempo aproximado de CPU que
transcurri desde que nuestro programa fue iniciado, dicho tiempo representado en un valor de tipo
clock_t: un valor entero que indica una cantidad de "tics" de reloj.
La precisin que tenemos con dicha rutina es de CLOCKS_PER_SEC (tics de reloj por segundo), lo que
significa que por cada segundo que pasa, la funcin clock() nos devolver CLOCKS_PER_SEC
unidades ms que el valor anterior. Segn la plataforma utilizada dicho valor CLOCKS_PER_SEC vara
entre 1000 a 1000000.
Una vez dicho esto, el cdigo de arriba en la mayora de los casos no funciona. As que tenemos que
buscar una funcin con mayor precisin, y adems, promediar varias muestras.
Esta alternativa en Windows no sirve y la razn es sencilla, en la misma MSDN explican que el
temporizador del sistema corre aproximadamente a unos 10 milisegundos, por lo tanto, cualquier
funcin que lo utilice nos estar dando la misma poca precisin (incluso al utilizar
GetSystemTimeAsFileTime y FILETIME). Por lo tanto la solucin es utilizar lo que se conoce en el
mundo de Windows como el "contador de rendimiento de alta resolucin" (high-resolution
performance counter: que tendremos que utilizar as:

6/12

Prctica 1_Eficiencia de Algoritmos


FAA_1 Grado Ingeniera Informtica_Curso 2014-15

#ifndef _LIB_MTIME
#define _LIB_MTIME
#include <stdio.h>
#include <windows.h>
/* retorna "a - b" en segundos */
double performancecounter_diff(LARGE_INTEGER *a, LARGE_INTEGER *b)
{
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
return (double)(a->QuadPart - b->QuadPart) / (double)freq.QuadPart;
}
#endif
/* Uso
int main(int argc, char *argv[])
{
LARGE_INTEGER t_ini, t_fin;
double secs;
QueryPerformanceCounter(&t_ini);
/* ...hacer algo... */
/*
QueryPerformanceCounter(&t_fin);
secs = performancecounter_diff(&t_fin, &t_ini);
printf("%.16g milliseconds\n", secs * 1000.0);
return 0;
}
*/

En este caso, QueryPerformanceCounter es como clock() y QueryPerformanceFrequency es como


CLOCKS_PER_SEC. Es decir, la primera funcin nos da el valor del contador, y la segunda su
frecuencia (en ciclos por segundo, hertz). Cabe aclarar que un LARGE_INTEGER es una forma de
representar un entero de 64 bits por medio de una unin (union).
Para obtener la eficiencia emprica deberemos ejecutar el mismo algoritmo para diferentes ejemplos.
As para un algoritmo cmo el de bsqueda y el de ordenacin lo ejecutaremos para diferentes tamaos
del vector y obtendremos los tiempos. Estos tiempos los almacenaremos en un fichero.

7/12

Prctica 1_Eficiencia de Algoritmos


FAA_1 Grado Ingeniera Informtica_Curso 2014-15

4.2.2. Cmo Mostrar los Datos


Para mostrar la eficiencia emprica haremos uso de los ficheros (tablas) que recojan el tiempo invertido
para cada caso y para cada algoritmo.

100
200
300
400
500
600
700
800
900

Tiempos empricos Algoritmo Bsqueda Lineal


Caso mejor
Caso peor
Caso medio
15
110
51
31
422
199
47
922
457
62
1625
844
94
2547
1379
110
3672
1847
140
4968
2477
140
6484
3211
172
8203
4273

8/12

Prctica 1_Eficiencia de Algoritmos


FAA_1 Grado Ingeniera Informtica_Curso 2014-15

4.3. Definicin de la Clase base ConjuntoInt.


Definicin de la clase ConjuntoInt para que se pueda especificar (y pueda variar) el tamao
mximo del vector.
La declaracin de dicha clase es la siguiente:
class ConjuntoInt {
private:
int tamano; //Tamao mximo variable.
int *datos; // VARIABLE DINMICA PARA CREAR EL TAMAO VARIABLE
public:
ConjuntoInt (int max= 0); //Constructor, por defecto tamao 0;
~ConjuntoInt (); //Destructor, liberar memoria;
void vaciar ();
void generaVector (int tam);
int generaKey();
int* getDatos();
void escribe ();
};

La implementacin de las funciones es la siguiente:


#include <iostream>
using namespace std;
#include <ctime> //para time
#include <cstdlib> // para srand, rand
#include "ConjuntoInt.h"
ConjuntoInt::ConjuntoInt (int max)
{
tamano= max;
datos= new int[max];
}
ConjuntoInt::~ConjuntoInt ()
{
delete[] datos;
}
void ConjuntoInt::vaciar ()
{
tamano= 0;
}
int* ConjuntoInt::getDatos()
{
int* v=datos;
for (int i= 0; i <tamano;i++){
v[i]=datos[i];}
return v;
}
void ConjuntoInt::generaVector (int tam)
{
tamano=tam;
srand( (unsigned)time( NULL ) ); //srand(time(0));
for (int i= 0; i<tamano; i++){
datos[i] = rand()%1000; //genera un nmero aleatorio entre 1 y 999
}
}
int ConjuntoInt::generaKey()

9/12

Prctica 1_Eficiencia de Algoritmos


FAA_1 Grado Ingeniera Informtica_Curso 2014-15
{
srand( (unsigned)time( NULL ) ); //srand(time(0));
return rand()%1000; //genera un nmero aleatorio entre 1 y 999
}
void ConjuntoInt::escribe()
{
for (int i= 0; i<tamano; i++)
cout << datos[i] << (i<tamano-1? ", ": "\n");
}

4.3.1. Programa Principal


El programa principal est compuesto por un men cuya estructura y descripcin es la siguiente:

El Men consta de 3 opciones incluida la opcin de salir. El programa no finalizar hasta que la opcin
salir sea seleccionada.
Opcin 1: Esta opcin abrir un submen que efectuar el clculo de los tiempos para el algoritmo
Bsqueda secuencial.
Opcin 2: Esta opcin abrir un submen efectuar el clculo de los tiempos para el algoritmo
Burbuja.
Opcin 3: Esta opcin hace que el programa termine.
Los submens correspondientes son los siguientes:

Como resultado de las opciones de clculo dar:

10/12

Prctica 1_Eficiencia de Algoritmos


FAA_1 Grado Ingeniera Informtica_Curso 2014-15

4.4. Conclusiones.
Para cada algoritmo habr que realizar una grfica para cada una de las tres curvas obtenidas y del
orden de complejidad y comentarlas tal y como se mostr anteriormente. Son coherentes con el
resultado terico obtenido? Justificar la respuesta.
Para mostrar los datos en grfica pondremos en el eje X (abscisa) el tamao de los casos y en el eje Y
(ordenada) el tiempo, medido en milisegundos(o microsegundos), requerido por la implementacin del
algoritmo.
Esto formar parte de la memoria de la prctica.

5.

Entrega de la prctica

La fecha de entrega es el domingo 29 de marzo.


La entrega de la prctica se realizar por Moodle en la tarea puesta al efecto y tendr el siguiente
formato:
Crear y subir la carpeta Apellido1Apellido2.rar la cual debe contener:

Una subcarpeta con los fuentes del programa (.cpp y .h)

Una subcarpeta con el ejecutable y los datos.

La memoria en formato pdf. con el esquema especificado a continuacin.

Esquema para la memoria.


ndice
1. Algoritmo Bsqueda secuencial.
1.1. Introduccin
1.2. Pseudcdigo y anlisis de coste
1.3. Grficas de coste
1.4. Conclusiones
2. Algoritmo Burbuja.
2.1. Introduccin
2.2. Pseudcdigo y anlisis de coste
2.3. Grficas de coste
2.4. Conclusiones
3. Diseo de la aplicacin.
(Mostrar un esquema grfico global de la estructura de tipos de datos existentes. Detallar la
descomposicin modular del programa, qu mdulos existen, cul es la responsabilidad de cada
uno y la relacin de uso. Documentar cualquier otra decisin de diseo que pueda resultar de
inters. Funcionamiento y explicacin de los mtodos implementados en la prctica.)

4. Conclusiones y valoraciones personales de la prctica.

11/12

Prctica 1_Eficiencia de Algoritmos


FAA_1 Grado Ingeniera Informtica_Curso 2014-15

6.

Consideraciones para la implementacin:

La clase ConjuntoInt permite crear vectores de tamao variable, para cada uno es tamao fijo pues no
hacemos inserciones ya que generamos el vector de forma aleatoria para ese tamao.
Para generar los vectores con los diferentes tamaos podis utilizar el siguiente esquema:
for (int i= 100; i<1000; i+=100) // para vectores de 100 a 900 elementos
{
ConjuntoInt *c= new ConjuntoInt(i); /* crea un nuevo objeto usando el constructor
por defecto. i= numero de elementos del vector, Tamao.*/

...
...
};

delete c; //Borra el objeto dinmico, usando el destructor.

Para la invocacin de un mtodo sobre el objeto dinmico se utiliza el operador flecha '->':
a->b equivale a (*a).b
Ejemplo:

c-> generaVector (100);


c->escribe();
cout << c->miembro(88);

12/12

Vous aimerez peut-être aussi