Estrategias de Optimización
Optimización de Algoritmos Recursivos
Optimizar algoritmos recursivos es crucial para mejorar el rendimiento y la eficiencia de la memoria. Esta sección explora técnicas avanzadas para mejorar el código recursivo.
Técnicas de Optimización
graph TD
A[Estrategias de Optimización] --> B[Recursión de Cola]
A --> C[Memorización]
A --> D[Programación Dinámica]
A --> E[Conversión Iterativa]
1. Optimización de Recursión de Cola
// Función recursiva no optimizada
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n-1) + fibonacci(n-2);
}
// Optimización recursiva de cola
int fibonacci_optimized(int n, int a, int b) {
if (n == 0) return a;
if (n == 1) return b;
return fibonacci_optimized(n-1, b, a+b);
}
2. Técnica de Memorización
#define MAX_N 1000
int memo[MAX_N];
int fibonacci_memoized(int n) {
// Comprobar el resultado memorizado
if (memo[n] != -1) {
return memo[n];
}
// Calcular y almacenar el resultado
if (n <= 1) {
memo[n] = n;
} else {
memo[n] = fibonacci_memoized(n-1) + fibonacci_memoized(n-2);
}
return memo[n];
}
Comparación de Rendimiento
| Técnica |
Complejidad Temporal |
Complejidad Espacial |
Pros |
Contras |
| Recursión Básica |
O(2^n) |
O(n) |
Simple |
Ineficiente |
| Memorización |
O(n) |
O(n) |
Eficiente |
Memoria adicional |
| Recursión de Cola |
O(n) |
O(1) |
Eficiente en memoria |
Necesita soporte del compilador |
3. Enfoque de Programación Dinámica
int fibonacci_dp(int n) {
if (n <= 1) return n;
int dp[n+1];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
Flags de Optimización del Compilador
graph LR
A[Flags de Optimización GCC] --> B[-O0: Sin optimización]
A --> C[-O1: Optimización básica]
A --> D[-O2: Nivel recomendado]
A --> E[-O3: Optimización agresiva]
Estrategias de Optimización Avanzadas
- Incorporación de Funciones
- Sugerencias del Compilador
- Conversión de Recursivo a Iterativo
Ejemplo de Sugerencia del Compilador
// Sugerencia de función inline
__attribute__((always_inline))
int recursive_helper(int n) {
if (n <= 1) return n;
return n * recursive_helper(n-1);
}
Buenas Prácticas
- Preferir soluciones iterativas cuando sea posible
- Usar memorización para cálculos repetidos
- Aprovechar las flags de optimización del compilador
- Probar y medir el rendimiento de tu código
- Considerar las compensaciones espacio-tiempo
En LabEx, recomendamos un enfoque sistemático para la optimización de algoritmos recursivos, equilibrando la legibilidad y el rendimiento.