Unidad 3 diseño de algoritmos

Page 1

Universidad Da Vinci Dr. Vicente Cubells (vcubells@udavinci.edu.mx)


Temario   Técnicas de diseño de algoritmos   Divide y Vencerás   Programación dinámica


Introducción   Al desarrollar un algoritmo computacional que nos

permita resolver un problema, podemos tomar ventaja de diferentes técnicas   Estas técnicas nos dan una guía para poder desarrollar de manera más rápida, una buena solución


Divide y Vencerás…   Divide and Conquer   Es una técnica para el diseño de algoritmos.   El principio en el que se basa es el siguiente:   Es más fácil resolver varios casos pequeños de un problema que un

solo caso grande.

  El enfoque de divide y vencerás está formado por etapas:   Dividir el problema en ejemplares más pequeños.   Resolver los problemas pequeños.   Combinar las soluciones parciales para obtener la solución al

problema original.

  Se resuelve directamente para un caso simple o se divide el problema en 2 o más subproblemas.


Divide y Vencerás…   Ejemplo de diseño de algoritmo del problema I:

resolver(I) { n = tamaño(I); if( n <= pequeño ) solucion = resolverDirecto(I); else { dividir I en I1, I2, ...Im. Para toda i: si = resolver(Ii); solucion = combinar(s1, s2,..., sm); } return solucion; }


Divide y Vencerás…   Ejemplo donde se quieren dibujar las divisiones de

una regla de la siguiente manera:

  Se comienza por ejemplo con una regla que va de 0 a

30 cms, que se divide a la mitad y se hace una marca de altura h.


Divide y Vencerás…   Luego cada mitad, es decir de 0 a 15cms. y de 15 a 30

cms, se vuelve a dividir a la mitad y se hacen marcas con una altura h1.

  Otra vez cada sección se divide a la mitad y se marca.

  Se deja de marcar cuando la altura de la raya sea

menor o igual a cero.


Divide y Vencerás…   Algoritmo: pintarRegla( int inicio, int final, int altura ) { if( altura <= 0 ) return; else { posicion = (inicio + final)/2; marcar( posicion, altura ); h1 = altura / 2; pintarRegla( inicio, posicion, h1); pintarRegla( posicion, final, h1);

}

}


Divide y Vencerás…  Algoritmo recursivo de búsqueda

binaria

int buscar( int a[], int valor, int ini, int fin ) { int medio; if ( fin < ini ) return -­‐1; medio = ( ini + fin ) / 2; if ( a[medio] > valor ) return buscar( a, valor, ini, medio-­‐1); else if ( a[medio] < valor ) return buscar( a, valor, medio+1, fin ); else return medio; }


Divide y Vencerás  Algoritmo iterativo de búsqueda

binaria

int buscar( int a[], int valor, int ini, int fin ) { int medio; while ( ini <= fin ) { medio = ( ini + fin ) / 2; if ( a[medio] > valor ) fin = medio -­‐ 1; else if ( a[medio] < valor ) ini = medio + 1; else return medio; } return -­‐1; }


Programación dinámica…   El inconveniente se presenta cuando los

subproblemas obtenidos no son independientes sino que existe solapamiento entre ellos   es cuando una solución recursiva no resulta eficiente

por la repetición de cálculos que conlleva

  En estos casos es cuando la Programación Dinámica

nos puede ofrecer una solución aceptable.

  La eficiencia de esta técnica consiste en resolver los

subproblemas una sola vez, guardando sus soluciones en una tabla para su futura utilización.


Programación dinámica…   Donde tiene mayor aplicación la Programación Dinámica

es en la resolución de problemas de optimización

  En este tipo de problemas se pueden presentar distintas

soluciones, cada una con un valor, y lo que se desea es encontrar la solución de valor óptimo (máximo o mínimo)

  Se basa en el llamado principio de óptimo enunciado por

Bellman en 1957 y que dice:

“En una secuencia óptima de decisiones, toda subsecuencia ha de ser también óptima”


Programación dinámica…   El diseño de un algoritmo de Programación Dinámica

consta de los siguientes pasos:

  Planteamiento de la solución como una sucesión de

decisiones y verificación de que ésta cumple el principio de óptimo   Definición recursiva de la solución   Cálculo del valor de la solución óptima mediante una tabla en donde se almacenan soluciones a problemas parciales para reutilizar los cálculos   Construcción de la solución óptima haciendo uso de la información contenida en la tabla anterior


Programación dinámica…   Serie de Fibonacci:

  Ver algoritmo recursivo…   Analizar utilización de una tabla

Fib(0)

Fib(1)

Fib(2)

Fib(n)


Programación dinámica… int FibonacciIterativo(int n) { int tabla[n]; if (n <= 1) return 1; else { T[0] = 1; T[1] = 1; for (int i=2 ; i < n ; i++) { T[i] = T[i-1] + T[i-2]; } return T[n]; } }


Programación dinámica… int FibonacciIterativo(int n) { int suma, x, y; if (n <= 1) return 1; else { x = 1; y = 1; for (int i=2 ; i < n ; i++) { suma = x + y; y = x; x = suma; } return suma; } }


Programación dinámica…   Cálculo de coeficientes binomiales


Programación dinámica…   Cálculo de coeficientes binomiales


Programación dinámica… int CoefIter(int n, int k) { int i,j; int C[n][k]; for (i=0 ; i < n ; i++) { C[i,0] = 1; } for (i=1 ; i < n ; i++) { C[i,1] = i; } for (i=2 ; i < k ; i++) { C[i,i] = 1; } for (i=3 ; i < n ; i++) { for (j=2 ; j < i-1 ; j++) if (j<=k) { C[i,j] = C[i-1,j-1]+C[i-1,j]; } } }

return C[n,k]; }


Programación dinámica…   Función de Ackerman

En cada paso m del algoritmo hay que actualizar los Ack[i] (1 ≤ i ≤ n)

Ack[] suficientemente grande pues m crece muy rápido


Resumiendo   La técnica Divide y Vencerás puede aplicarse para

resolver problemas descomponiendo en subproblemas más pequeños   Funciona cuando existe un independencia total entre

las subsoluciones

  Si no existe independencia entre las subsoluciones,

lo mejor es utilizar Programación Dinámica, siempre y cuando se cumpla el principio del óptimo


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.