EliminacionRecursividadRedundante
-
Upload
alex-espinoza -
Category
Documents
-
view
69 -
download
1
description
Transcript of EliminacionRecursividadRedundante
Eliminación de la recursividad redundante
Algoritmos recursivos
• Ventajas:– Sencillez
• Desventajas:– Ineficiencia:
• Muy grave su hay redundancia• Factores constantes si no hay redundancia
• Técnicas de eliminación de la recursividad:– Recursividad general– Recursividad lineal– Recursividad redundante (múltiple)
Ejemplo de eliminación de recursividad lineal
Intercambiar 2 secciones de un vector :• Dado un vector v, intercambiar las l primeras celdas con
las n-l restantes• El intercambio debe realizarse sobre el mismo vector,
sin un vector auxiliar
Ejemplo de eliminación de recursividad lineal
public static void intercambiarSecciones (int l, int[ ] v) { interAux (l, v.length-l, l, v);}
donde:• interAux(i,j,k,v) intercambia dos secciones consecutivas
de v, de longitudes i y j, de forma que la segunda comienza en la posición k
Ejemplo de eliminación de recursividad lineal
Ejemplo de eliminación de recursividad lineal
• interAux(i,j,k,v) intercambia dos secciones consecutivas de v, de longitudes i y j, de forma que la segunda comienza en la posición k
• intercambiar(i,j,m,v) intercambia dos secciones consecutivas de v de longitud m y que comienzan en las posiciones i y j
private static void interAux (int i, int j, int k, int[ ] v) { if (i==j) intercambiar (k-i, k, i, v); else if (i<j) { intercambiar (k-i, k+j-i, i, v); interAux (i, j-i, k, v); } else { intercambiar (k-i, k, j, v); interAux (i-j, j, k, v); } }
Ejemplo de eliminación de recursividad lineal
• intercambiar intercambia dos secciones consecutivas de v de longitud m y que comienzan en las posiciones i y j:
public static void intercambiar (int i, int j, int m, int[ ] v) { for (int k=0; k<m; k++) { int temp = v[i+k]; v[i+k] = v[j+k]; v[j+k] = temp; } }
Ejemplo de eliminación de recursividad lineal
• Usando un esquema de eliminación de la recursividad final:
public static void intercambiarSecciones (int l, int[ ] v) { int i = l; int j = v.length-l; int k = l; while (i!=j) if (i<j) { j = j-i; intercambiar (k-i, k+j-i, i, v); } else { intercambiar (k-i, k, j, v); i = i-j; } intercambiar (k-i, k, i, v); }
Puede expandirse la definición de intercambiar, resultando un algoritmo con dos bucles anidados:
Algoritmo iterativo difícil de diseñar sin la versión recursiva inicial
Eliminación de la recursividad redundante
• Pasos:1. Análisis de la redundancia:
a. Árbol de recursión
b. Grafo de dependencia
2. Técnicas de eliminación de la redundancia:• Memorización• Tabulación
3. Optimización de memoria
Análisis de redundancia
• Algoritmo recursivo (múltiple) con redundancias:
public static int fib (int n) {
if ((n==0) || (n==1))
return 1;
else
return fib(n-1) + fib(n-2);
}
Análisis de redundancia
• Árbol de recursión de fib(5):– Usando SRec
Análisis de redundancia
• Árbol de recursión de fib(5):
• Grafo de dependencia de fib(5):
Análisis de redundancia
• Definición: • Árbol de recursión de C5,2:
Análisis de redundancia
• Árbol de recursión de C5,2:
• Grafo de dependencia de C5,2:
n+1
m-n+1
public static int fibRabbit (int n) { return bebes(n) + adultos(n); } private static int bebes (int n) { if (n==0) return 1; else return adultos(n-1); } private static int adultos (int n) { if (n==0) return 0; else return adultos(n-1) + bebes(n-1); }
• Dificultad:– Recursividad mutua
Análisis de redundancia
• Dificultad: Métodos anidados
public static int ack (int m, int n) { if (m==0) return n+1; else if (n==0) return ack(m-1,1); else return ack(m-1,ack(m,n-1));}
¿Árbol de recursión de ack(2,2)?
Análisis de redundancia
Análisis de redundancia
• No todos los algoritmos recursivos múltiples son redundantes:– Algoritmos de divide y vencerás:
• P.ej. ordenación por mezcla (árbol de recursión con índices del subvector a ordenar)
Memorizaciónpublic static T’ f (T x) {
if (P<x>)
return B<x>;
else
return
C(E<x>, f(D1<x>),f(D2<x>));
}
public static T’ F (T x) { T’[ ] t = new T’[x]; for (i=0; i<=n; i++) t[i] = v; M (x,t); return (t[x]);}private static void M (T x, T’[ ] t) { if (t[x] == v) if (P<x>) t[x] = B<x>; else { M(D1<x>,t); M(D2<x>,t); t[x] = C(E<x>, t[D1<x>], t[D2<x>]); }}
Memorizaciónpublic static int fib (int n) { if (n==0 || n==1) return 1; else return fib(n-1) + fib(n-2); }
public static int fib (int n) { int[ ] fibs = new int[n+1]; for (int i=0; i<=n; i++) fibs[i] = -1; fibMem (n, fibs); return fibs[n];}private static void fibMem (int n, int[ ] fibs){ if (fibs[n] == -1) if (n==0||n==1) fibs[n] = 1; else { fibMem (n-1, fibs); fibMem (n-2, fibs); fibs[n] = fibs[n-1]+fibs[n-2]; }}
public static int comb (int m, int n) { if (n==0||m==n) return 1; else return comb(m-1,n) +
comb(m-1,n-1);}
public static int comb (int m, int n) { int[ ][ ] combs = new int[m-n+1][n+1]; for (int i=0; i<=m-n; i++) for (int j=0; j<=n; j++) combs[i][j] = 0; combMem (m, n, combs); return combs[m-n][n]; } private static void combMem (int m, int n, int[ ][ ] combs) { if (combs[m-n][n] == 0) if (n==0||m==n) combs[m-n][n] = 1; else { combMem (m-1, n, combs); combMem (m-1, n-1, combs); combs[m-n][n] = combs[m-n-1][n] + combs[m-n][n-1]; } }
Memorización
Memorización
Tabulación
• Algoritmo con un orden lineal de cómputo y una tabla auxiliar:
public static int fib (int n) { int[ ] fibs = new int[n+1]; fibs[0] = 1; fibs[1] = 1; for (int i=2; i<=n; i++) fibs[i] = fibs[i-1]+fibs[i-2]; return fibs[n]; }
Tabulación• Algoritmo con orden lineal de cómputo (columnas): public static int comb (int m, int n) { int[ ][ ] combs = new int[m-n+1][n+1]; for (int j=1; j<=n; j++) combs[0][j] = 1; for (int i=1; i<=m-n; i++) { combs[i][0] = 1; for (int j=1; j<=n; j++) combs[i][j] = combs[i-1][j] + combs[i][j-1]; } return combs[m-n][n]; }
Tabulación• Algoritmo con orden lineal de cómputo (filas): public static int comb (int m, int n) { int[ ][ ] combs = new int[m-n+1][n+1]; for (int i=1; i<=m-n; i++) combs[i][0] = 1; for (int j=1; j<=n; j++) { combs[0][j] = 1; for (int i=1; i<=m-n; i++) combs[i][j] = combs[i-1][j] + combs[i][j-1]; } return combs[m-n][n]; }
Minimización de memoria
• Con optimización de la memoria (f2 >= f1):
public static int fib (int n) { int f1 = 1; int f2 = 1; for (int i=1; i<=n/2; i++) { f1 = f1+f2; f2 = f2+f1; } return (n%2==0)?f1:f2; }
Minimización de memoria
• Con optimización de la memoria (f2 >= f1):
public static int fib (int n) { int f1 = 1; int f2 = 1; for (int i=2; i<=n; i++) { int temp = f2; f2 = f1+f2; f1 = temp; } return f2; }
Minimización de memoria• Con optimización de la memoria (columnas): public static int comb (int m, int n) { int[] combs = new int[n+1]; for (int j=0; j<=n; j++) combs[j] = 1; for (int i=1; i<=m-n; i++) for (int j=1; j<=n; j++) combs[j] = combs[j] + combs [j-1]; return combs[n]; }
Competición deportiva
• Algoritmo recursivo:
P(0,j+1) = 0
P(i+1,0) = 1
P(i+1,j+1) = ½ [P(i,j+1)+P(i+1,j)]• Análisis de redundancia:
Competición deportiva
• Tabulación (columnas):
public static float prob (int i, int j) { float[][] tabla = new float[i+1][j+1]; for (int h=1; h<=i; h++) tabla[h][0] = (float)1.0; for (int k=1; k<=j; k++) { tabla[0][k] = (float)0.0; for (int h=1; h<=i; h++) tabla[h][k] = (tabla[h][k-1]+tabla[h-1][k])/2; } return tabla[i][j]; }
Competición deportiva
• Tabulación (filas):
public static float prob (int i, int j) { float[][] tabla = new float[i+1][j+1]; for (int k=1; k<=j; k++) tabla[0][k] = (float)0.0; for (int h=1; h<=i; h++) { tabla[h][0] = (float)1.0; for (int k=1; k<=j; k++) tabla[h][k] = (tabla[h][k-1]+tabla[h-1][k])/2; } return tabla[i][j]; }
• Tabulación, con memoria optimizada (filas):
public static float prob (int i, int j) { float[] tabla = new float[j+1]; tabla[0] = (float)1.0; for (int k=1; k<=j; k++) tabla[k] = (float)0.0; for (int h=1; h<=i; h++) for (int k=1; k<=j; k++) tabla[k] = (tabla[k-1]+tabla[k])/2; return tabla[j]; }
Competición deportiva
Competición deportiva• Tabulación (en diagonal):
public static float prob (int i, int j) { float [ ][ ] tabla = new float[i+1][j+1]; for (int k=1; k<=i+j; k++) { if (k<=j) tabla[0][k] = (float)0.0; if (k<=i) tabla[k][0] = (float)1.0; for (int h=1; h<k; h++) if ((h<=i) && (k-h<=j)) tabla[h][k-h]=(tabla[h-1][k-h]+tabla[h][k-h-1])/2; } return tabla[i][j]; }
Mochila 0/1
ps=(3,6,9,5)bs=(7,2,8,4)c=15
cpniparappsibppimpim
ppsipimpim
cpparapnm
iii
i
0,1)),1(),,1(max(
),1(),(
00),1(
Mochila 0/1
ps=(3,6,9,5)bs=(7,2,8,4)c=15
cpniparappsibppimpim
ppsipimpim
cpparapnm
iii
i
0,1)),1(),,1(max(
),1(),(
00),1(
Mochila 0/1
ps=(3,6,9,5)bs=(7,2,8,4)c=15
cpniparappsibppimpim
ppsipimpim
cpparapnm
iii
i
0,1)),1(),,1(max(
),1(),(
00),1(
Mochila 0/1ps=(3,6,9,5)bs=(7,2,8,4)c=15
• Grafo variable:
• Subgrafo de:
cpniparappsibppimpim
ppsipimpim
cpparapnm
iii
i
0,1)),1(),,1(max(
),1(),(
00),1(
Tabla mínima
• Solución recursiva:
• um={200,100,50,20,10,5,2,1}• m(0,12):
Cambio de monedas
][/0,10])[·,1(min),(
0),(
iumxjniparaiumjximjxim
cxparaxxnm
• Solución recursiva:
• um={7,5,1}, m(0,10):
Cambio de monedas
][/0,10])[·,1(min),(
0),(
iumxjniparaiumjximjxim
cxparaxxnm
Cambio de monedas
• um={7,5,1}, c=10: