Documentos de Académico
Documentos de Profesional
Documentos de Cultura
DIVIDE Y CONQUISTA
Divide y Conquista
Divide y Conquista: Esquema algorítmico
else { // P es grande
Divide y Conquista
Divide y Conquista: Análisis de Eficiencia
DyC (P) {
if ( SIMPLE (P) )
return Solucion_Directa (P);
else {
DIVIDE P en k Subproblemas P1, P2,... Pk;
return ( COMBINA ( DyC(P1) , DyC(P2), ..., DyC(Pk) );
}
}
Si el tamaño de P es n y el tamaño de los k subproblemas es n1, n2, ..., nk :
g(n) n pequeño
T(n) =
T(n1) + T(n2) + ... + T(nk) + f(n) n suficientemente grande
Divide y Conquista
MERGE-SORT
Divide y Conquista
MERGE-SORT
Merge-Sort es un método que aplica la técnica divide y conquista para
ordenar los elementos almacenados en un arreglo:
Divide y Conquista
MERGE-SORT
MERGE-SORT (A, i, d) {
// ordena los elementos del arreglo A[i...d]
if ( i < d )
// Si hay más de un elemento divide el problema de ordenar A
// en dos subproblemas
{ m ← ⌊(i + d)/2⌋
MERGE-SORT (A, i, m)
// llama recursivamente para ordenar A[i...m] ( ⌈n/2⌉ elementos)
MERGE-SORT (A, m + 1, d)
// llama recursivamente para ordenar A[m+1...d] ( ⌊n/2⌋ elementos)
MERGE (A, i, m, d) // combina los subarreglos para
// formar un único subarreglo ordenado A[i..d]
}
}
Divide y Conquista
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d) i m d
MERGE (A, i, m, d)
}
}
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
i m d
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
1 2 3
A: 70 65 50
i m d
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
1 2 3
A: 70 65 50
1 2
A: 70 65
i,m d
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
1 2 3
A: 70 65 50
1 2
A: 70 65
i,m d
1
A: 70
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
1 2 3
A: 70 65 50
1 2
A: 70 65
i,m d
1 2
A: 70 A: 65
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
1 2 3
A: 70 65 50
1 2
MERGE asume que los subarreglos A[i..m] y A[m+1..d]
A: 70 65
están ordenados.
i,m d Luego, mezcla los elementos de los dos subarreglos para
1 2
MERGE formar un único subarreglo ordenado que reemplazará al
A: 70 A: 65 actual subarreglo A[i..d]
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
1 2 3
A: 70 65 50
i m d
1 2 3
A: 65 70 A: 50
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
1 2 3
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
1 2 3
A: 50 65 70
i m d
1 2 MERGE 3
A: 65 70 A: 50
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
i m d
1 2 3
A: 50 65 70
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
i m d
1 2 3 4 5
A: 50 65 70 A: 80 85
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
i m d
1 2 3 4 5
A: 50 65 70 A: 80 85
80
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
i m d
1 2 3 4 5
A: 50 65 70 A: 80 85
4 5
80 85
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
i m d
1 2 3 4 5
A: 50 65 70 A: 80 85
MERGE
4 5
80 85
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
i m d
1 2 3 4 5
A: 50 65 70 A: 80 85
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 70 65 50 80 85
} A:
i m d
1 2 3 MERGE 4 5
A: 50 65 70 A: 80 85
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d) 1 2 3 4 5
} 50 65 70 80 85
} A:
i m d
1 2 3 MERGE 4 5
A: 50 65 70 A: 80 85
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d) i m d
MERGE (A, i, m, d) 1 2 3 4 5
} 50 65 70 80 85
} A:
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
6 7 8 9
MERGE (A, i, m, d) 1 2 3 4 5
} 50 65 70 80 85 60 55 75 45
} A: A:
i m d
… ...
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
6 7 8 9
MERGE (A, i, m, d) 1 2 3 4 5
} 50 65 70 80 85 45 55 60 75
} A: A:
i m d
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 70 65 50 80 85 60 55 75 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d) i m d
6 7 8 9
MERGE (A, i, m, d) 1 2 3 4 5 MERGE
} 50 65 70 80 85 45 55 60 75
} A: A:
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 45
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d) i m d
6 7 8 9
MERGE (A, i, m, d) 1 2 3 4 5 MERGE
} 50 65 70 80 85 45 55 60 75
} A: A:
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 45 50
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d) i m d
6 7 8 9
MERGE (A, i, m, d) 1 2 3 4 5 MERGE
} 50 65 70 80 85 45 55 60 75
} A: A:
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 45 50 55
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d) i m d
6 7 8 9
MERGE (A, i, m, d) 1 2 3 4 5 MERGE
} 50 65 70 80 85 45 55 60 75
} A: A:
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 45 50 55 60
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d) i m d
6 7 8 9
MERGE (A, i, m, d) 1 2 3 4 5 MERGE
} 50 65 70 80 85 45 55 60 75
} A: A:
MERGE-SORT: ejemplo
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 45 50 55 60 65 70 75 80 85
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d) i m d
6 7 8 9
MERGE (A, i, m, d) 1 2 3 4 5 MERGE
} 50 65 70 80 85 45 55 60 75
} A: A:
MERGE-SORT (A, i, d) { 1 2 3 4 5 6 7 8 9
if ( i < d )
{ m ← ⌊(i + d)/2⌋ A: 45 50 55 60 65 70 75 80 85
MERGE-SORT (A, i, m)
MERGE-SORT (A, m + 1, d)
MERGE (A, i, m, d)
}
}
c0 n pequeño
T(n) =
2 T(n/2) + cn + c n suficientemente grande
Divide y Conquista
MERGE-SORT
Divide y Conquista
QUICKSORT
Divide y Conquista
QUICKSORT
Quicksort es un método que aplica la técnica divide y conquista para ordenar
los elementos almacenados en un arreglo:
Divide y Conquista
QUICKSORT
void QUICKSORT (Type A[], int i, int j) {
Divide y Conquista
QUICKSORT : Partición
Primer paso: selecciona un pivote (por ejemplo, a[1])
1 2 3 4 5 6 7 8 9
a: 65 70 50 80 85 60 55 75 45
Pivote
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 70 50 80 85 60 55 75 45
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 70 50 80 85 60 55 75 45
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 80 85 60 55 75 70
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 80 85 60 55 75 70
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 80 85 60 55 75 70
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 80 85 60 55 75 70
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 80 85 60 55 75 70
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 80 85 60 55 75 70
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 55 85 60 80 75 70
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 55 85 60 80 75 70
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 55 85 60 80 75 70
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 55 85 60 80 75 70
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 55 60 85 80 75 70
i j
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 55 60 85 80 75 70
j i
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 55 60 85 80 75 70
j i
Pivote
Mientras i < j
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
65 45 50 55 60 85 80 75 70
j i
Pivote
i > j =>
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
60 45 50 55 65 85 80 75 70
Pivote
i > j =>
Divide y Conquista
QUICKSORT : Partición
1 2 3 4 5 6 7 8 9
60 45 50 55 65 85 80 75 70
Pivote
elementos elementos
menores al pivote mayores al pivote
Divide y Conquista
QUICKSORT
1 2 3 4 5 6 7 8 9
60 45 50 55 65 85 80 75 70
Pivote
elementos elementos
menores al pivote mayores al pivote
Una vez realizada la partición, cada subarreglo es ordenado llamando recursivamente a quicksort
Divide y Conquista
QUICKSORT
1 2 3 4 5 6 7 8 9
45 50 55 60 65 70 75 80 85
Pivote
elementos elementos
menores al pivote mayores al pivote
Divide y Conquista
QUICKSORT
void QUICKSORT (Type A[], int i, int j) {
Divide y Conquista
QUICKSORT: Complejidad temporal
Divide y Conquista
QUICKSORT: Complejidad temporal
p a [ i+1 … j ] > p
i j
a [ i … j-1] ≤ p p
i j
Divide y Conquista
QUICKSORT: Complejidad temporal
Divide y Conquista
QUICKSORT: Complejidad temporal
T(n) O ( n2)
El tiempo en el peor de los casos:
• No es mejor que el ordenamiento por inserción
• El peor tiempo ocurre cuando el arreglo ya está ordenado
Divide y Conquista
QUICKSORT: Complejidad temporal
Divide y Conquista
QUICKSORT: Complejidad temporal
Divide y Conquista
QUICKSORT: Complejidad temporal
El caso promedio es mucho más cercano al mejor caso que la peor caso.
Divide y Conquista
QUICKSORT
Ejercicio:
M I P R I M E R E J E M P L O
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Divide y Conquista
Problema del Torneo de Tenis
Divide y Conquista
Problema del Torneo de Tenis
n es potencia de dos
Cada jugador ha de jugar exactamente una vez contra cada uno de sus posibles
n–1 competidores,
Divide y Conquista
Problema del Torneo de Tenis
La técnica D&C
Día 1
Jugador
• Si n = 2, caso base, sólo hay dos jugadores,
1 2
basta enfrentar uno contra el otro.
2 1
Día 1 2 3 4 5 6 7
Jugador
• Si n > 2, Divide y Conquista: la técnica construye un 1
2
programa para la mitad de los jugadores, aplicando
3
Divide y Conquista
Problema del Torneo de Tenis
Día 1 2 3 4 5 6 7
Ejemplo n= 8 Jugador
1
• Si n > 2: la técnica construye un programa para 2
la mitad de los jugadores 3
4
5
6
7
8
Divide y Conquista
Problema del Torneo de Tenis
Día 1 2 3 4 5 6 7
n= 4 Jugador
1
• Si n > 2: la técnica construye un programa para 2
la mitad de los jugadores 3
4
5
6
7
8
Divide y Conquista
Problema del Torneo de Tenis
Día 1 2 3 4 5 6 7
n= 2 Jugador
1 2
Caso Base: 2 jugadores los enfrentamos
2 1
3
4
5
6
7
8
Divide y Conquista
Problema del Torneo de Tenis
Día 1 2 3 4 5 6 7
n= 4 Jugador
1 2 3 4
Una vez resuelto el caso base, retorna de la recursión
2 1 4 3
y procede a construir la solución:
3 4 1 2
1°) llena la mitad inferior izquierda: 4 3 2 1
enfrenta a los jugadores de numeración más alta 5
(suma n/2) a la solución obtenida para la numeración más baja. 6
7
2°) llena el cuadrante superior derecho:
8
El día n/2 se enfrenta a los jugadores de menor numeración
con los de mayor numeración y el resto de los días se permutan cíclicamente.
1 2 3 4 5 6 7 8
Llenó el primer cuadrante, retorna de la recursión
2 1 4 3 6 7 8 5
y procede a construir la solución:
3 4 1 2 7 8 5 6
1°) llena la mitad inferior izquierda: 4 3 2 1 8 5 6 7
enfrenta a los jugadores de numeración más alta 5 6 7 8 1 4 3 2
(suma n/2) a la solución obtenida para la numeración más baja. 6 5 8 7 2 1 4 3
7 8 5 6 3 2 1 4
2°) llena el cuadrante superior derecho:
El día n/2 se enfrenta a los jugadores de menor numeración 8 7 6 5 4 3 2 1
con los de mayor numeración y el resto de los días se permutan cíclicamente.
Algoritmo:
Torneo ( Tabla, n)
{
if ( n == 2 ) // caso base
enfrentar a los dos jugadores
else
{ divide
Divide y Conquista
Problema del Torneo de Tenis
Complejidad Temporal
Torneo ( Tabla, n)
{
c0 , n = 2
if ( n == 2 ) // caso base
T(n) enfrentar a los dos jugadores
T(n/2) + 3 (n/2)2 c1 + c2 , n > 2 else
{
Torneo (tabla, n/2);
llenar cuadrante inferior izq;
llenar cuadrante superior derecho;
T(n) (n2) llenar cuadrante inferior derecho;
}
}
Divide y Conquista
Problema de la subsecuencia
de suma máxima
Divide y Conquista
Subsecuencia de suma máxima
Por ejemplo:
1 -2 11 -4 13 -5 2 2
Por ejemplo:
1 -2 11 -4 13 -5 2 2
Costoso!!!
Divide y Conquista
Subsecuencia de suma máxima
Divide y Conquista
Subsecuencia de suma máxima
Divide y Conquista
Subsecuencia de suma máxima
Algoritmo para resolver el problema de la SSM por divide y conquista:
bajo
Encontrar_SSM ( A, bajo, alto ) { alto
if (alto == bajo) // caso base: solo un elemento A
return < bajo, alto, A[bajo] >;
medio
else { // cálculo de subproblemas bajo alto
medio = (alto + bajo) / 2; A
Divide y Conquista
Subsecuencia de suma máxima
Encontrar_SSM ( A, bajo, alto ) {
…
…
// Combinar soluciones
<bajoMedio, altoMedio, sumaMedio> =
SolucionMedio( A, bajo, medio, alto);
Divide y Conquista
Subsecuencia de suma máxima
Este problema no es una instancia menor del problema original, ya que tiene la
restricción adicional que el subarreglo debe cruzar el punto medio.
A 1 -2 11 -4 13 -5 2 2
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
Suma = 0
sumaIzq = -∞
suma = 0
for i = medio hasta bajo
suma += A[ i ]
SumaIzq = - ∞ if (suma > sumaIzq )
sumaIzq = suma
indiceIzq = i
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
Suma = 0
Suma + A[ medio ] = -4
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
Suma = 0
Suma + A[ medio ] = -4
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
Suma = 0
Suma + A[ medio ] = -4
Suma + A[ 2 ] = -4 +11 = 7
sumaIzq = -∞
Suma > sumaIzq suma = 0
for i = medio hasta bajo
suma += A[ i ]
SumaIzq = - 4 if (suma > sumaIzq )
sumaIzq = suma
IndiceIzq = medio indiceIzq = i
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
Suma = 0
Suma + A[ medio ] = -4
Suma + A[ 2 ] = -4 +11 = 7
sumaIzq = -∞
Suma > sumaIzq suma = 0
for i = medio hasta bajo
suma += A[ i ]
SumaIzq = 7 if (suma > sumaIzq )
sumaIzq = suma
IndiceIzq = 2 indiceIzq = i
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
Suma = 0
Suma + A[ medio ] = -4
Suma + A[ 2 ] = -4 +11 = 7
sumaIzq = -∞
Suma + A[ 1 ] = -4 +11 - 2 = 5 suma = 0
for i = medio hasta bajo
suma += A[ i ]
SumaIzq = 7 if (suma > sumaIzq )
sumaIzq = suma
IndiceIzq = 2 indiceIzq = i
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
Suma = 0
Suma + A[ medio ] = -4
Suma + A[ 2 ] = -4 +11 = 7
sumaIzq = -∞
Suma + A[ 1 ] = -4 +11 - 2 = 5 suma = 0
for i = medio hasta bajo
Suma + A[ 0 ] = -4 +11 - 2 + 1= 6 suma += A[ i ]
SumaIzq = 7 if (suma > sumaIzq )
sumaIzq = suma
IndiceIzq = 2 indiceIzq = i
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
Suma = 0
sumaDer = -∞
suma = 0
for j = medio + 1 hasta alto
suma += A[ j ]
if (suma > sumaDer )
sumaDer = suma SumaDer = - ∞
indiceDer = j
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
Suma = 0
Suma + A[ medio+1 ] = 13
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
Suma = 0
Suma + A[ medio+1 ] = 13
A 1 -2 11 -4 13 -5 2 2
Suma = 0
Suma + A[ medio+1 ] = 13
Suma + A[ 5 ] = 13 – 5 = 8
sumaDer = -∞
suma = 0
for j = medio + 1 hasta alto
suma += A[ j ]
if (suma > sumaDer )
sumaDer = suma SumaDer = 13
indiceDer = j IndiceDer = 4
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
Suma = 0
Suma + A[ medio+1 ] = 13
Suma + A[ 5 ] = 13 – 5 = 8
sumaDer = -∞ Suma + A[ 6 ] = 13 – 5 + 2= 10
suma = 0
for j = medio + 1 hasta alto
suma += A[ j ]
if (suma > sumaDer )
sumaDer = suma SumaDer = 13
indiceDer = j IndiceDer = 4
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
Suma = 0
Suma + A[ medio+1 ] = 13
Suma + A[ 5 ] = 13 – 5 = 8
sumaDer = -∞ Suma + A[ 6 ] = 13 – 5 + 2= 10
suma = 0
for j = medio + 1 hasta alto Suma + A[ 7 ] = 13 – 5 + 2 + 2 = 12
suma += A[ j ]
if (suma > sumaDer )
sumaDer = suma SumaDer = 13
indiceDer = j IndiceDer = 4
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
SumaIzq = 7 SumaDer = 13
IndiceIzq = 2 IndiceDer = 4
Divide y Conquista
Subsecuencia de suma máxima
0 1 2 3 4 5 6 7
A 1 -2 11 -4 13 -5 2 2
IndiceIzq = 2 IndiceDer = 4
Suma = 20
SolucionMedio
Divide y Conquista
Subsecuencia de suma máxima
Encontrar_SSM ( A, bajo, alto ) {
…
…
// Combinar soluciones
<bajoMedio, altoMedio, sumaMedio> =
SolucionMedio( A, bajo, medio, alto);
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
bajo alto
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio=(alto+bajo)/2= 3
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
medio
Encontrar_SSM ( A, bajo, alto ) {
if (alto = = bajo) // caso base
1 -2 return < bajo, alto, A[bajo] >;
else // cálculo de subproblemas
{ medio = (alto + bajo) / 2;
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
medio
Encontrar_SSM ( A, bajo, alto ) {
if (alto = = bajo) // caso base
1 -2 return < bajo, alto, A[bajo] >;
else // cálculo de subproblemas
medio { medio = (alto + bajo) / 2;
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
medio
1 -2
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
medio
1 -2
< 0,0,1 >
Encontrar_SSM ( A, bajo, alto ) {
if (alto = = bajo) // caso base
1
return < bajo, alto, A[bajo] >;
…
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
medio
Encontrar_SSM ( A, bajo, alto ) {
if …
else // cálculo de subproblemas
1 -2 { medio = (alto + bajo) / 2;
< 0,0,1 > medio+1 // Subproblema: Parte izquierda
<bajoIzq, altoIzq,sumaIzq> = Encontrar_SSM (A, bajo, medio);
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
medio
1 -2
< 0,0,1 > medio+1
Encontrar_SSM ( A, bajo, alto ) {
if (alto = = bajo) // caso base
-2
return < bajo, alto, A[bajo] >;
alto = bajo …
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
medio
1 -2
< 0,0,1 > < 1,1,-2 >
Encontrar_SSM ( A, bajo, alto ) {
if (alto = = bajo) // caso base
-2
return < bajo, alto, A[bajo] >;
alto = bajo …
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
…. Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
….
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
< 0,0,1 > medio Encontrar_SSM ( A, bajo, alto ) {
< 0,1,-1 > …
// Combinar soluciones
1 -2 …
< 0,0,1 > < 1,1,-2 > If ((sumaIzq > sumaDer ) and ( sumaIzq > sumaMedio))
return < bajoIzq, altoIzq, sumaIzq>;
else If ((sumaDer >= sumaIzq) and (sumaDer > = sumaMedio))
return < bajoDer, altoDer, sumaDer>;
else return < bajoMedio, altoMedio, sumaMedio>
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
< 0,0,1 > medio
Encontrar_SSM ( A, bajo, alto ) {
if …
else // cálculo de subproblemas
{ medio = (alto + bajo) / 2;
// Subproblema: Parte izquierda
<bajoIzq, altoIzq,sumaIzq> = Encontrar_SSM (A, bajo, medio);
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
< 0,0,1 > medio Encontrar_SSM ( A, bajo, alto ) {
if (alto = = bajo)
return < bajo, alto, A[bajo] >;
11 -4 else
{ medio = (alto + bajo) / 2;
medio
// Subproblema: Parte izquierda
<bajoIzq, altoIzq,sumaIzq> =
Encontrar_SSM (A, bajo, medio);
…
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
< 0,0,1 > medio
11 -4
medio
Encontrar_SSM ( A, bajo, alto ) {
if (alto = = bajo) // caso base
11 return < bajo, alto, A[bajo] >;
alto = bajo …
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
< 0,0,1 > medio
11 -4
< 2,2,11 >
medio
Encontrar_SSM ( A, bajo, alto ) {
if (alto = = bajo) // caso base
11 return < bajo, alto, A[bajo] >;
…
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
Encontrar_SSM ( A, bajo, alto ) {
< 0,0,1 > medio if …
else // cálculo de subproblemas
{ medio = (alto + bajo) / 2;
// Subproblema: Parte izquierda
11 -4
< 2,2,11 > <bajoIzq, altoIzq,sumaIzq> =
Encontrar_SSM (A, bajo, medio);
medio
// Subproblema: Parte derecha
<bajoDer, altoDer,sumaDer> =
Encontrar_SSM (A, medio+1, alto);
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
< 0,0,1 > medio
11 -4
< 2,2,11 >
medio
Encontrar_SSM ( A, bajo, alto ) {
if (alto = = bajo) // caso base
-4 return < bajo, alto, A[bajo] >;
alto = bajo …
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
< 0,0,1 > medio
11 -4
< 2,2,11 > < 3,3,-4 >
medio
Encontrar_SSM ( A, bajo, alto ) {
if (alto = = bajo) // caso base
-4 return < bajo, alto, A[bajo] >;
alto = bajo …
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
< 0,0,1 > medio Encontrar_SSM ( A, bajo, alto ) {
…
// Subproblema: Parte izquierda
11 -4
< 2,2,11 > < 3,3,-4 >
medio // Subproblema: Parte derecha
…
// Combinar soluciones
<bajoMedio, altoMedio, sumaMedio> =
SolucionMedio( A, bajo, medio, alto);
…. Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
Encontrar_SSM ( A, bajo, alto ) {
1 -2 11 -4 …
11 -4 ….
< 2,2,11 > < 3,3,-4 >
medio
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
1 -2 11 -4
< 0,0,1 > medio < 2,2,11 >
< 2,3,7 > retorna la tripla con suma máxima
11 -4
< 2,2,11 > < 3,3,-4 >
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
// Combinar soluciones
1 -2 11 -4 <bajoMedio, altoMedio, sumaMedio> =
SolucionMedio( A, bajo, medio, alto);
< 0,0,1 > medio < 2,2,11 >
Suma = 0
Suma + A[ medio ] = -2
Suma + A[ 0 ] = -2 +1 = -1
SumaIzq = -1
IndiceIzq = 0
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
// Combinar soluciones
1 -2 11 -4 <bajoMedio, altoMedio, sumaMedio> =
SolucionMedio( A, bajo, medio, alto);
< 0,0,1 > medio < 2,2,11 >
Suma = 0
Suma + A[ medio+1 ] = 11
Suma + A[ 3 ] = 11-4 = 7
SumaDer = 11
IndiceDer = 2
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
// Combinar soluciones
1 -2 11 -4 <bajoMedio, altoMedio, sumaMedio> =
SolucionMedio( A, bajo, medio, alto);
< 0,0,1 > medio < 2,2,11 >
SumaIzq = -1 SumaDer = 11
IndiceIzq = 0 IndiceDer = 2
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
medio
< 0, 2, 10 >
// Combinar soluciones
1 -2 11 -4 <bajoMedio, altoMedio, sumaMedio> =
SolucionMedio( A, bajo, medio, alto);
< 0,0,1 > medio < 2,2,11 >
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
< 2,2,11 > medio
13 -5 2 2
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
< 2,2,11 > medio
13 -5 2 2
// Combinar Soluciones
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
< 2,2,11 > medio < 4,4,13 >
< 4,7,12 >
13 -5 2 2
< 4,4,13 > < 6,7,4 >
< 4,5,8 > < 6,7,4 >
13 -5 2 2
< 4,4,13 > < 5,5,-5 > < 6,6,2 > < 7,7,2 >
13 -5 2 2
< 4,4,13 > < 5,5,-5 > < 6,6,2 > < 7,7,2 >
Divide y Conquista
Subsecuencia de suma máxima
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
< 2,2,11 > medio < 4,4,13 >
Ir a SolucionMedio
Divide y Conquista
Subsecuencia de suma máxima
< 2,4,20 >
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
< 2,2,11 > medio < 4,4,13 >
A 1 -2 11 -4 13 -5 2 2
0 1 2 3 4 5 6 7
< 2,2,11 > < 4,4,13 >
Divide y Conquista
Subsecuencia de suma máxima
Complejidad temporal:
co n=1
T (n) =
2 T (n/2) + n c1 n>1
T SolucionMedio
Divide y Conquista
Subsecuencia de suma máxima
Complejidad temporal:
co n=1
T (n) =
2 T (n/2) + n c1 n>1
T SolucionMedio
Divide y Conquista
Subsecuencia de suma máxima
Para pensar:
Escriba un algoritmo no recursivo que en tiempo lineal resuelva el problema
de hallar la subsecuencia de suma máxima
Pistas:
Ninguna secuencia de suma máxima comienza o termina con un número negativo.
Recorrer el arreglo de izquierda a derecha, guardando el subarreglo máximo encontrado
hasta el momento.
Si conoce el subarreglo de suma máxima A[1..j], extienda la solución para encontrar un
subarreglo máximo que termina en j+1, usando la siguiente información:
Para algún 1 <= i <= j+1, un subarreglo máximo de A[1..j+1] es
• o un subarreglo máximo de A[1..j]
• o un subarreglo máximo de A[i…j+1]
Divide y Conquista
BIBLIOGRAFÍA