Unidad Análisis de algoritmos

12
Estructura de datos                                                             Instituto Tecnológico de Orizaba Unidad  I Análisis de algoritmos Uno de los problemas más grandes en la programación de computadoras, es diseñar algoritmos que permitan la ejecución eficiente de los programas. Todo algoritmo que se diseña se puede analizar para determinar el rendimiento que proporciona a la ejecución de un programa. Este rendimiento esta dado por los recursos que utiliza (memoria y tiempo) para su ejecución, en esta unidad se trataran los aspectos de cómo analizar algoritmos y que ayuden a determinar cual es el indicado para el problema que deseamos resolver. 1.1 Concepto de Complejidad de algoritmos. El espacio que un algoritmo utiliza esta relacionada con la información estructurada que se va a procesar y alguna otra información estructurada que dará soporte a la ejecución de los procesos computacionales que el algoritmo requiere. El tiempo que un algoritmo necesita para su ejecución depende de la estructura del algoritmo (operaciones).  Estas al ejecutarse podrán darnos como resultado un tiempo optimo, un tiempo promedio o un tiempo pésimo con respecto a otros algoritmos que resuelven el mismo problema. El tiempo de ejecución del algoritmo también depende de la cantidad y organización de los datos a ser procesados; de acuerdo a esto, de un mismo algoritmo se puede obtener su rendimiento en el mejor de los casos, en el peor de los casos y en casos promedios. Así pues la complejidad de un algoritmo se define como el tiempo que un algoritmo necesita para ejecutarse sobre un conjunto de datos. Al evaluar dos o mas algoritmos necesitamos saber cual de ellos tiene el mejor rendimiento sea cual fuera la forma en que los datos están organizados considerando el peor de los casos, como un parámetro esencial. Como se observa los algoritmos están relacionados con los datos que tienen que procesar o manipular. Las estructuras de datos desde el punto de vista de la programación orientada a objetos son tipos de datos abstractos (TDA’s). Lic. Rafael Herrera García                                                                                 Página No. 1

Transcript of Unidad Análisis de algoritmos

Estructura de datos                                                              Instituto Tecnológico de Orizaba

Unidad  I Análisis de algoritmos

Uno de los problemas más grandes en la programación de computadoras, esdiseñar   algoritmos   que   permitan   la   ejecución   eficiente   de   los   programas.   Todoalgoritmo   que   se   diseña   se   puede   analizar   para   determinar   el   rendimiento   queproporciona a la ejecución de un programa.

Este rendimiento esta dado por  los recursos que utiliza (memoria y  tiempo)para   su   ejecución,   en   esta   unidad   se   trataran   los   aspectos   de   cómo   analizaralgoritmos   y   que   ayuden   a   determinar   cual   es   el   indicado   para   el   problema  quedeseamos resolver.

1.1 Concepto de Complejidad de algoritmos. 

El  espacio  que  un  algoritmo  utiliza  esta   relacionada  con   la   informaciónestructurada que se va a procesar  y alguna otra  información estructurada quedará  soporte  a  la  ejecución de  los procesos computacionales que el  algoritmorequiere.

El   tiempo   que   un  algoritmo   necesita   para   su  ejecución   depende   de   laestructura del algoritmo (operaciones).   Estas al ejecutarse podrán darnos comoresultado un tiempo optimo, un tiempo promedio o un tiempo pésimo con respectoa otros algoritmos que resuelven el mismo problema. 

El   tiempo de ejecución del  algoritmo  también depende de  la cantidad yorganización de  los datos a ser procesados;  de acuerdo a esto,  de un mismoalgoritmo se puede obtener su rendimiento en el mejor de los casos, en el peor delos casos y en casos promedios.

Así pues la complejidad de un algoritmo se define como el tiempo que unalgoritmo necesita para ejecutarse sobre un conjunto de datos.

Al evaluar dos o mas algoritmos necesitamos saber cual de ellos tiene elmejor rendimiento sea cual fuera  la  forma en que los datos están organizadosconsiderando el peor de los casos, como un parámetro esencial.

