Mateo Sanabria Ardila
ISIS1105: Diseño y análisis de algoritmos
Se rompe el problema en subproblemas que son idénticos al original pero de menor tamaño:
Se soluciona los subproblemas
Se combinan las soluciones, para dar solución al problema original
Búsqueda Binaria
Merge Sort
Quicksort
Problema: Cantidad de años
Problema: Alcanzar el Valhalla
Pares de puntos mas cercanos
Problema del máximo subarreglo
Algoritmo de Strassen (multiplicación de matrices)
Se adapta naturalmente a la computación paralela
Usualmente hacen uso eficiente de memoria (DEPENDE!)
Recursión (Stack overflow)
Subproblemas repetidos
Donde a es el número de subproblemas y 1/b es la fracción de los datos a procesar en cada caso recursivo
Divide: Divide los n-elementos del arreglo en dos subarreglos de tamaño n/2 cada uno
Conquista: Ordena cada una de los subarreglos usado Merge-Sort
Combina: Une (Merge) dos subarreglos ordenados para entregar la respuesta ordenada
El caso Base se da cuando se alcanza un arreglo de longitud 1
def merge_sort(array):
if len(array)<2:
return array
else:
midpoint=len(array)//2
left,right = array[:midpoint], array[midpoint:]
left,right = merge_sort(left), merge_sort(right)
return merge(left,right)
def merge(left,right):
result=[]
l_pointer = r_pointer = 0
while l_pointer < len(left) and r_pointer < len(right):
if left[l_pointer] < right[r_pointer]:
result.append(left[l_pointer])
l_pointer+=1
else:
result.append(right[r_pointer])
r_pointer+=1
result.extend(left[l_pointer:])
result.extend(right[r_pointer:])
return result
def merge_sort(array):
if len(array)<2: # <- ?
return array # <- ?
else:
midpoint=len(array)//2 <- #?
left,right = array[:midpoint], array[midpoint:] # <- ?
left,right = merge_sort(left), merge_sort(right) # <- ?
return merge(left,right) # <- ?
Cual es la complejidad del algoritmo?
Divide: Toma tiempo constate, k.
Conquista: El problema de divide en dos subproblemas de tamaño n/2, se tiene 2R(n/2).
Combina: Es lineal, luego el costo es, n.
Divide: Dividir el arreglo inicial A[0:N] en dos L = A[0:q] y R = A[q+1:N] tal que todo elemento de L es menor o igual que A[q] y todo elemento de R es mayor o igual que A[q].
Conquista: Ordenar L y R llamando recursivamente a Quick-Sort.
Combina: No es necesario, el arreglo ya se ordeno en los pasos anteriores.
def quick_sort(array,start,end):
if start < end:
q = partition(array,start,end)
quick_sort(array,start,q-1)
quick_sort(array,q+1,end)
def partition(array,start,end):
x = array[end]
i = start-1
for j = start to end-1
if array[j] <= x
i += 1
array[i],array[j] = array[j],array[i]
array[i+1],array[end] = array[end],array[i+1]
return i+1