Clase 13 Algoritmos Voraces
Clase 13 Algoritmos Voraces
Clase 13 Algoritmos Voraces
Greedy Algorithms
INTRODUCCIÓN
El método que produce algoritmos ávidos es un
método muy sencillo y que puede ser aplicado a
numerosos problemas, especialmente los de
optimización.
Dado un problema con n entradas el método consiste
en obtener un subconjunto de éstas que satisfaga
una determinada restricción definida para el
problema. Cada uno de los subconjuntos que
cumplan las restricciones diremos que son
soluciones prometedoras. Una solución
prometedora que maximice o minimice una
función objetivo la denominaremos solución
óptima.
Como ayuda para identificar si un problema es susceptible de ser resuelto
por un algoritmo ávido vamos a definir una serie de elementos que han
de estar presentes en el problema:
2. Para ello trabajará por etapas, tomando en cada una de ellas la decisión que le
parece la mejor, sin considerar las consecuencias futuras, y por tanto escogerá
de entre todos los candidatos el que produce un óptimo local para esa etapa,
suponiendo que será a su vez óptimo global para el problema.
En primer lugar, porque no todos los problemas admiten esta estrategia de solución.
De hecho, la búsqueda de óptimos locales no tiene por qué conducir siempre a
un óptimo global, como veremos en varios ejemplos. La estrategia de los
algoritmos ávidos consiste en tratar de ganar todas las batallas sin pensar que para
ganar la guerra muchas veces es necesario perder alguna batalla.
Desgraciadamente, y como en la vida misma, pocos hechos hay para los que
podamos afirmar sin miedo a equivocarnos que lo que parece bueno para hoy
siempre es bueno para el futuro. Y aquí radica la dificultad de estos algoritmos.
El nombre de algoritmos ávidos, o voraces (su nombre original proviene del término
inglés greedy) se debe a su comportamiento: en cada etapa “toman lo que
pueden” sin analizar consecuencias, es decir, son glotones por naturaleza.
En lo que sigue veremos algunos problemas que muestran cómo diseñar algoritmos
ávidos y cuál es su comportamiento. En este tipo de algoritmos el proceso no
acaba cuando disponemos de la implementación del procedimiento que lo
lleva a cabo. Lo importante es la demostración de que el algoritmo encuentra
la solución óptima en todos los casos, o bien la presentación de un
contraejemplo que muestra los casos en donde falla.
EL PROBLEMA DEL CAMBIO
Suponiendo que el sistema monetario de un país está formado por monedas de
valores v1,v2,...,vn, el problema del cambio de dinero consiste en descomponer
cualquier cantidad dada M en monedas de ese país utilizando el menor número
posible de monedas.
a) Suponiendo que cada moneda del sistema monetario del país vale al menos el
doble que la moneda de valor inferior, que existe una moneda de valor unitario,
y que disponemos de un número ilimitado de monedas de cada valor.
Consulte la demostración.
EL PROBLEMA DE LOS RECORRIDOS DEL
CABALLO DE AJEDREZ
BEGIN
InicTablero(t,n) (* inicializa las casillas del tablero a 0 *)
FOR i 1 TO n*n DO
t[x,y] i
IF NOT NuevoMov(t,n,x,y) AND (i<n*n-1) THEN
RETURN FALSE
END
END
RETURN TRUE (* hemos recorrido las n*n casillas *)
END Caballo
algoritmo NuevoMov(VAR t:tablero; n:INT; VAR x,y:INT):BOOLEAN
(*Esta función es la que va a ir calculando la nueva casilla a la que salta el caballo
siguiendo la indicación del enunciado, devolviendo FALSE si no puede Moverse*)
INT accesibles,minaccesibles,i,solx,soly,nuevax,nuevay
BEGIN
minaccesibles 9
solx x
soly y
FOR i:=1 TO 8 DO
IF Salto(t,n,i,x,y,nuevax,nuevay) THEN
accesibles:=Cuenta(t,n,nuevax,nuevay)
IF (accesibles>0) AND (accesibles<minaccesibles) THEN
minaccesibles accesibles
solx nuevax soly nuevay
END
END
END
X solx
y soly
RETURN (minaccesibles<9)
END NuevoMov
Algoritmo Salto(VAR t:tablero; n,i,x,y: INT;VAR nx,ny:INT ) :BOOL
(* i indica el numero del movimiento, (x,y) es la casilla actual, y (nx,ny) es la casilla a
donde salta. *)
BEGIN
CASE i OF
1: nx x-2 ny y+1
2: nx x-1 ny y+2
3: nx x+1 ny y+2
4: nx x+2 ny y+1
5: nx x+2 ny y-1
6: nx x+1 ny y-2
7: nx x-1 ny y-2
8: nx x-2 ny y-1
END
RETURN((1<=nx) AND (nx<=n) AND (1<=ny) AND (ny<=n) AND (t[nx,ny]=0))
END Salto
La función Salto calcula las coordenadas de la casilla a
donde salta el caballo (tiene 8 posibilidades), y devuelve si
es posible o no realizar ese movimiento ya que la casilla
puede estar ocupada o bien salirse del tablero.
Algoritmo Caballos()
tablero t
INT n,i,j
BEGIN
FOR n 4 TO TAMMAX DO
print (“Dimension = “, n) println;
FOR i1 TO n DO
FOR j 1 TO n DO
IF Caballo(t,n,i,j) THEN
print(“ Desde: “)
print(i,j)
print(“ tiene solucion.”)
END
END
END
WrLn()
END
END Caballos.
La salida del programa anterior nos permite inferir un patrón general para las
soluciones del problema:
• Para n = 4, el problema no tiene solución.
• Para n > 4, n par, el problema tiene solución para cualquier casilla inicial.
• Para n > 4, n impar, el problema tiene solución para aquellas casillas iniciales
(x0,y0) que verifiquen que x0 + y0 sea par, es decir, si el caballo comienza su
recorrido en una casilla blanca.