Como  se  observa   los  algoritmos  están   relacionados   con   los  datos  quetienen que procesar o manipular. Las estructuras de datos desde el punto de vistade la programación orientada a objetos son tipos de datos abstractos (TDA’s).

Lic. Rafael Herrera García                                                                                  Página No. 1

Estructura de datos                                                              Instituto Tecnológico de Orizaba

Un tipo de dato abstracto es un tipo de dato definido por el programador, elcual define los datos y las operaciones que permitirán manipularlos.

En un lenguaje orientado a objetos se utiliza una clase para definir un tipode dato abstracto.

La   intención   es   construir   estructuras   de   datos   donde   las   operacionesimplementen algoritmos que sean los más óptimos.

Una  forma de  medir  el   rendimiento  de  un  algoritmo es   implementarlo  ytomar los tiempos que se lleva en ejecutarse con conjuntos de datos de distintostamaños, tomando en cuenta el mejor de los casos, el peor de los casos y el casopromedio.

Suponer que tenemos un algoritmo para recuperar la posición de la últimaocurrencia de un número en un arreglo.

int UltimaOcurrencia(int [ ]x ,int value){     int i, pos=­1;     for(i=0;i<x.length;i++)        if(x[i]==value)              pos=i;    return pos;}

En   Java   se   puede   medir   el   tiempo   de   ejecución   con   el   métodoSystem.currentTimeMillis(), con distintos tamaños de datos, este método retornael tiempo del sistema en milisegundos. Para calcular el tiempo de ejecución de unalgoritmo debemos obtener el tiempo del sistema antes y después de la ejecuciónde este, para obtener la diferencia.

int a[ ];int valor;:long t1= System.currentTimeMillis();int r=UltimaOcurrencia(a,valor);long t2=System.currentTimeMillis();int t= (int)(t2­t1);

Lic. Rafael Herrera García                                                                                  Página No. 2

Estructura de datos                                                              Instituto Tecnológico de Orizaba

EJERCICIO: Elaborar programa que determine los tiempos que el algoritmose lleva al ejecutarse con datos distribuidos aleatoriamente, hacer la prueba conarreglos de 1000000, 2000000,3000000,.., hasta10000000 de valores, los valorespermitidos en el  arreglo deberán ser entre  1 y 50000.  Analizar   los tiempos deejecución que cada caso nos proporciona y graficarlos.

CODIGO PARA GRAFICAR DATOS DESCRIPCIONimport java.awt.*;import javax.swing.*;public class Graficador {//=====================================  static int maximo(int x[ ]){      int max=x[0];      int i;      for(i=1;i<x.length;i++)        if(x[i]>max)          max=x[i];     return max;   }//======================================   static void dibuja(Graphics g,int [ ]r,int max){      g.setColor(Color.BLUE);      int limite=300;      int proporcion=limite/(max==0?1:max);      g.drawLine(10,limite,(r.length+10)*20,limite);      g.drawLine(10,limite,10,0);      int i,x=10,y;      for(i=0;i<r.length­1;i++){           g.setColor(Color.GREEN);           y=limite­r[i]*proporcion;           g.drawRect(x­1,y­1,3,2);           g.setColor(Color.RED);           g.drawLine(x,y,x+20,limite­r[i+1]*proporcion);           x=x+20;       }       g.setColor(Color.GREEN);       y=limite­r[i]*proporcion;       g.drawRect(x­1,y­1,3,2);   }//===========================================      static void Grafica(final int r[]){       final int max=maximo(r);      JPanel p= new JPanel(){                       public void paint(Graphics g){                   dibuja(g,r,max);              }      };     JFrame f=new JFrame("Grafica");     Container c= f.getContentPane();     c.add(new JLabel("Y pon etiqueta que desees"),BorderLayout.NORTH);     c.add(new JLabel("X pon etiqueta que desees"),BorderLayout.SOUTH);     c.add(p,BorderLayout.CENTER);     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     f.setSize(550,400);     f.show();  }//=================================================   public static void main(String[ ] args){       int a[]={4,60,80,100,78,34,34,23,12,0,23,43,89};       Grafica(a);   }}

Método para obtener el  valor  máximo deun arreglo.

Método   que   dibuja   en   un   componentegráfico   los   valores   de   un   arreglo   querepresentan el eje Y, cuyo valor mayor esmax.   Se   considera   al   eje   X   distribuidouniformemente.   El   Eje   Y   tiene   límite   de300 puntos.

Ciclo para dibujar  los puntos y  las  líneasque los unen.

Método   que   se   invoca   desde   unaaplicación   para   hacer   un   polígono   defrecuencias con valores uniformes en ejeX.

Esto funciona solo con versiones 1.4.2 deJRE o mayores.

Ejemplo   de   arreglo   que   se   utiliza   eninvocación.

Lic. Rafael Herrera García                                                                                  Página No. 3

Estructura de datos                                                              Instituto Tecnológico de Orizaba

Esta es la pantalla obtenida de la ejecución del programa.

El siguiente método realiza la búsqueda de la última ocurrencia de un valoren un arreglo de una forma distinta al anterior método.

int UltimaOcurrencia2(int [ ]x ,int value){        int i,p=­1;        for(i=x.length­1;i>=0;i­­)            if(x[i]==value){              p = i;              break;            }        return p;}

Lic. Rafael Herrera García                                                                                  Página No. 4

Estructura de datos                                                              Instituto Tecnológico de Orizaba

A simple vista pareciera que es un código más grande, lo interesante esevaluarlo   con   las   misma   condiciones   que   al   método   anterior   y   determinar   elcomportamiento que tiene con respecto al caso anterior. 

1.2 Aritmética de la notación O. 

El estudio experimental de los algoritmos tiene ciertas desventajas:

a) Los valores sobre los que se prueba el algoritmo, muchas de las vecesson ciertos casos que son escogidos aleatoriamente. Lo cual puede noincluir los casos reales con los cuales se utilizará el algoritmo.

b) Es difícil  comparar  la eficiencia de dos o más algoritmos sin que susejecuciones se lleven a cabo en los mismos ambientes de hardware osoftware.

c) Es necesario implementar y ejecutar el algoritmo, para estudiar de formaexperimental sus tiempos de respuesta.

Existen diversos tipos de complejidad:

  La  complejidad   temporal  es  el   tiempo  que  necesita  un  algoritmo  paraejecutarse.

La   complejidad   espacial   es   la   cantidad   de   memoria   que   un   algoritmoconsume o utiliza durante su ejecución.

La complejidad computacional de los algoritmos indica el esfuerzo que hayque realizar para aplicar un algoritmo y lo costoso que éste resulta.

La complejidad asintótica consiste en el cálculo de la complejidad temporala priori de un algoritmo en función del tamaño del problema (n), prescindiendo defactores constantes multiplicativos y suponiendo valores de n muy grandes.

Esta ultima no sirve para establecer el tiempo exacto de ejecución, sino quepermite   especificar   una   cota(inferior,   superior   o   ambas)   para   el   tiempo   deejecución de un algoritmo.

Lic. Rafael Herrera García                                                                                  Página No. 5

Estructura de datos                                                              Instituto Tecnológico de Orizaba

El enfoque teórico o a priori permite (complejidad asintótica):

a) Utilizar una descripción de alto nivel del algoritmo (v.g. en pseudocódigo)

b) Determinar,   matemáticamente,   la   cantidad  de   recursos   necesarios  paraejecutar el algoritmo

c) Obtener una función genérica f(n) que permita hacer predicciones sobre lautilización de recursos, siendo n el tamaño del problema

Dadas   las   funciones  f(n)   y  g(n),   se   dice   que  f(n)   es  O(g(n))   si   existenconstantes positivas c y n0 tales que

f(n) ≤ cg(n)  para n ≥ n0

Podemos decir que

f(n)  es la función que determina el tiempo de ejecución de un algoritmo enel peor de los casos.

g(n) es la función que determina el orden (O) “big­Oh” de la función f(n).

c es una constante entera >0.

n0 es una constante entera >= 1

Considerar que para una función de la forma:

f(n)= 5n­3 siempre será O(n), ya que es una función lineal.

f(n)= 4n2+2n­5 siempre sera O(n2), ya que es una función cuadrática

Lic. Rafael Herrera García                                                                                  Página No. 6

Estructura de datos                                                              Instituto Tecnológico de Orizaba

La siguiente tabla muestra las principales “big­Oh” que encontramos en losalgoritmos.

1.3 Complejidad. 

1.3.1 Tiempo de ejecución de un algoritmo.

Todo algoritmo se puede describir en termino de las operaciones que va aejecutar y cuantas veces se ejecutaran estas. Una operación computacional esaquella   que   describe   una   operación   simple   como   las   que   se   mencionan   acontinuación:

1.­ Asignación de un valor a una variable (no expresión)2.­ Invocación a un método (call)3.­ Ejecutar una operación aritmética, relacional o lógica.4.­ Resolver el índice de un arreglo (a[i])5.­Retornar un valor de un método.

Si tengo el método que localiza el mayor de los elementos de un arreglo deenteros:

Lic. Rafael Herrera García                                                                                  Página No. 7

PolinómicaO(nk) k>3

IntratableAlgunos algoritmos de grafos

ExponencialO(kn) k>1

Quick­sortCasi linealO(n•log n)

TratableAlgoritmo de la burbujaCuadráticaO(n2)

Producto de matricesCúbicaO(n3)

Búsqueda lineal

Búsqueda binaria

No depende del tamaño del problema

FactorialO(n!)

LinealO(n)

LogarítmicaO(log n)

EficienteConstanteO(1)

Estructura de datos                                                              Instituto Tecnológico de Orizaba

METODO DESCRIPCIONint mayor(int x[ ]){    int i;    int max= x[0];

    for(i=1;i<x.length;i++)

                  if(x[i]>max)                 max=x[i];    return max;}

2   Operaciones   (asignación   e   índice   que   seresuelve)i=1   ,   es   una   operación   ,   i<x.length     es   otraoperación y  i++ son 2 operaciones (incrementa yasigna)x[i]>max, son 2 operacionesTambién aquí existen 2 operacionesEs una sola operación.

EJERCICIO: De los métodos siguientes determina de cuantas operacionesestán compuestos.

int  PrimeraOcurrencia(int x[ ],int value){int i,pos=­1;

  for(i=0;i<x.length;i++)if(x[i]==value){   pos=i;   break;}

return pos;}

int VecesRepite(int x[ ], int value){int i,c=0;

  for(i=0;i<x.length;i++)if(x[i]==value)   c++;

return pos;}

Lic. Rafael Herrera García                                                                                  Página No. 8

Estructura de datos                                                              Instituto Tecnológico de Orizaba

int promedio (int x[ ]){int i,s=x[0];for(i=1;i<x.length;i++)

               s=s+x[i];return s/x.length;

}

Para   realizar   un   análisis   formal   de   un   algoritmo   necesitamos   unametodología  para   llevar  a  cabo dicho análisis,  esta  consiste  en   los  siguientespasos:

1.­   Elabore   el   algoritmo   en   pseudocodigo   (aproximación   a   laimplementación).

2.­ Determine para cada operación computacional el tiempo (ti) necesariopara ejecutarla.

3.­  Determine  para   cada  operación   el   número  de   veces   (ni)   que  dichaoperación será ejecutada cuando el algoritmo sea implementado.

4.­ Sume los productos (ni  ti) de todas las operaciones, el resultado será eltiempo que el algoritmo necesitara para ejecutarse.

5.­ Si es necesario considerar el número de veces (ni)  que dicha operaciónserá ejecutada en el mejor y peor de los casos.

Para probar este análisis vamos utilizar el método que localiza al elementomayor en un arreglo. Considerar que todas las operaciones se ejecutan en unaunidad de tiempo.

int mayor(int x[ ]){    int i;    int max= x[0];

    for(i=1;i<x.length;i++)         if(x[i]>max)                 max=x[i];    return max;}

Lic. Rafael Herrera García                                                                                  Página No. 9

Estructura de datos                                                              Instituto Tecnológico de Orizaba

Tomaremos  primero  el   peor   de   los  casos  y  que   todas   las  operacionesconsumen el mismo tiempo, considerando el siguiente arreglo:

 

Como se puede observar, en dicho arreglo, el mayor esta al final, así queanalizaremos el algoritmo de la siguiente forma:

OPERACIÓN VECES QUE SE REPITEx[0] 1max=x[0] 1i=1 1i<x.length ni++ n­1 (2 operaciones)x[i] n­1x[i]>max n­1x[i] n­1max=x[i] n­1return max 1

El resultado se puede representar mediante una función matemática, comola suma de las operaciones.

   1+1+1+n+6(n­1)+1=          3+n+6(n­1)+1 =             3+ n+6n­6+1 =                 3+7n­6+1 =                    7n+4­6 = 7n­2

Tomaremos ahora el mejor de los casos y será  considerado el siguientearreglo:

Como se puede observar, en dicho arreglo, el mayor esta al principio, asíque analizaremos el algoritmo de la siguiente forma:

Lic. Rafael Herrera García                                                                                  Página No. 10

12 342723 45 49

49 273445 13 11

Estructura de datos                                                              Instituto Tecnológico de Orizaba

OPERACIÓN VECES QUE SE REPITEx[0] 1max=x[0] 1i=1 1i<x.length ni++ n­1 (2 operaciones)x[i] n­1x[i]>max n­1x[i] 0max=x[i] 0return max 1

1+1+1+n+4(n­1)+1=       3+n+4(n­1)+1 =           3+n+4n­4+1=               3+5n­4+1=                   5n+4­4= 5n

Así  podemos decir  que  el  algoritmo  para  obtener  el   valor  mayor  de  unarreglo, para el peor de los casos tiene un tiempo de 7n­2 y para el mejor de loscasos su tiempo es de 5n.

Tomaremos a 7n­2 como una función (f(n)) que describe el tiempo que seejecuta este algoritmo en el peor de los casos.

Una vez obtenida la función f(n) es fácil determinar el orden del algoritmo,para el caso del algoritmo que obtiene el mayor de los elementos de un arreglodada la función:

7n­2     su orden es O(n)

EJERCICIOS: Diseña y determina el orden de un algortimo formalmente delos siguientes problemas.

a)   Diseñar   un   algoritmo   que   de   un   arreglo   obtenga   un   arreglo   sin   loselementos que se repiten en el, si tengo 3,4,5,6,4,3,6,7,6,5,9,1  el resultado será7,9,1

Lic. Rafael Herrera García                                                                                  Página No. 11

Estructura de datos                                                              Instituto Tecnológico de Orizaba

b) Diseñar un algoritmo que obtenga el número de veces que se repite unvalor en el arreglo.

c)   Diseñar   un   algoritmo   que   dado   un   arreglo   bidimensional,   retorne   elnumero de veces que un numero par se localiza en el arreglo.

d) Diseñar un algoritmo que dado un arreglo unidimensional , obtenga paracada valor del arreglo cuantos valores en el arreglo son multiplos de el. Sia= 4,8,5,3,6,7,9,10,5,2 el arreglo resultante será b= 1,0,2,2,0,0,0,2,3

1.3.2 Complejidad en espacio

Este tipo de complejidad a diferencia de la temporal, tiene que ver con losrecursos de memoria que se utilizan.  Podemos decir  que un algoritmo que noutiliza memoria adicional su complejidad espacial es n.

Cuando un algoritmo utiliza el doble de su memoria su complejidad espaciales 2n y así sucesivamente. 

Analizar   los  algoritmos  vistos  anteriormente   (complejidad   temporal)  paradeterminar el espacio que utilizan.

1.4 Selección de un algoritmo. 

La   elección   del   algortimo   nunca   debería   afectar   a   la   corrección   de   lasolución ni a la claridad (evitar algoritmos imcomprensibles).

A veces se eligen algoritmos aproximados o heurísticos porque la solucióncorrecta   resulta   inmanejable.   No   alcanzan   la   solución   óptima   pero   sí   a   unasolución aceptable.

Ejemplo:

a) El problema de la raiz cuadrada.b) El problema del agente viajero

Un algortimo es más eficiente cuanto menos complejo sea. La eficiencia semide como ya se menciono anteriormente en términos de consumo de recursos(temporales y espaciales).

Lic. Rafael Herrera García                                                                                  Página No. 12