You are on page 1of 582

Algoritmia básica

Grado en Ingeniería Informática


Universidad de Zaragoza

Algoritmia básica - Javier Campos (Universidad de Zaragoza)


Introducción a la algoritmia

Algoritmia básica - Javier Campos (Universidad de Zaragoza)


Introducción a la algoritmia

AB Algoritmia =
Algoritmia = tratamiento sistemático de
técnicas fundamentales para
el diseño y análisis de
algoritmos eficientes

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 2


Introducción a la algoritmia
• Computadores cada vez más rápidos
y a más bajo precio:
– Se resuelven problemas
de cálculo antes impensables.
– Inconscientemente se tiende a restar
importancia al concepto de eficiencia.
• Existen problemas que seguirán siendo intratables si se
aplican ciertos algoritmos por mucho que se aceleren
los computadores
⇒ importancia de
nuevas soluciones eficientes

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 3


Introducción a la algoritmia
• Ejemplo:
“En Agosto de 1977, Scientific American proponía a sus lectores el reto
consistente en descifrar un mensaje secreto, para así ganar cien dólares.
Parecía algo seguro: se estimaba en aquel momento que el ordenador más
rápido existente, empleando el algoritmo más eficiente de los conocidos,
no podría ganar la apuesta salvo funcionando sin interrupción durante un
tiempo equivalente a millones de veces la edad del Universo. Sin
embargo, ocho meses de cálculo que comenzaron dieciséis años después
bastaron para la tarea. ¿Qué había pasado?…”

G. Brassard y P. Bratley
Fundamentos de Algoritmia (Prólogo)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 4


Introducción a la algoritmia
• Un curso de algoritmia
NO ES
– ni un curso de programación
(ya deberíais saber programar)
– ni un curso de estructuras de datos
(ya deberíais conocer las fundamentales)
TAMPOCO ES
– una colección de “recetas” Si tu problema es
o algoritmos listos para ordenar un fichero
secuencial de
ser introducidos en el enteros
computador para resolver entonces ejecuta
el algoritmo A026.
problemas específicos

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 5


Introducción a la algoritmia
• Un curso de algoritmia tiene como objetivo principal:

– dar más herramientas


fundamentales para
facilitar el desarrollo
de programas

¿qué herramientas?:

técnicas o “esquemas” de diseño de


algoritmos eficientes

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 6


Introducción a la algoritmia
• Un medio para alcanzar ese objetivo es:

– presentar cada esquema de forma


genérica, incidiendo en los
principios que conducen a él, e

– ilustrar el esquema mediante ejemplos concretos de


algoritmos tomados de varios dominios de aplicación

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 7


Introducción a la algoritmia
• Un problema muy sencillo:

Multiplicación de dos enteros positivos con lápiz y


papel.
– En España: – En Inglaterra:
981
1234
981
1234

3924 981
2943 1962
1962 2943
981 3924
1210554 1210554

– Ambos métodos son muy similares, los llamaremos algoritmo


“clásico” de multiplicación.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 8
Introducción a la algoritmia
– Algoritmo de multiplicación “a la rusa”:

 981 1234 1234


490 2468
 245 4936 4936
122 9872
 61 19744 19744
30 39488
 15 78976 78976
 7 157952 157952
 3 315904 315904
 1 631808 631808
1210554

• Ventaja: no hay que almacenar los productos parciales.


• Sólo hay que saber sumar y dividir por 2.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 9


Introducción a la algoritmia
– Todavía otro algoritmo:
• De momento, exigimos que ambos números tengan igual nº de cifras y
que éste sea potencia de 2.
Por ejemplo: 0981 y 1234.
• En primer lugar, partimos ambos números por la mitad y hacemos
cuatro productos:
multiplicar desplazar resultado
1) 09 12 4 108····
2) 09 34 2 306··
3) 81 12 2 972··
4) 81 34 0 2754
1210554

doble del nº de cifras nº de cifras

Es decir, hemos reducido un producto de nos de 4 cifras en cuatro


productos de nos de 2 cifras, varios desplazamientos y una suma.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 10
Introducción a la algoritmia
• Los productos de números de 2 cifras pueden hacerse con la misma técnica.
Por ejemplo, 09 y 12:
multiplicar desplazar resultado
1) 0 1 2 0··
2) 0 2 1 0·
3) 9 1 1 9·
4) 9 2 0 18
108
– Es un ejemplo de algoritmo que utiliza la técnica de “divide y vencerás”.
– Tal y como lo hemos presentado…
NO mejora en eficiencia al algoritmo clásico.
– Pero, puede mejorarse:
Es posible reducir un producto de dos números de muchas cifras a 3 (en
vez de 4) productos de números de la mitad de cifras, y éste SÍ que mejora
al algoritmo clásico.
– Y aún se conocen métodos más rápidos para multiplicar números muy
grandes.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 11


Introducción a la algoritmia
• Ideas clave:
– Incluso para un problema tan básico pueden construirse MUCHAS
soluciones.
– El método clásico lo usamos con lápiz y papel porque nos resulta muy
familiar (lo que se aprende en la infancia…).
– El método “a la rusa” se implementa en hardware en los computadores
por la naturaleza elemental de los cálculos intermedios.
– El método de divide y vencerás es más rápido si se quiere multiplicar
números grandes.
La algoritmia estudia las propiedades de los algoritmos y nos ayuda a
elegir la solución más adecuada en cada situación.

En muchos casos, una buena elección ahorra tiempo y dinero.


En algunos casos, una buena elección marca la diferencia entre poder
resolver un problema y no poder hacerlo.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 12


Introducción a la algoritmia
• ¿A quién puede interesar este curso?

A todo aquél a quien:


– le guste diseñar algoritmos para resolver nuevos problemas o
algoritmos mejores a los triviales para resolver viejos
problemas, y

O(n2) ¿O(nlog n)?

– tenga curiosidad por conocer, por ejemplo, cómo se resuelven


los siguientes problemas:

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 13


Introducción a la algoritmia

– ¿Cómo multiplicar dos números enteros de forma más


eficiente que con el algoritmo clásico?

– ¿Cómo se compactan ficheros mediante el algoritmo de


Huffman?

– ¿Cómo se consiguen implementaciones muy eficientes de la


multiplicación y potenciación de enteros muy grandes para el
algoritmo RSA?

– ¿Por qué funcionan algoritmos vistos en Matemática Discreta


como el de Dijkstra, Prim o Kruskal?
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 14
Introducción a la algoritmia

– ¿Existen árboles binarios de búsqueda óptimos suponiendo


que se conocen las probabilidades de búsqueda de cada
clave?

– ¿Alguna forma de resolver el problema del viajante de


comercio?

– ¿Cómo se compara el ADN de un Homo sapiens y de un


Homo neanderthalensis?

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 15


Algoritmia básica: Contenidos de la asignatura
• Introducción a la algoritmia
• Algoritmos voraces
• Divide y vencerás
• Programación dinámica
• Búsqueda con retroceso
• Ramificación y poda
• Programación lineal y reducciones

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 16


Algoritmia básica: Bibliografía básica

[CLRS09] T.H. Cormen, C.E. Leiserson, R.L. Rivest, C. Stein. Introduction to


Algorithms (3rd edition), The MIT Press, 2009.

[DPV08] S. Dasgupta, C. Papadimitriou, U. Vazirani. Algorithms, McGraw-


Hill, 2008.

[BB97] G. Brassard, P. Bratley. Fundamentos de Algoritmia, Prentice Hall,


1997.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 17


Algoritmia básica: Bibliografía complementaria

[KT05] J. Kleinberg, E. Tardos. Algorithm Design, Addison-Wesley,


2005.

[PG02] I. Parberry and W. Gasarch. Problems on Algorithms (2nd


edition), free book, 2002.

Además: transparencias y otro material adicional disponibles en la


web de la asignatura, hojas de ejercicios, enlaces de Internet
(ejemplo: http://jeffe.cs.illinois.edu/teaching/algorithms/), etc.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 18


Chuleta
• Coste de algoritmos recursivos:
El coste T(n) de una función para datos de tamaño n se define
en función del coste T(m) de las llamadas recursivas para
otros tamaños m (menores que n)

Teorema (Master Theorem):


Θ( n k ) si a < 1
 f ( n) si 0 ≤ n < c   k +1
T1 ( n) =   ⇒ T1 ( n ) ∈ Θ( n ) si a = 1
 1
a ⋅ T ( n − c ) + b ⋅ n k
si c ≤ n  Θ(a n / c ) si a > 1

Θ(n k ) si a < c k
 g ( n) si 0 ≤ n < c  
T2 (n) =   ⇒ T2 (n) ∈ Θ(n k ⋅ log n) si a = c k
a ⋅ T2 (n / c) + b ⋅ n si c ≤ n
k
 Θ(n log c a ) si a > c k

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 19


Algoritmos voraces

Algoritmia básica - Javier Campos (Universidad de Zaragoza)


Algoritmos voraces

• Introducción y primer ejemplo 3


• El problema de la mochila 9
• Caminos mínimos en grafos 17
• Árboles de recubrimiento de coste mínimo 39
• Consideraciones sobre la corrección del esquema voraz 55
• Códigos de Huffman 58
• El problema de la selección de actividades 66
• El problema de la minimización del tiempo de espera 71
• Fundamentos teóricos del esquema voraz 75
• Un problema de planificación de tareas a plazo fijo 85
• Heurísticas voraces 91
– Coloreado de grafos 91
– El problema del viajante de comercio 94

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 2


El esquema voraz: Introducción y primer ejemplo
• Es uno de los esquemas más simples y al mismo tiempo de los
más utilizados.
• Típicamente se emplea para resolver problemas de
optimización:
– existe una entrada de tamaño n que son los candidatos a formar parte de
la solución;
– existe un subconjunto de esos n candidatos que satisface ciertas
restricciones: se llama solución factible;
– hay que obtener la solución factible que maximice o minimice una cierta
función objetivo: se llama solución óptima.
• Ejemplos:
– encontrar la secuencia óptima para procesar un conjunto de tareas por un
computador,
– hallar un camino mínimo en un grafo,
– problema de la mochila,…
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 3
El esquema voraz: Introducción y primer ejemplo
• El esquema voraz procede por pasos:
– inicialmente el conjunto de candidatos escogidos es vacío;
– en cada paso, se intenta añadir al conjunto de los escogidos “el mejor” de
los no escogidos (sin pensar en el futuro), utilizando una función de
selección basada en algún criterio de optimización (puede ser o no ser la
función objetivo);
– tras cada paso, hay que ver si el conjunto seleccionado es completable
(i.e., si añadiendo más candidatos se puede llegar a una solución);
• si el conjunto no es completable, se rechaza el último candidato elegido y no
se vuelve a considerar en el futuro;
• si es completable, se incorpora al conjunto de escogidos y permanece
siempre en él;
– tras cada incorporación se comprueba si el conjunto resultante es una
solución;
– el algoritmo termina cuando se obtiene una solución;
– el algoritmo es correcto si la solución encontrada es siempre óptima;
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 4
El esquema voraz: Introducción y primer ejemplo
• Esquema genérico:
función voraz(C:conjunto) devuelve conjunto
{C es el conjunto de todos los candidatos}
principio
S:=Ø; {S es el conjunto en el que se construye la solución}
mq ¬solución(S) ∧ C≠Ø hacer
x:=elemento de C que maximiza seleccionar(x);
C:=C-{x};
si completable(S∪{x})
entonces S:=S∪{x}
fsi
fmq;
si solución(S)
entonces devuelve S
sino devuelve no hay solución
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 5


El esquema voraz: Introducción y primer ejemplo
• Problema del cambio en monedas.
– Se trata de devolver una cantidad de euros con el
menor número posible de monedas.
– Se parte de:
• un conjunto de tipos de monedas válidas, de las que se supone que hay cantidad
suficiente para realizar el desglose, y de
• un importe a devolver.
• Elementos fundamentales del esquema:
– Conjunto de candidatos: cada una de las monedas de los diferentes tipos que se
pueden usar para realizar el desglose del importe dado.
– Solución factible: un conjunto de monedas devuelto tras el desglose y cuyo valor
total es igual al importe a desglosar.
– Completable: la suma de los valores de las monedas escogidas en un momento
dado no supera el importe a desglosar.
– Función de selección: elegir si es posible la moneda de mayor valor de entre las
candidatas.
– Función objetivo: número total de monedas utilizadas en la solución (debe
minimizarse).
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 6
El esquema voraz: Introducción y primer ejemplo
• Solución:
tipo moneda=(M25,M10,M5,M1) {por ejemplo}

función cambia(importe:nat; valor:vector[moneda] de nat)


devuelve vector[moneda] de nat
variables mon:moneda; cambio:vector[moneda] de nat
principio
para todo mon en moneda hacer
cambio[mon]:=0
fpara;
para mon:=M25 hasta M1 hacer
mq valor[mon]≤importe hacer
cambio[mon]:=cambio[mon]+1;
importe:=importe-valor[mon]
fmq
fpara;
devuelve cambio
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 7


El esquema voraz: Introducción y primer ejemplo
• Problemas sobre el problema del cambio en monedas:
– Demostrar la corrección del algoritmo.
– Demostrar, buscando contraejemplos, que el algoritmo no es
óptimo si se añade un nuevo tipo de moneda de 12 euros o si
se elimina alguno de los tipos existentes.
Demostrar que, en esas condiciones, el algoritmo puede
incluso no encontrar solución alguna aunque ésta exista.
• Otro problema:
– ¿Es el método de ordenación por selección directa un
algoritmo voraz?
Si es así, ¿cuáles son las funciones utilizadas (“selección”,
“completable”, “solución”)?

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 8


El problema de la mochila
• Se tienen n objetos fraccionables y una mochila.
• El objeto i tiene peso pi, 1≤i ≤ n.
• La mochila tiene capacidad C.
• Si se mete una fracción xi, 0 ≤ xi ≤ 1, del objeto i en la
mochila, entonces se consigue un beneficio bixi.
• El objetivo es llenar la mochila de manera que se
maximice el beneficio total.
• Pero como la mochila tiene capacidad C, el peso total
de todos los objetos metidos en ella no puede superar
esa cantidad.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 9


El problema de la mochila
• Formalmente: maximizar Σ
1≤i≤n
bixi (1)

sujeto a Σ pixi ≤ C (2)


1≤i≤n

con 0≤xi≤1, bi>0, pi>0, 1≤i≤n (3)

• Una solución factible es cualquier n-tupla (x1,…,xn) que


satisfaga (2) y (3).
• Una solución óptima es cualquier solución factible para la que
(1) sea máximo.
• Si p1+⋅⋅⋅+pn≤C, entonces obviamente xi=1, 1≤i≤n, es una
solución óptima.
• Por tanto, supongamos que p1+⋅⋅⋅+pn>C.
• Nótese además que todas las soluciones óptimas llenarán la
mochila por completo (podemos poner ‘=‘ en (2)).
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 10
El problema de la mochila
• Ejemplo:
n=3 C=17
(b1,b2,b3)=(40,36,22)
(p1,p2,p3)=(15,12,8)

• Tres soluciones factibles (entre otras muchas):

Σ bixi
(x1,x2,x3) 1≤i≤3
(i) (1,1/6,0) 46
(ii) (0,3/4,1) 49
(iii) (0,1,5/8) 49’75
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 11
El problema de la mochila
• Solución voraz:
– El conjunto de candidatos son los objetos, tomándose de ellos
cierta fracción.
– Un conjunto de candidatos es completable si la suma de sus
pesos no supera la capacidad de la mochila, y es una solución
si iguala dicha capacidad.
Σ bixi.
– La función objetivo a maximizar es 1≤i≤n

– La función de selección es la más difícil de determinar.


• Si procedemos vorazmente, en cada paso debemos considerar un
objeto y tomar cierta fracción suya.
• La cuestión de qué fracción se toma es más fácil de resolver: si hemos
elegido el mejor candidato, tomamos todo lo que podamos de él.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 12


El problema de la mochila
– ¿Cuál es el mejor candidato (es decir, la mejor función de
selección)?
– Volvamos al ejemplo:
• Primera estrategia: elegir el objeto con mayor beneficio total (el
primero). Sin embargo, la mochila se llena muy rápidamente con poco
beneficio total.
• Segunda estrategia: elegir el objeto que llene menos la mochila, para
acumular beneficios de un número mayor de objetos. Sin embargo, es
posible que se elija un objeto con poco beneficio simplemente porque
pesa poco.
• La tercera estrategia, que es la óptima, es tomar siempre el objeto que
proporcione mayor beneficio por unidad de peso.
– Los algoritmos resultantes de aplicar cualquiera de las dos
primeras estrategias también son voraces, pero no calculan la
solución óptima.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 13
El problema de la mochila
constante n=... {número de objetos}
tipo vectReal=vector[1..n] de real

{Pre:∀i∈1..n:peso[i]>0 ∧
∀i∈1..n-1:benef[i]/peso[i]≥benef[i+1]/peso[i+1]}
función mochila(benef,peso:vectReal; cap:real) devuelve vectReal
variables resto:real; i:entero; sol:vectReal
principio
para todo i en 1..n hacer
sol[i]:=0.0 {inicializar solución}
fpara;
resto:=cap; {capacidad restante}
i:=1;
mq (i≤n) and (peso[i]≤resto) hacer
sol[i]:=1; resto:=resto-peso[i]; i:=i+1
fmq;
si i≤n entonces sol[i]:=resto/peso[i] fsi;
devuelve sol
fin
{Post: sol es solución óptima del problema de la mochila}

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 14


El problema de la mochila
• Coste temporal: Θ(n)
Θ(nlog n) si se tiene en cuenta que hay que ordenar primero los vectores.
• Demostración de la corrección:
Sea X=(x1,…,xn) la solución generada por el algoritmo voraz.
Si todos los xi son iguales a 1, la solución es claramente óptima.
Luego, sea j el menor índice tal que xj≠1.
Por tanto xi=1 para 1≤i<j, xi=0 para j<i≤n, y 0≤xj<1.
Si X no es óptima ent. existe otra solución factible Y=(y1,…,yn) tal que
Σ biyi > Σ bixi.
Sin perdida de generalidad, asumimos que Σ piyi =C.
Sea k el menor índice tal que yk≠xk (claramente, existe ese k).
Se verifica: yk<xk . En efecto:
• Si k<j entonces xk=1. Pero yk≠xk luego yk<xk .
• Si k=j ent., puesto que Σ piyi =C y yi=xi para 1≤i<j, se sigue que yk<xk ó Σ piyi >C.
• Si k>j entonces Σ piyi > C, y eso no es posible.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 15


El problema de la mochila
Ahora, supongamos que aumentamos yk hasta xk y disminuímos tantos
(yk+1,…,yn) como sea necesario para que la capacidad utilizada siga siendo C.
Se obtiene así una nueva solución Z=(z1,…,zn)
con zi=xi, para 1≤i≤k y Σk<i≤n pi(yi -zi)=pk(zk-yk).
Entonces:
Σ1≤i≤n bizi = Σ1≤i≤n biyi + (zk-yk)pkbk/pk -
- Σk<i≤n (yi -zi)pibi/pi
≥ Σ1≤i≤n biyi +
+ [(zk-yk)pk - Σk<i≤n (yi -zi)pi]bk/pk
= Σ1≤i≤n biyi
Si Σ1≤i≤n bizi > Σ1≤i≤n biyi entonces Y no puede ser óptima.
Si esas sumas son iguales entonces bien Z=X y X es óptima, o bien Z≠X.
En este último caso, se usa de nuevo el mismo argumento hasta demostrar
que bien Y no es óptima o bien Y se transforma en X, demostrando que X
también es óptima. 
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 16
Caminos mínimos en grafos
• Grafos etiquetados con pesos no negativos

12 3 3 12
3 3
5 5
1 2 5 1 2 5
21 4 21 4
4 4
• Búsqueda de caminos de longitud mínima
– longitud o coste de un camino: suma de los pesos de las aristas que lo componen
– cálculo de la longitud mínima de los caminos existentes entre dos vértices dados
• Características del tipo de dato de las etiquetas (o pesos):
– dominio ordenado (<, =, ≤)
– operación suma (+):
• conmutativa
• con elemento neutro (0), que es además el peso más pequeño posible
• con elemento idempotente (∞), que es además el peso más grande posible

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 17


Caminos mínimos en grafos
• Representaciones de grafos: Matriz de adyacencia
– Grafo dirigido G=(V,A) con V={1,2,…,n}.
– La matriz de adyacencia para G es una matriz A de dimensiones n × n de
elementos booleanos en la que A[i,j] es verdad si y sólo si existe una arista
en G que va del vértice i al vértice j.
constante n = ... {cardinal de V}
tipo grafo = vector[1..n,1..n]de booleano

1
falso verdad falso

2 A = verdad falso verdad


Grafo
falso falso falso
dirigido
3
Matriz de adyacencia
– En el caso de un grafo no dirigido, la matriz de adyacencia tiene la
particularidad de ser simétrica.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 18


Caminos mínimos en grafos
– La representación de la matriz de adyacencia es útil para aquellos algoritmos
que precisan saber si existe o no una arista entre dos vértices dados.
– En el caso de grafos etiquetados con pesos, los elementos de la matriz
pueden ser enteros o reales (en lugar de booleanos) y representar el peso de la
arista. Si no existe una arista de i a j, debe emplearse un valor que no pueda
ser una etiqueta válida para almacenarse en A[i,j].
– Un inconveniente de la representación de la matriz de adyacencia es que
requiere un espacio en Θ(n2) aunque el grafo tenga muy pocas aristas.
– Dado un grafo G=(V,A) representado mediante su matriz de adyacencia, la
pregunta ¿(u,v)∈A? se puede contestar en un tiempo en Θ(1).
– Sin embargo, la operación sucesores(g,v) necesita un tiempo en Θ(n) (pues
hay que recorrer una fila completa de la matriz).
– Más aún, para saber, por ejemplo, si un grafo no dirigido representado
mediante su matriz de adyacencia es conexo, o simplemente para conocer el
número de aristas, los algoritmos requieren un tiempo en Θ(n2), lo cual es
más de lo que cabría esperar.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 19


Caminos mínimos en grafos
• Listas de adyacencia
– Esta representación sirve para mejorar la eficiencia de los algoritmos
sobre grafos que necesitan acceder a los vértices sucesores a uno dado.
– Consiste en almacenar n listas enlazadas mediante punteros de forma que
la lista i-ésima contiene los vértices sucesores del vértice i.
1
constante n = ... {cardinal de V}
tipos ptNodo = ↑nodo;
Grafo 2
nodo = registro
dirigido
vértice:1..n;
3
sig:ptNodo
freg
2 nil
grafo = vector[1..n] de ptNodo 1
2 1 3 nil
3 nil

Vector de listas de adyacencia

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 20


Caminos mínimos en grafos
– La representación de un grafo con listas de adyacencia requiere un espacio
del orden del máximo entre n (el número de vértices) y a (el nº de aristas).
– En el caso de un grafo no dirigido, si (u,v)∈A entonces el vértice v estará
en la lista correspondiente al vértice u, y el vértice u lo estará a su vez en
la lista de adyacencia del vértice v.
– Para representar un grafo etiquetado con pesos basta con añadir otro
campo al tipo nodo que almacene el peso correspondiente.
– Acceder a la lista de los vértices sucesores de uno dado lleva un tiempo
constante.
– Sin embargo, consultar si una determinada arista (u,v) está en el grafo
precisa recorrer la lista asociada al vértice u, lo que en el caso peor se
realiza en Θ(n).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 21


Caminos mínimos en grafos
– En el caso de un grafo dirigido, si se necesita saber los
predecesores de un vértice dado, la representación con listas
de adyacencia no es adecuada.

Ese problema puede superarse si se almacena otro vector de n


listas de forma que la lista i-ésima contenga los vértices
predecesores del vértice i.

Estas listas se llaman listas de adyacencia inversa.


1

2 nil
2 1
2 1 nil
3
2 nil
3

Grafo Vector de listas de adyacencia inversa


dirigido
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 22
Caminos mínimos en grafos
• Listas múltiples de adyacencia
– En el caso de grafos dirigidos, las listas de adyacencia directa e inversa
pueden representarse de forma más compacta…
– Una lista múltiple es una estructura dinámica de datos enlazados mediante
punteros en la que cada dato puede pertenecer a dos o más listas.
– Hay un nodo por cada una de las aristas del grafo.
– Cada nodo guarda la clave de dos vértices (origen y destino de la arista) y
dos punteros: el primero al nodo que guarda la siguiente arista que tiene el
mismo vértice destino y el segundo al nodo que guarda la siguiente arista
que tiene el mismo vértice origen.
1 Listas de adyacencia inversa
1 2 3

3 1 2 nil nil
1
2 2 1 nil 2 3 nil nil
Grafo dirigido
3 nil

Listas de adyacencia

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 23


Caminos mínimos en grafos

constante n = ... {cardinal de V}


tipos ptNodo = ↑nodo;
nodo = registro
origen,destino: 1..n;
sigInvAdy,sigAdy: ptNodo
freg
grafoDirigido =
= registro
adyacentes,invAdyacentes: vector[1..n] de ptNodo
freg

Nótese que se emplea la palabra “adyacente” con el


significado de “sucesor”, mientras que “adyacente inverso” se
refiere a “predecesor”.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 24


Caminos mínimos en grafos
– Las listas múltiples pueden utilizarse también para representar grafos no
dirigidos.
– De esta forma, en lugar de
2 3 4 nil
que a cada arista le correspondan 1
1
1 3 4 nil
dos nodos en la estructura 2 3
2
3
1 2 4 nil
dinámica (como ocurre con la 4
4
1 2 3 nil
representación basada en listas
Grafo no dirigido Listas de adyacencia
“ simples” de adyacencia), puede
representarse cada arista con un 1 2

solo nodo y hacer que éste


1
pertenezca a dos listas de 2 1 3 2 3
adyacencia diferentes. 3
4

1 4 2 4 3 4

nil nil nil nil

Listas múltiples de adyacencia

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 25


Caminos mínimos en grafos
– La definición de la estructura de datos es la siguiente:

constante n = ... {cardinal de V}


tipos ptNodo = ↑nodo;
nodo = registro
v1,v2:1..n;
sig1,sig2:ptNodo
freg
grafoNoDirigido = vector[1..n] de ptNodo

– Una ventaja de esta representación es que es útil para


implementar aquellos algoritmos que necesitan recorrer un
grafo y al mismo tiempo “marcar” las aristas por las que se
pasa (bastaría con añadir un campo booleano al tipo nodo).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 26


Caminos mínimos en grafos
• Cálculo del coste del camino mínimo desde un vértice
dado al resto, en un grafo etiquetado con pesos no
negativos

• Utilidad:
el grafo representa una distribución geográfica, donde las
aristas dan el coste (precio, distancia...) de la conexión entre
dos lugares y se desea averiguar el camino más corto
(barato...) para llegar a un punto partiendo de otro

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 27


Caminos mínimos en grafos

E.W. Dijkstra:
“A note on two problems in connexion with
graphs”,
Numerical Mathematica, 1, pp. 269-271, 1959.

• Solución voraz: Algoritmo de Dijkstra


– para grafos dirigidos (la extensión a no dirigidos es inmediata)
– genera uno a uno los caminos de un nodo v al resto por orden creciente de
longitud
– usa un conjunto de vértices donde, a cada paso, se guardan los nodos para los que
ya se sabe el camino mínimo
– devuelve un vector indexado por vértices: en cada posición w se guarda el coste
del camino mínimo que conecta v con w
– cada vez que se incorpora un nodo a la solución se comprueba si los caminos
todavía no definitivos se pueden acortar pasando por él
– se supone que el camino mínimo de un nodo a sí mismo tiene coste nulo
– valor ∞ en la posición w del vector indica que no hay ningún camino desde v a w

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 28


Caminos mínimos en grafos

{Pre: g es un grafo dirigido etiquetado no neg.}


función Dijkstra(g:grafo; v:vért) devuelve vector[vért] de etiq
variables S:cjtVért; D:vector[vért] de etiq
principio
∀w∈vért:D[w]:=etiqueta(g,v,w);
D[v]:=0; S:={v};
mq S no contenga todos los vértices hacer
{D contiene caminos mínimos formados íntegramente por nodos de S
(excepto el último), y los nodos de S corresponden a los caminos
mínimos más cortos calculados hasta el momento}
elegir w∉S t.q. D[w] es mínimo;
S:=S∪{w};
∀u∉ S:actualizar dist.mín. comprobando si por w hay un atajo
fmq;
devuelve D
fin
{Post: D=caminosMínimos(g,v)}

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 29


Caminos mínimos en grafos
• Corrección:
ver material adicional en la web.

• Se presenta a continuación una implementación más


detallada
– Se utiliza en lugar de S su complementario T
– Se supone que n es el número de vértices

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 30


Caminos mínimos en grafos

{Pre: g es un grafo dirigido etiquetado no neg.}


función Dijkstra(g:grafo; v:vért) devuelve vector[vért] de etiq
variables T:cjtVért;
D:vector[vért] de etiq;
u,w:vért; val:etiq
principio
T:=∅;
para todo w en vért hacer
D[w]:=etiqueta(g,v,w); T:=T∪{w}
fpara;
D[v]:=0; T:=T-{v};
repetir n-2 veces {quedan n-1 caminos por determinar}
{selección del w tal que D[w] es mín.: w∈T ∧ ∀u∈ T:D[w]≤D[u]}
val:=∞;
para todo u en T hacer
si D[u]≤val ent w:=u; val:=D[u] fsi
{siempre hay un nodo que cumple la condición}
fpara;
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 31


Caminos mínimos en grafos

...
{se marca w como vértice tratado}
T:=T-{w};
{se recalculan las nuevas dist. mínimas}
para todo u en T hacer
si D[w]+etiqueta(g,w,u)<D[u]
ent D[u]:=D[w]+etiqueta(g,w,u)
fsi
fpara
frepetir;
devuelve D
fin
{Post: D=caminosMínimos(g,v)

Nota: el bucle principal se ejecuta n-2 veces porque el último camino queda
calculado después del último paso (no quedan vértices para hallar atajos)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 32


Caminos mínimos en grafos
• Tiempo de ejecución:
– se supone que las operaciones sobre cjtos. están implementadas en tiempo
constante, excepto la creación (p.ej., mediante un vector de booleanos)
– fase de inicialización:
• creación del cjto. y ejecución n veces de diversas operaciones constantes: Θ(n)
– fase de selección:
• las instrucciones del interior del bucle son Θ(1)
• nº de ejecuciones del bucle:
1ª vuelta: se consultan n-1 vértices,
2ª vuelta: n-2, etc.
(el cardinal de T decrece en 1 en cada paso)
nº de ejecuciones: n(n-1)/2-1 ⇒ Θ(n2)
– fase de “marcaje”:
• n supresiones a lo largo del algoritmo: Θ(n)
– fase de recálculo de las distancias mínimas:
• queda Θ(n2) por igual razón que la selección
Coste total: Θ(n2)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 33


Caminos mínimos en grafos
• Mejoras en el tiempo de ejecución
– Si la representación es por listas de adyacencia, la fase de recálculo se
ejecuta sólo a (a<n2) veces (sustituyendo el bucle sobre los vért. de T por
otro bucle sobre los vért. sucesores de w).
– Si el conjunto T se sustituye con una cola con prioridades, se rebaja
también el coste de la fase de selección (puesto que se selecciona el
mínimo).

Problema: la fase de recálculo puede exigir cambiar la prioridad de un


elemento cualquiera de la cola.

Solución: nuevo tipo de cola con prioridades que permita el acceso directo
a cualquier elemento.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 34


Caminos mínimos en grafos
género cpa {colaPriAristas}
operaciones
creaVacía: → cpa Θ(1)
inserta: cpa vért etiq → cpa Θ(log n)
primero: cpa → (vért,etiq) Θ(1)
borra: cpa → cpa Θ(log n)
sustit: cpa vért etiq → cpa Θ(log n)
valor: cpa vért → etiq Θ(1)
está?: cpa vért → bool Θ(1)
vacía?: cpa → bool Θ(1)

– Implementación: montículo junto con un vector indexado por vértices


<4,20>
1
2 el valor ∞ de la etiqueta
<3,75> <5,60>
3 significa que el vértice
4
5 <2,∞>
no está en la cola

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 35


Caminos mínimos en grafos
{Pre: g es un grafo dirigido etiquetado no neg.}
función Dijkstra(g:grafo; v:vért) devuelve vector[vért] de etiq
variables A:cpa; {cola de aristas con prior.}
D:vector[vért] de etiq; u,w:vért; et,val:etiq
principio
{crear la cola con todas las aristas <v,w>}
creaVacía(A);
para todo w en vért hacer
inserta(A,w,etiqueta(g,v,w))
fpara;
mq not esVacía(A) hacer
<w,val>:=primero(A); {selecc. arista mín.}
D[w]:=val; borra(A); {marca w como tratado}
{se recalculan las nuevas dist. mínimas}
para todo <u,et> en suc(g,w) hacer
si está(A,u) and_then val+et<valor(A,u) entonces
sustituye(A,u,val+et) fsi
fpara
fmq;
D[v]:=0; devuelve D
fin {Post: D=caminosMínimos(g,v)}

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 36


Caminos mínimos en grafos
• Eficiencia temporal:
– inicialización: Θ(nlog n)
– selección y supresión: Θ(nlog n)
– bucle interno: examina todas las aristas del grafo y en el caso
peor efectúa una sustitución por arista, por tanto: Θ(alog n)
• El coste total es: Θ((a+n)log n), luego es mejor que la versión
anterior si el grafo es disperso.
• Si el grafo es denso, el algoritmo original es mejor.

• Puede conseguirse un coste en Θ(n2) para grafos densos y en


Θ(alog n) para no densos, representando el montículo en un
árbol k-ario en lugar de binario [BB97, pp. 243].

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 37


Caminos mínimos en grafos
• Ejercicio: cálculo de la secuencia de nodos que componen el
camino mínimo
– si el camino mínimo entre v y w pasa por u, el camino mínimo entre v y u
es un prefijo del camino mínimo entre v y w
– basta con devolver un vector pred tal que pred[w] contenga el nodo
predecesor de w en el camino mínimo de v a w (que será v si está
directamente unido al nodo de partida o si no hay camino entre v y w)
– el vector debe actualizarse al encontrarse un atajo en el camino
– es necesario también diseñar un nuevo algoritmo para recuperar el camino
a un nodo dado, que tendría como parámetro pred

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 38


Árboles de recubrimiento de coste mínimo
• Objetivo: dado un grafo, obtener un nuevo grafo que sólo contenga las aristas
imprescindibles para una optimización global de las conexiones entre todos
los nodos

“optimización global”: algunos pares de nodos pueden no quedar conectados entre


ellos con el mínimo coste posible en el grafo original

• Aplicación: problemas que tienen que ver con distribuciones geográficas

conjunto de computadores distribuidos geográficamente en diversas ciudades de


diferentes países a los que se quiere conectar para intercambiar datos, compartir
recursos, etc.;

se pide a las compañías telefónicas respectivas los precios de alquiler de líneas


entre ciudades

asegurar que todos los computadores pueden comunicar entre sí, minimizando el
precio total de la red

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 39


Árboles de recubrimiento de coste mínimo
• Terminología:
– árbol libre:
es un grafo no dirigido conexo acíclico
• todo árbol libre con n vértices tiene n – 1 aristas
• si se añade una arista se introduce un ciclo
• si se borra una arista quedan vértices no conectados
• cualquier par de vértices está unido por un único camino simple
• un árbol libre con un vértice distinguido es un árbol con raíz
– árbol de recubrimiento de un grafo no dirigido y etiquetado no
negativamente: es cualquier subgrafo que contenga todos los vértices y
que sea un árbol libre
– árbol de recubrimiento de coste mínimo:
es un árbol de recubrimiento y no hay ningún otro árbol de recubrimiento
cuya suma de aristas sea menor
– notación: arm(g)={árboles de recubrimiento de coste mínimo de g}

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 40


Árboles de recubrimiento de coste mínimo
• Propiedad fundamental de los árboles de recubrimiento
de coste mínimo:
“Sea g un grafo no dirigido conexo y etiquetado no
negativamente, g∈{f:V×V→E},
sea U un conjunto de vértices, U⊂V, U≠∅,
si <u,v> es la arista más pequeña de g tal que u∈U y v∈V–U,
entonces existe algún árbol de recubrimiento de coste mínimo
de g que la contiene.”

Dem: Por reducción al absurdo (por ejemplo, en


[AHU88] A.V. Aho, J.E. Hopcroft y J.D Ullman. Estructuras de datos y
algoritmos. Addison-Wesley Iberoamericana, S.A., 1988.).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 41


Árboles de recubrimiento de coste mínimo
V. Jarník: “O jistém problému minimálním”,
Práca Moravské Prírodovedecké Spolecnosti, 6,
pp. 57-63, 1930.

R.C. Prim:
“Shortest connection networks and some generalizations”,
Bell System Technical Journal, 36, pp. 1389-1401, 1957.

• Algoritmo de Prim (debido a Jarník)


– Aplica reiteradamente la propiedad de los árboles de
recubrimiento de coste mínimo incorporando a cada paso una
arista
– Se usa un conjunto U de vértices tratados y se selecciona en
cada paso la arista mínima que une un vértice de U con otro
de su complementario

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 42


Árboles de recubrimiento de coste mínimo

{Pre: g es un grafo no dirigido conexo etiquetado no negativamente}


función Prim(g:grafo) devuelve grafo
variables U:cjtVért; gsol:grafo;
u,v:vért; x:etiq
principio
creaVacío(gsol); U:={cualquier vértice};
mq U no contenga todos los vért. hacer
seleccionar <u,v,x> mínima t.q. u∈U; v∉U
añade(gsol,u,v,x); U:=U∪{v}
fmq;
devuelve gsol
fin
{Post: gsol∈arm(g)}

Coste: Θ(na)
(es decir, Θ(n3) si el grafo es denso)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 43


Árboles de recubrimiento de coste mínimo
• La versión previa puede refinarse hasta obtener un
algoritmo en Θ(n2), es decir, mejor que el anterior
(a≥n-1).

Se usa un vector arisMín, indexado por vértices, que


contiene:

si v∉U: arisMín[v]=<w,g(v,w)> t.q. <v,w> es la arista más


pequeña que conecta v con un vértice w∈U

si v∈U: arisMín[v]=<v,∞>

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 44


Árboles de recubrimiento de coste mínimo
{Pre: g es un grafo no dirigido conexo etiquetado no negativamente}
función Prim(g:grafo) devuelve grafo
variables
arisMín:vector[vért] de <vért,etiq>;
gsol:grafo; prim,mín,v,w:vért; x:etiq
principio
{inicialización del resultado}
prim:=unVérticeCualquiera;
para todo v en vért hacer
arisMín[v]:=<prim,etiqueta(g,prim,v)>
fpara;
arisMín[prim]:=<prim,∞>;
{a continuación se aplica el método}
creaVacío(gsol);
repetir n-1 veces
mín:=prim; {centinela: arisMín[mín].et=∞}
para todo v en vért hacer
<w,x>:=arisMín[v];
si x<arisMín[mín].et ent mín:=v {como mínimo habrá uno} fsi
fpara;
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 45


Árboles de recubrimiento de coste mínimo

...
{a continuación se añade a la solución}
añade(gsol,mín,arisMín[mín].v,arisMín[mín].et);
{se añade mín al conjunto de vértices tratados}
arisMín[mín]:=<mín,∞>;
{se reorganiza el vector comprobando si la arista mínima de los
vértices todavía no tratados los conecta a mín}
para todo <v,x> en adyacentes(g,mín) hacer
si (arisMín[v].v≠v)and(x<arisMín[v].et)
entonces arisMín[v]:=<mín,x>
fsi
fpara
frepetir;
devuelve gsol
fin
{Post: gsol∈arm(g)}

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 46


Árboles de recubrimiento de coste mínimo
• Eficiencia temporal:
– inicialización: lineal en caso de matriz de adyacencia y
cuadrática en caso de listas
– bucle principal:
• el bucle de selección: Θ(n)
• el añadido de una arista al grafo: constante usando matriz, lineal
usando listas
• el bucle de reorganización:
– con matriz de adyacencia: el cálculo de los adyacentes es Θ(n) y
el coste total queda Θ(n2)
– con listas: el coste total es Θ(a+n)
Coste total: Θ(n2), independientemente de la
representación.
Coste espacial: Θ(n) de espacio adicional.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 47


Árboles de recubrimiento de coste mínimo

J.B. Kruskal: “On the shortest spanning subtree of a graph


and the traveling salesman problem”, Proceedings of the
American Mathematical Society, 7, pp. 48-50, 1956.

• Algoritmo de Kruskal:
– Se basa también en la propiedad de los árboles de
recubrimiento de coste mínimo:

Partiendo del árbol vacío, se selecciona en cada paso la arista


de menor etiqueta que no provoque ciclo sin requerir ninguna
otra condición sobre sus extremos.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 48


Árboles de recubrimiento de coste mínimo

{Pre: g es un grafo no dirigido conexo etiquetado no negativamente}


función Kruskal(g:grafo) devuelve grafo
variables gsol:grafo; u,v:vért; x:etiq
principio
creaVacío(gsol);
mq gsol no contenga todos los vértices hacer
seleccionar <u,v,x> mínima(∗) no examinada;
si no provoca ciclo
entonces añade(gsol,u,v,x)
fsi
fmq;
devuelve gsol
fin
{Post: gsol∈arm(g)}

(∗) Utilizar una cola con prioridades.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 49


Árboles de recubrimiento de coste mínimo
• Implementación eficiente:
– En cada momento, los vértices que están dentro de una componente
conexa en la solución forman una clase de equivalencia, y el algoritmo se
puede considerar como la fusión continuada de clases hasta obtener una
única componente con todos los vértices del grafo.

30 3
A B A B
40 40 4

50 C 60 C
10 20 1 2
D 50
E D E

Evolución de las clases de equivalencia:

{[A],[B],[C],[D],[E]} → {[A],[B],[C,D],[E]} → {[A],[B],[C,D,E]} →

→ {[A,B],[C,D,E]} → {[A,B,C,D,E]}

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 50


Árboles de recubrimiento de coste mínimo

• Se utiliza el TAD “relación de equivalencia” sobre los vértices


género rev {relac. de equiv. sobre vért.}
operaciones
creaREV: → rev {cada vért. una clase}
clase: rev vért → nat
fusiona: rev nat nat → rev
numClases: rev → nat

Implementación asintóticamente óptima:


• basada en una representación del tipo rev usando árboles y una técnica de
compresión de caminos [AHU88, pp. 182-191]
(o ver aquí: http://webdiis.unizar.es/asignaturas/TAP/material/3.5.disjuntos.pdf )
• el coste de creaREV es lineal
• el coste de numClases es constante
• el coste de k ejecuciones combinadas de fusiona y clase es
Θ(kα(k,n)), lo cual es prácticamente constante, porque
α es una función inversa de la función de Ackerman que crece MUY
despacio (α(k,n)≤4, para todos los valores de k y n “imaginables”)
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 51
Árboles de recubrimiento de coste mínimo

{Pre: g es un grafo no dirigido conexo etiquetado no negativamente}


función Kruskal(g:grafo) devuelve grafo
variables T:cpa; gsol:grafo;
u,v:vért; x:etiq;
C:rev; ucomp,vcomp:nat
principio
creaREV(C); {cada vért. forma una clase}
creaVacío(gsol);
creaVacía(T);
{se colocan todas las aristas en la cola}
para todo v en vért hacer
para todo <u,x> en adyacentes(g,v) hacer
inserta(T,v,u,x)
fpara
fpara;
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 52


Árboles de recubrimiento de coste mínimo

...
mq numClases(C)>1 hacer
{obtener y elim. la arista mín.de la cola}
<u,v,x>:=primero(T); borra(T);
{si la arista no provoca ciclo se añade a la
solución y se fusionan las clases corresp.}
ucomp:=clase(C,u); vcomp:=clase(C,v);
si ucomp≠vcomp entonces
fusiona(C,ucomp,vcomp);
añade(gsol,u,v,x)
fsi
fmq;
devuelve gsol
fin
{Post: gsol∈arm(g)}

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 53


Árboles de recubrimiento de coste mínimo
• Coste del algoritmo:
– las a inserciones consecutivas de aristas en la cola con prioridades dan Θ(alog a);
como a≤n2: Θ(alog a)⊆Θ(alog n2)=Θ(2alog n)=Θ(alog n)
– como mucho hay a consultas y supresiones de la arista mínima, el coste de la
consulta es constante y el de la supresión es Θ(log a); por ello, este paso queda en
Θ(alog n)
– averiguar cuántas clases hay en la relación de equivalencia es constante
– en el caso peor, la operación de fusión de clases se ejecuta n-1 veces y la
operación de localizar la clase 2a veces; por tanto, el coste total es en la práctica
Θ(a)
– las n-1 inserciones de aristas quedan en Θ(n) con matriz de adyacencia y Θ(n2)
con listas, aunque en el caso de las listas puede reducirse también a Θ(n) si se
elimina en la operación de añade la comprobación de existencia de la arista (el
algoritmo de Kruskal garantiza que no habrá inserciones repetidas de aristas)

Coste total: Θ(alog n)


(menos que el algoritmo de Prim, aunque con mayor espacio adicional)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 54


Consideraciones sobre la corrección del esquema voraz
• La selección de una candidata óptima en cada paso es una
estrategia heurística que no siempre conduce a la solución
óptima.
• En ocasiones, se utilizan heurísticas voraces para obtener
soluciones subóptimas cuando el cálculo de las óptimas es
demasiado costoso.
• ¿Puede saberse si una estrategia voraz servirá para resolver un
problema concreto de optimización?
La respuesta es: NO siempre.
• Sin embargo, existen ciertos indicios…:
la propiedad de la selección voraz y la existencia de una
subestructura óptima.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 55


Consideraciones sobre la corrección del esquema voraz
• La propiedad de la selección voraz:

– Se verifica esta propiedad cuando una solución globalmente


óptima puede ser alcanzada mediante selecciones localmente
óptimas que son tomadas en cada paso sin depender de las
selecciones futuras;

– en otras palabras, una estrategia voraz progresa de arriba


hacia abajo, tomando una decisión voraz tras otra, reduciendo
iterativamente el problema a otro más pequeño.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 56


Consideraciones sobre la corrección del esquema voraz
• ¿Cómo se comprueba si se verifica la propiedad de la selección
voraz?
– Normalmente, se examina una solución globalmente óptima,
– se trata de demostrar que esa solución puede ser manipulada de forma que
se obtiene tras una primera selección voraz (localmente óptima),
– y esa selección reduce el problema a otro similar pero más pequeño;
– se aplica inducción para demostrar que se puede usar una selección voraz
en cada paso
hay que demostrar que una solución óptima
posee una “subestructura óptima”

• Subestructura óptima:
– Un problema posee una subestructura óptima si una solución óptima de
ese problema incluye soluciones óptimas de subproblemas.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 57


Códigos de Huffman
D.A. Huffman: “A method for the construction of
minimum-redundancy codes”,
Proceedings of the IRE, 40(9), pp. 1098-1101, 1952.
• Los códigos de Huffman son una técnica muy útil para comprimir ficheros.
• El algoritmo voraz de Huffman utiliza una tabla de frecuencias de aparición de cada
carácter para construir una forma óptima de representar los caracteres con códigos
binarios.
• Ejemplo:
– Se tiene un fichero con 100.000 caracteres que se desea comprimir. Las frecuencias de
aparición de caracteres en el fichero son las siguientes:

a b c d e f
aparic. (en miles) 45 13 12 16 9 5

– Puede usarse un código de longitud fija (de 3 bits). El fichero requeriría 300.000 bits.

a b c d e f
cód.long.fija 000 001 010 011 100 101

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 58


Códigos de Huffman
– Puede hacerse mejor con un código de longitud variable, dando codificaciones
cortas a los caracteres más frecuentes y más largas a los
menos frecuentes.

a b c d e f
cód.long.var. 0 101 100 111 1101 1100

Este código ahorra algo más del 25% (requiere 224.000 bits en lugar de 300.000).
• Se precisa un código libre de prefijos:
– Ninguna codificación puede ser prefijo de otra.
– De esta forma, la decodificación es inmediata pues no hay ambigüedades.
– Por ejemplo: ‘001011101’ sólo puede ser ‘aabe’.
• El código se representa mediante un trie (árbol lexicográfico):
– árbol binario cuyas hojas son los caracteres codificados;
– el código de cada carácter es el camino desde la raíz hasta la hoja, donde ir al hijo
izquierdo significa ‘0’ e ir hacia el derecho significa ‘1’.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 59


Códigos de Huffman
• Ejemplo: árboles de los dos códigos anteriores.
100 100
0 1 0 1

86 14 a:45 55
0 1 0 0 1
58 28 14 25 30
0 1 0 1 0 1 0 1 0 1
a:45 b:13 c:12 d:16 e:9 f:5 c:12 b:13 14 d:16
0 1
f:5 e:9
– Cada hoja está etiquetada con un carácter y su frecuencia.
– Cada nodo interno está etiquetado con la suma de los pesos de las hojas de
su subárbol.
– Un código óptimo siempre está representado por un árbol lleno: cada
nodo interno tiene dos hijos.
• Si el alfabeto que se quiere codificar es C, entonces el árbol del código
óptimo tiene |C| hojas y |C| – 1 nodos internos.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 60
Códigos de Huffman
• El algoritmo voraz de Huffman construye el árbol A de
un código óptimo de abajo hacia arriba.
• Utiliza una cola Q de árboles con prioridades (las
frecuencias hacen de prioridades).
• Empieza con un conjunto de |C| hojas en Q y realiza
una secuencia de |C| – 1 “mezclas” hasta crear el árbol
final.
• En cada paso, se “mezclan” los dos objetos (árboles) de
Q que tienen menos frecuencia y el resultado es un
nuevo objeto (árbol) cuya frecuencia es la suma de las
frecuencias de los dos objetos mezclados.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 61


Códigos de Huffman
{Pre: C es un conjunto de caracteres y f es el
vector de frecuencias de esos caracteres}
función Huffman(C:conjunto;f:vectFrec) devuelve árbol
variables Q:colaPri; i,fx,fy,fz:entero; z,x,y:árbol
principio
creaVacía(Q);
para todo x en C hacer
inserta(Q,<x,f[x]>)
fpara;
para i:=1 hasta |C|-1 hacer
<x,fx>:=primero(Q); borra(Q);
<y,fy>:=primero(Q); borra(Q);
fz:=fx+fy;
z:=creaÁrbol(raíz=>fz, hijoIzq=>x, hijoDer=>y);
inserta(Q,<z,fz>)
fpara;
<z,fz>:=primero(Q); borra(Q)
devuelve z
fin
{Post: z es el árbol de un código libre de prefijos óptimo para
(C,f)}

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 62


Códigos de Huffman
• Para el ejemplo anterior:

f:5 e:9 c:12 b:13 d:16 a:45 c:12 b:13 14 d:16 a:45 (3º) 14 d:16 25 a:45
0 1 0 1 0 1
(1º) (2º) f:5 e:9 f:5 e:9 c:12 b:13

25 30 a:45 a:45 55 100


0 1 0 1 0 1 0 1
c:12 b:13 d:16 (5º)
14 25 30 a:45 55
0 1 0 1 0 1 0 1
(4º) f:5 e:9 (6º)
c:12 b:13 14 d:16 25 30
0 1 0 1 0 1
f:5 e:9 c:12 b:13 14 d:16
0 1
f:5 e:9
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 63
Códigos de Huffman
• Coste temporal:
– inicialización de Q: Θ(|C|) (ejercicio)
– el interior del bucle: Θ(log |C|)
Coste total: Θ(|C|log |C|)
• Corrección: ver que se verifican las propiedades de la selección voraz y
de la subestructura óptima.
• Propiedad de la selección voraz:
– Sea C un alfabeto en el que cada carácter c tiene frecuencia f[c]. Sean x e y
dos caracteres de C con frecuencias mínimas. Entonces existe un código
libre de prefijos óptimo para C en el que las codificaciones de x e y tienen
igual longitud y se diferencian sólo en el último bit.
La idea de la demostración consiste en tomar un árbol que represente un
código libre de prefijos óptimo arbitrario y modificarlo hasta convertirlo en
otro árbol que represente otro código libre de prefijos óptimo y tal que los
caracteres x e y aparezcan como hojas hermanas de máxima profundidad.
Detalles en [CLRS09, pp. 433-434].

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 64


Códigos de Huffman
– Por tanto, el proceso de construir un árbol óptimo mediante mezclas
puede empezar, sin pérdida de generalidad, con la elección voraz de
mezclar los dos caracteres de menor frecuencia.
• Propiedad de la subestructura óptima:
– Sea T un árbol binario lleno que representa un código libre de prefijos
óptimo sobre un alfabeto C, con frecuencia f[c] para cada carácter c∈C.
Sean x e y dos caracteres que aparecen como hojas hermanas en T, y sea z
su padre. Entonces, considerando z como un carácter con frecuencia
f[z]=f[x]+f[y], el árbol T’=T–{x,y} representa un código libre de prefijos
óptimo para el alfabeto C’=C–{x,y}∪{z}.
La demostración, en [CLRS09, p. 435].
• La corrección del algoritmo se sigue de los dos resultados
anteriores, aplicando inducción.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 65


El problema de la selección de actividades
• Es un problema de planificación de tareas (en inglés,
scheduling).
• Se tiene un conjunto S={1,2,…,n} de actividades (por ej., clases)
que deben usar un recurso (por ej., un aula) que sólo puede ser
usado por una actividad en cada instante.
• Cada actividad i tiene asociado un instante de comienzo ci y un
instante de finalización fi, tales que ci≤fi, de forma que la
actividad i, si se realiza, debe hacerse durante [ci,fi).
• Dos actividades i, j se dicen compatibles si los intervalos [ci,fi) y
[cj,fj) no se superponen (i.e., (ci≥fj)∨(cj≥fi)).
• El problema de selección de actividades consiste en seleccionar
un conjunto de actividades mutuamente compatibles que tenga
cardinal máximo.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 66
El problema de la selección de actividades
• Ejemplos de estrategias voraces (funciones de selección
voraz) para resolver el problema:
– Seleccionar primero la tarea que empieza primero.
– Seleccionar primero la tarea que termina primero.
– Seleccionar primero la tarea más corta.
– Seleccionar primero la tarea menos conflictiva.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 67


El problema de la selección de actividades

constante n=... {número de actividades}


tipo vectReal=vector[1..n] de real

{Pre: ∀i∈1..n:c[i]≤f[i] ∧ ∀i∈1..n-1:f[i]≤f[i+1]}


función selec(c,f:vectReal)devuelve conjunto
variables i,j:entero; A:conjunto
principio
A:={1};
j:=1; {j es la última actividad seleccionada}
para i:=2 hasta n hacer
si c[i]≥f[j]
entonces A:=A∪{i}; j:=i
fsi
fpara;
devuelve A
fin
{Post: A es soluc. óptima del problema de la selección de
actividades.}

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 68


El problema de la selección de actividades
• Coste temporal: Θ(n)
Θ(nlog n) si se tiene en cuenta que hay que ordenar primero los vectores.
• Demostración de la corrección:
La actividad 1 tiene el primer instante de finalización. Veamos que existe
una solución óptima que comienza con una selección voraz, es decir, con
la actividad 1.
Supongamos que A⊆S es una solución óptima y que las actividades de A
están ordenadas por tiempos de finalización. Supongamos que la primera
actividad de A es la actividad k.
Si k=1, entonces A empieza con una selección voraz.
Si k≠1, veamos que existe otra solución óptima B que comienza con 1.
Sea B=A–{k}∪{1}. Como f1≤fk, las actividades en B son disjuntas y como
tiene el mismo número de actividades que A entonces B es también óptima.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 69


El problema de la selección de actividades
Después de la selección voraz de la actividad 1, el problema se reduce a
encontrar una solución óptima del problema de selección actividades
sobre las actividades de S que son compatibles con la actividad 1.
Entonces, si A es una solución óptima para el problema original S, se tiene
que A’=A–{1} es una solución óptima para el problema S’={i∈S | ci≥f1}.
En efecto, si existiera una solución B’ para S’ con más actividades que A’,
añadiendo la actividad 1 a B’ tendríamos una solución B para S con más
actividades que A, en contra de la optimalidad de A.
Por tanto, después de cada selección voraz, nos encontramos con otro
problema de optimización con igual forma que el problema original.
Por inducción sobre el número de selecciones, y realizando una selección
voraz en cada paso, se obtiene una solución óptima. 

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 70


El problema de la minimización del tiempo de espera
• Es otro problema de planificación de tareas.
• Un servidor (por ej., un procesador, un cajero
automático, un surtidor de gasolina, etc.) tiene que
atender n clientes que llegan todos juntos al sistema.
• El tiempo de servicio para cada cliente es ti, i=1,2,…,n.
• Se quiere minimizar:
n
T = Σ tiempo total que el cliente i está en el sistema
i=1

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 71


El problema de la minimización del tiempo de espera
• Ejemplo:

3 clientes con t1=5, t2=10, t3=3.

orden T
1 2 3: 5+ (5+10) + (5+10+3) = 38
1 3 2: 5+ (5+3) + (5+3+10) = 31
2 1 3: 10 + (10+5) + (10+5+3) = 43
2 3 1: 10 + (10+3) + (10+3+5) = 41
3 1 2: 3+ (3+5) + (3+5+10) = 29 óptimo
3 2 1: 3+ (3+10) + (3+10+5) = 34

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 72


El problema de la minimización del tiempo de espera
• Estrategia voraz: Atender en cada paso al cliente no atendido con
menor tiempo de servicio.
• Demostración de la corrección:
Sea I=(i1,i2,…,in) una permutación cualquiera de los naturales {1,2,…,n}.
Si se atiende a los clientes según la secuencia I, el tiempo total que los
clientes están en el sistema es:
T(I) = ti1 + (ti1+ti2) + ((ti1+ti2)+ti3) + ···
= nti1 + (n-1)ti2 + (n-2)ti3 + ···
n
= Σ
k=1
(n-k+1)t ik

Supongamos que I es tal que es posible encontrar dos naturales a y b con


a<b y tia>tib, es decir, que el cliente a-ésimo es atendido antes que el
b-ésimo aunque su tiempo de servicio es mayor.
Si se invierten sus posiciones en I se obtiene una nueva secuencia I’.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 73
El problema de la minimización del tiempo de espera
Entonces: n
T(I’) = (n-a+1)tib + (n-b+1)tia + Σ
k=1
(n-k+1)t ik

k≠a,b

T(I) - T(I’) = (n-a+1)(tia-tib) + (n-b+1)(tib-tia)


= (b-a)(tia-tib)
>0
Es decir, se puede mejorar cualquier secuencia en la que un cliente que
necesita más tiempo sea atendido antes que otro que necesita menos.
Las únicas secuencias que no pueden mejorarse, y por tanto son óptimas,
son aquéllas en las que los clientes están ordenados por tiempos de
servicio decrecientes (todas ellas dan igual tiempo total). 
• Puede generalizarse a s procesadores.
– Se numeran los clientes de forma que t1≤t2≤⋅⋅⋅≤tn.
– El procesador i, 1≤i≤s, atenderá a los clientes i, i+s, i+2s, …

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 74


Fundamentos teóricos del esquema voraz
• Existe una teoría matemática que sirve de base a los algoritmos
voraces:
Teoría de matroides

• Un matroide es un par M=(S,I) tal que:


– S es un conjunto finito no vacío.
– I es una familia no vacía de subconjuntos de S, llamados subconjuntos
independientes, tal que si B∈I y A⊆B, entonces A∈I.
Por cumplir esta propiedad, I se dice hereditaria
(nótese que el conjunto vacío es necesariamente un miembro de I).
– Si A∈I, B∈I y |A|<|B|, entonces existe algún x∈B–A tal que A∪{x}∈I.
Se dice que M satisface la propiedad de intercambio.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 75


Fundamentos teóricos del esquema voraz
• Ejemplos de matroides:
– Dada una matriz de números reales, sea S el conjunto de sus vectores fila,
y considerese que un subconjunto de S es independiente si los vectores
que lo componen son linealmente independientes (en el sentido habitual).

Se llama “matroide matricial” y es el primero que se estudió (H. Whitney,


1935).

– Sea un grafo no dirigido G=(V,A).


Sea MG=(SG,IG), donde:
• SG=A (el conjunto de aristas).
• Si B⊆A, entonces B∈IG si y sólo si B es acíclico.
Se llama “matroide gráfico” y está muy relacionado con el cálculo de
árboles de recubrimiento de coste mínimo.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 76


Fundamentos teóricos del esquema voraz
• Sea M=(S,I) y B∈I.
Un elemento x∉B se dice extensión de B si B∪{x}∈I.
– Ejemplo: en un matroide gráfico MG, si B es un conjunto independiente de
aristas, entonces la arista a es una extensión de B si y sólo si a no está en
B y la incorporación de a a B no crea un ciclo.
• Si A es un subconjunto independiente de un matroide M, se dice
que A es maximal si no tiene extensiones.
• Teorema. Todos los subconjuntos independientes maximales de
un matroide tienen el mismo cardinal.
(Dem.: muy fácil [CLRS09, p. 439].)
– Ejemplo: Dado un grafo no dirigido y conexo G, todo subconjunto
independiente maximal de MG es un árbol libre con |V|–1 aristas que
conecta todos los vértices de G.
Ese árbol se llama árbol de recubrimiento de G.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 77


Fundamentos teóricos del esquema voraz
• Un matroide M=(S,I) al que se le asocia una función que asigna
un “peso” estrictamente positivo w(x) a cada x∈S se llama
matroide ponderado.

La función de peso w se extiende a los subconjuntos de S


mediante la suma:

w(A) = ∑ w(x), para todo A⊆S.


x∈A

– Ejemplo: si w(a) denota la longitud de la arista a en un matroide gráfico


MG, entonces w(B) es la longitud total de todas las aristas del subconjunto
de aristas B.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 78


Fundamentos teóricos del esquema voraz
• Voracidad y matroides.

Muchos de los problemas para


los que un algoritmo voraz
calcula la solución óptima
pueden formularse en términos
de “encontrar un subconjunto
independiente de máximo peso
en un matroide ponderado.”

– Es decir, dado un matroide ponderado M=(S,I), se quiere encontrar un


subconjunto A independiente (i.e., A∈I) tal que w(A) sea máximo.
– Un subconjunto independiente y de máximo peso en un matroide
ponderado se llama subconjunto óptimo del matroide.
– Como la función de peso w es positiva, un subconjunto óptimo siempre es
maximal (i.e., no tiene extensiones, ya que aumentar un conjunto siempre
incrementa su peso).
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 79
Fundamentos teóricos del esquema voraz
• Ejemplo: el problema del árbol de recubrimiento de coste mínimo (*).
– Sea un grafo no dirigido y conexo G=(V,A) y una función de longitud w tal que
w(a) es la longitud positiva de la arista a (llamamos longitudes a las etiquetas del
grafo en lugar de pesos por reservar esta palabra para la función definida sobre un
matroide).
– El problema(*) consiste en encontrar un subconjunto de aristas que conecte todos
los vértices del grafo y tenga longitud mínima.
– Considerar MG y la función de peso w’ definida como: w’(a) = w0 – w(a), donde
w0 es un valor mayor que la longitud de todas las aristas.
– En este matroide ponderado, todos los pesos son positivos y un subconjunto
óptimo es precisamente un árbol de recubrimiento del grafo original con longitud
total mínima.
– Más específicamente, cada subconjunto independiente maximal B corresponde a
un árbol de recubrimiento, y puesto que
w’(B) = (|V| – 1)w0 – w(B)
para todo subconjunto independiente maximal B, el subconjunto independiente
que maximiza w’(B) debe minimizar w(B).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 80


Fundamentos teóricos del esquema voraz
• Algoritmo voraz de cálculo de un subconjunto óptimo
en un matroide arbitrario:
{Pre: S y la función indep definen un matroide;
w es una función de peso positiva sobre S}
función voraz(S:conjunto) devuelve conjunto
variable A:conjunto
principio
A:=Ø;
ordenar S por valores decrecientes del peso w;
para todo x en S tomado en orden decreciente de w(x) hacer
si indep(A∪{x}) entonces
A:=A∪{x}
fsi
fpara;
devuelve A
fin
{Post: A es subconjunto óptimo de (S,indep,w)}

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 81


Fundamentos teóricos del esquema voraz
• Eficiencia temporal:
Denotando |S| como n,
• fase de ordenación: Θ(nlog n)
• bucle: Θ(n f(n)), suponiendo que el coste de evaluar la función
indep es Θ(f(n))

Total: Θ(nlog n + n f(n))

• Corrección:
Teorema 16.11 en [CLRS09, pp. 441-442]
(un par de páginas; sin gran dificultad).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 82


Fundamentos teóricos del esquema voraz
• Utilidad fundamental:

Dados un problema y una solución voraz,

para demostrar la corrección de esa solución basta con

identificar una estructura


de matroide subyacente al
problema

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 83


Fundamentos teóricos del esquema voraz
• Resumen:
– La teoría de matroides no cubre todos los problemas en los
que el esquema voraz calcula la solución óptima.
– Sin embargo cubre muchos casos interesantes (por ej., árboles
de recubrimiento de coste mínimo).
– Más aún, se ha demostrado que una estructura es un matroide
si y sólo si el esquema voraz calcula para ella una solución
óptima sea cual sea la función de peso escogida
(la demostración puede verse en pp. 13-18 de
[Koz92] D.C. Kozen. The Design and Analysis of Algorithms. Springer-
Verlag, 1992.)
– La investigación continúa…

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 84


Un problema de planificación de tareas a plazo fijo
• Se tiene un conjunto S={1,2,…,n} de tareas de duración
unidad.
• En cada instante, sólo se puede realizar una tarea.
• La tarea i, 1≤i≤n, debe terminarse antes del instante (o
plazo) di, con 1≤di≤n.
• Hay una penalización wi, 1≤i≤n, si la tarea i no termina
antes de su plazo.
• Se trata de encontrar una secuencia de realización de las
tareas que minimice la penalización total.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 85


Un problema de planificación de tareas a plazo fijo
• Una tarea en una secuencia se dice puntual si termina antes de
su plazo, y tardía si lo hace después de su plazo.
• Una secuencia está en forma “puntuales primero” si todas las
tareas puntuales están antes de las tardías.
• Cualquier secuencia puede transformarse en forma puntuales
primero (manteniendo la penalización).
En efecto, si una tarea puntual x va detrás de una tarea tardía y, pueden
intercambiarse sus posiciones de forma que x sigue siendo puntual e y
tardía.
• Una secuencia está en forma canónica si está en forma
puntuales primero y las tareas puntuales están ordenadas por
valores crecientes de sus plazos.
• Cualquier secuencia puede transformarse en forma canónica
(manteniendo la penalización).
Argumentación similar a la anterior.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 86
Un problema de planificación de tareas a plazo fijo
• Encontrar una secuencia óptima es encontrar un subconjunto A
de tareas que sean puntuales en la secuencia óptima.
• Una vez encontrado A, la secuencia se crea ordenando los
elementos de A por plazos crecientes y a continuación las tareas
tardías (en S – A) en cualquier orden.
• Decimos que un subconjunto A de tareas es independiente si
existe una ordenación de las mismas en la que ninguna es tardía.
Por ejemplo, el conjunto de tareas puntuales de una secuencia es un
conjunto independiente.
• Denotamos con I el conjunto de todos los subconjuntos
independientes de tareas.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 87


Un problema de planificación de tareas a plazo fijo
• Sea Nt(A), t=1,…,n, el nº de tareas de A cuyo plazo es menor o igual que t.
• Lema. Sea A un conjunto de tareas. Son equivalentes:
1. A es independiente.
2. Nt(A)≤t, para t=1,…,n.
3. Si las tareas de A se ordenan por plazos crecientes, entonces ninguna tarea es
tardía.
Dem.: (1)⇒(2) Si Nt(A)>t para algún t, entonces no hay forma de construir una
secuencia con las tareas de A de forma que ninguna sea tardía.
(2)⇒(3) El i-ésimo plazo mayor es como mucho i. Por tanto, ordenando las tareas
por plazos crecientes, no hay forma de que alguna tarea sea tardía.
(3)⇒(1) Trivial. 
• Corolario. La propiedad (2) del lema anterior sirve para decidir en tiempo
O(|A|) si un conjunto de tareas es independiente.
Dem.: Ejercicio
(suponer las tareas sin ordenar previamente; puede usarse espacio adicional O(|A|)).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 88


Un problema de planificación de tareas a plazo fijo
• El problema de minimizar la suma de penalizaciones de las
tareas tardías de una secuencia es el mismo que el de maximizar
la suma de penalizaciones de sus tareas puntuales.
• Teorema. Si S es un conjunto de tareas de duración unidad con
penalizaciones e I es el conjunto de todos los conjuntos
independientes de tareas, entonces (S,I) es un matroide.
Dem.: Es claro que todo subconjunto de un conjunto independiente de tareas
es también independiente.
Para demostrar la propiedad del intercambio, supongamos que B y A son
conjuntos independientes de tareas con |B|>|A|.
Sea k el mayor t tal que Nt(B)≤Nt(A).
Como Nn(B)=|B| y Nn(A)=|A|, se sigue que k<n y que Nj(B)>Nj(A) para
todo j tal que k+1≤j≤n.
Por tanto, B tiene más tareas con plazo k+1 que A.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 89


Un problema de planificación de tareas a plazo fijo
Sea x una tarea de B\A con plazo k+1.
Sea A’=A∪{x}.
Demostramos ahora que A’ es independiente usando la propiedad (2) del
Lema anterior.
Como A es independiente, Nt(A’)=Nt(A)≤t, para 1≤t≤k.
Como B es independiente, Nt(A’)≤Nt(B)≤t, para k<t≤n.
Por tanto, A’ es independiente. 
• Corolario. Se puede utilizar un algoritmo voraz para encontrar
un conjunto independiente de tareas A con penalización máxima.
• A continuación, se puede crear una secuencia óptima que tiene
como tareas puntuales las de A.
• Tiempo de ejecución: O(n2)
¿Por qué?

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 90


Heurísticas voraces: Coloreado de grafos
• A veces se utilizan algoritmos voraces a pesar de que no calculan
soluciones óptimas:
– bien porque el cálculo de una solución óptima es demasiado costoso,
– bien porque el algoritmo voraz calcula un solución “subóptima” que
resulta suficiente.
• Problema del coloreado de un grafo.
– Sea G=(V,A) un grafo no dirigido cuyos vértices se desea colorear.
– Se exige que todo par de vértices unidos por una arista tengan asignados
colores diferentes.
– Se pretende emplear el menor número posible de colores.
3

1 2 5

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 91


Heurísticas voraces: Coloreado de grafos
– Algoritmo voraz de coloreado de un grafo:
• escoger inicialmente un color y un vértice arbitrario como punto de
partida;
• tratar de asignarle ese color al mayor número posible de vértices,
respetando la restricción impuesta (vértices adyacentes deben tener
distinto color);
• escoger otro vértice aún no coloreado y un color distinto y repetir el
proceso hasta haber coloreado todos los vértices.

– Aplicado al ejemplo anterior, se obtiene la solución óptima:


dos colores.
3

1 2 5

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 92


Heurísticas voraces: Coloreado de grafos
– Sin embargo, tomando el mismo grafo pero ordenando los
vértices de otra forma, 1,5,2,3,4, el algoritmo voraz colorearía
1 y 5 de un color, 2 en otro, y necesitaría un tercer color para
3 y 4.
3

1 2 5

– Por tanto es un algoritmo heurístico que tiene la


posibilidad, pero no la certeza, de encontrar la solución
óptima.
– Todos los algoritmos exactos conocidos para el problema del
coloreado de un grafo emplean un tiempo exponencial, de ahí
la utilidad de la heurística voraz.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 93
Heurísticas voraces: El problema del viajante de comercio
• El problema del viajante de comercio
consiste en encontrar un recorrido de
longitud mínima para un viajante que
tiene que visitar varias ciudades y
volver al punto de partida, conocida
la distancia existente entre cada dos
ciudades.

• En términos matemáticos es el
problema del cálculo del hamiltoniano
de longitud mínima.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 94


Heurísticas voraces: El problema del viajante de comercio
• Ejemplo:
Cinco cabinas de teléfonos, b, c, d, e, f, para las que se conocen sus
coordenadas relativas a la central telefónica, a, desde la que parten los
recolectores y a donde deben regresar al terminar, y se supone que la
distancia entre cada dos viene dada por la línea recta.

c (1,7) d (15,7)
e (15,4)
b (4,3)
a (0,0) f (18,0)

a
b 5
c 7,07 5
d 16,55 11,70 14
e 15,52 11,05 14,32 3
f 18 14,32 18,38 7,6 5
distan. a b c d e f
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 95
Heurísticas voraces: El problema del viajante de comercio

• El algoritmo de fuerza bruta para resolver el problema


consiste en intentar todas las posibilidades, es decir,
calcular las longitudes de todos los recorridos posibles, y
seleccionar la de longitud mínima (veremos una solución
algo mejor mediante programación dinámica).
• Obviamente, el coste de tal algoritmo crece
exponencialmente con el número de puntos a visitar.
• En el ejemplo anterior, la solución viene dada por el
siguiente recorrido (en realidad dos recorridos, pues ambos
sentidos de marcha son posibles) de longitud 48,39:
c d
b e
a f

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 96


Heurísticas voraces: El problema del viajante de comercio
• Heurística voraz:
Ir seleccionando parejas de puntos que serán visitados de forma consecutiva:
– se seleccionará primero aquella pareja de puntos entre los que la distancia
sea mínima;
– a continuación, se selecciona la siguiente pareja separada con una
distancia mínima siempre que esta nueva elección no haga que:
• se visite un punto dos veces o más (es decir, que el punto aparezca tres o más
veces en las parejas de puntos seleccionadas), o
• se cierre un recorrido antes de haber visitado todos los puntos.

De esta forma, si hay que visitar n puntos (incluido el origen), se


selecciona un conjunto de n parejas de puntos (que serán visitados de
forma consecutiva) y la solución consiste en reordenar todas esas parejas
de forma que constituyan un recorrido.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 97


Heurísticas voraces: El problema del viajante de comercio
• En el ejemplo anterior:
– Las parejas ordenadas por distancia entre sus puntos son: (d,e), (a,b),
(b,c), (e,f), (a,c), (d,f), (b,e), (b,d), (c,d), (b,f), (c,e), (a,e), (a,d), (a,f) y
(c,f).
– Se selecciona primero la pareja (d,e) pues la distancia entre ambos puntos
es mínima (3 unidades).
(d,e)
– Después se seleccionan las parejas (a,b), (b,c) y (e,f). La distancia es para
todas ellas igual (5 unidades).
(d,e), (a,b), (b,c), (e,f)
– La siguiente pareja de distancia mínima es (a,c), con longitud 7,07.
Sin embargo, esta pareja cierra un recorrido junto con otras dos ya
seleccionadas, (b,c) y (a,b), por lo que se descarta.
– La siguiente pareja es (d,f) y se descarta también por motivos similares.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 98


Heurísticas voraces: El problema del viajante de comercio
(d,e), (a,b), (b,c), (e,f)
– La siguiente es la pareja (b,e), pero debe rechazarse también porque su
inclusión haría visitar más de una vez los puntos b y e.
– La pareja (b,d) se rechaza por motivos similares (el punto b habría que
visitarlo dos veces).
– La siguiente pareja es (c,d), y se selecciona.
(d,e), (a,b), (b,c), (e,f), (c,d)
– Las parejas (b,f), (c,e), (a,e) y (a,d) no son aceptables.
– Finalmente, la pareja (a,f) cierra el recorrido:
c d
b e
f
a
– Este recorrido no es el óptimo pues su longitud es de 50 unidades.
No obstante, es el 4º mejor recorrido de entre los sesenta (esencialmente
distintos) posibles y es más costoso que el óptimo en sólo un 3,3%.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 99
Divide y vencerás

Algoritmia básica - Javier Campos (Universidad de Zaragoza)


Divide y vencerás
• Introducción 3
• La búsqueda dicotómica 9
• La ordenación por fusión 14
• El algoritmo de ordenación de Hoare 16
• Algoritmos de selección y de búsqueda de la mediana 19
• Multiplicación de enteros grandes 23
• Potenciación de enteros 30
• Introducción a la criptografía 37
• Multiplicación de matrices 48
• Calendario de un campeonato 53

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 2


El esquema divide y vencerás: Introducción
• Técnica de diseño de algoritmos “divide y vencerás”:

– descomponer el ejemplar a resolver en un cierto número de


subejemplares más pequeños del mismo problema;
– resolver independientemente cada subejemplar;
– combinar los resultados obtenidos para construir la solución
del ejemplar original.

aplicar esta técnica recursivamente

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 3


El esquema divide y vencerás: Introducción
• Esquema genérico:
función divide_y_vencerás(x:tx) devuelve ty
variables x1,…,xk:tx; y1,…,yk:ty
principio
si x es suficientemente simple entonces
devuelve solución_simple(x)
sino
descomponer x en x1,…,xk;
para i:=1 hasta k hacer
yi:=divide_y_vencerás(xi)
fpara;
devuelve combinar(y1,…,yk)
fsi
fin

• Si k=1, el esquema anterior se llama técnica de


reducción.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 4


El esquema divide y vencerás: Introducción
• Sobre el coste computacional:
– Sea un algoritmo A que emplea un tiempo cuadrático.
– Sea c una constante tal que una implementación particular de
A emplea un tiempo

tA(n)≤cn2

para un ejemplar de tamaño n.


– Supongamos que A se puede descomponer en tres
subejemplares de tamaño n/2, resolverlos y combinar su
resultados para resolver A.
– Sea d una constante tal que el tiempo empleado en la
descomposición y combinación es t(n)≤dn.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 5


El esquema divide y vencerás: Introducción
– La utilización de esta partición da lugar a un nuevo algoritmo B con un
tiempo: tB (n) = 3tA (n / 2)+ t(n)
2
 n + 1
≤ 3c  + dn
 2 
3 3  3
= cn2 +  c+ d n + c
4 2  4

– Luego B es un 25% más rápido que A.


– Si se aplica a B la misma técnica de descomposición se obtiene un
algoritmo C con tiempo:
 tA (n) si n ≤ n0
tC (n) = 
 3tC (n / 2)+ t(n) en otro caso

– Donde tA(n) es el tiempo del algoritmo simple, n0 es el umbral por


encima del cual el algoritmo se usa recursivamente y t(n) el tiempo de la
descomposición y combinación.
– La solución de la ecuación en recurrencias da un tiempo para el algoritmo
C de nlog 3 ≈ n1,59.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 6


El esquema divide y vencerás: Introducción
• Recordar…

una de las ecuaciones en recurrencias especialmente útil para el


análisis de algoritmos de divide y vencerás:

– La solución de la ecuación

T(n) = aT(n/b) + Θ(nklogpn)

con a≥1, b>1, p≥0 es

O (nlogb a), si a > bk



T (n) ∈ O (nk logp + 1n), si a = bk
O (nk logp n), si a < bk

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 7


El esquema divide y vencerás: Introducción
• Sobre el cálculo del umbral óptimo:
– Es un problema complejo.
– Para un mismo problema, varía con la implementación
concreta y varía con el valor de n.
– Puede estimarse empíricamente (tablas,…)...
– ... o teóricamente: calculando el n para el que la solución
recursiva y la solución simple tienen igual coste; por ejemplo,
si tA(n)=n2 y t(n)=16n:

t A (n) = 3tA (n / 2) + t(n)

da un valor de n0≈64 (ignorando los redondeos).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 8


La búsqueda dicotómica
• Problema:
– Dado T[1..n] vector ordenado crecientemente y dado x, encontrar x en T, si es que
está.
– Formalmente: encontrar un natural i tal que
0≤i≤n y T[i]≤x<T[i+1], con el convenio de que
T[0]= – ∞ y T[n+1]= ∞ (centinelas).
– Solución secuencial evidente:
función secuencial(T:vector[1..n]de dato; x:dato) devuelve 0..n
variables i:0..n+1; parar:booleano
principio
i:=1; parar:=falso;
mq (i≤n) and not parar hacer
si T[i]>x entonces parar:=verdad sino i:=i+1 fsi
fmq;
devuelve i-1
fin Coste caso promedio y caso peor: Θ(n)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 9


La búsqueda dicotómica
• Búsqueda dicotómica (alg. de reducción, puesto que k=1):
función dicotómica(T:vector[1..n]de dato; x:dato) devuelve 0..n
principio
si (n=0) or (x<T[1]) entonces devuelve 0
sino devuelve dicotRec(T,1,n,x)
fsi
fin

función dicotRec(T:vector[1..n]de dato; i,d:1..n; x:dato) dev. 1..n


{búsqueda dicotómica de x en T[i..d]; Pre: T[i]≤x<T[d+1], i≤d}
variable k:1..n
principio
si i=d entonces devuelve i
sino
k:=(i+d+1) div 2;
si x<T[k] ent devuelve dicotRec(T,i,k-1,x)
sino devuelve dicotRec(T,k,d,x)
fsi
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 10


La búsqueda dicotómica
• Versión iterativa:
función dicotIter(T:vector[1..n]de dato; x:dato) devuelve 0..n
variables i,d,k:1..n
principio
si (n=0) or (x<T[1]) entonces devuelve 0
sino
i:=1; d:=n;
mq i<d hacer {T[i]≤x<T[d+1]}
k:=(i+d+1) div 2;
si x<T[k]
entonces d:=k-1
sino i:=k
fsi
fmq;
devuelve i
Coste: Θ(log n), en todos los casos.
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 11


La búsqueda dicotómica
• Mejora aparente:
función dicotIter2(T:vector[1..n]de dato; x:dato) devuelve 0..n
variable i,d,k:1..n
principio
si (n=0) or (x<T[1]) entonces devuelve 0
sino
i:=1; d:=n;
mq i<d hacer {T[i]≤x<T[d+1]}
k:=(i+d) div 2;
si x<T[k] entonces d:=k-1
sino
si x≥T[k+1] entonces i:=k+1
sino i:=k; d:=k
fsi
fsi
fmq;
devuelve i
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 12


La búsqueda dicotómica
• La mejora es sólo aparente:
– el primer algoritmo realiza siempre Θ(log n) iteraciones mientras que el
segundo puede parar antes;
– cálculo del número medio de iteraciones suponiendo que:
• todos los elementos de T son distintos,
• x está en T,
• cada posición tiene igual probabilidad de contener a x
[BB90] G. Brassard y P. Bratley. Algorítmica. Concepción y análisis. Masson,
S.A., 1990. pp. 116-119. 3
Iter 1 (n) ≅ Iter2 (n) +
2
– Es decir, el 1er algoritmo realiza, en media, 1’5 iteraciones más que el 2º.
– Pero, cada iteración del 2º es ligeramente más costosa que la del 1º.
Son difícilmente comparables.
Si n es suficientemente grande, el 1er algoritmo es mejor que el 2º.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 13


La ordenación por fusión
• Dado un vector T[1..n] de n elementos dotados de una relación de orden total,
se trata de ordenar de forma creciente esos elementos.
• Técnica de divide y vencerás más sencilla: Ojo: usamos notación de
vectores pero el algoritmo es
– dividir el vector en dos mitades; especialmente adecuado para
– ordenar esas dos mitades recursivamente; listas y para ficheros.

– fusionarlas (o mezclarlas) en un solo vector ordenado.


algoritmo ordFusión(e/s T:vect[1..n]de dato)
variables U:vect[1..(n div 2)]de dato;
V:vect[1..((n+1) div 2)]de dato
principio
si n es pequeño entonces ordInserción(T)
sino
U:=T[1..(n div 2)];
V:=T[(n div 2 + 1)..n];
ordFusión(U);
ordFusión(V);
fusión(T,U,V)
fsi
fin {método denominado “mergesort”}
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 14
La ordenación por fusión
• Coste de ejecución:
– la descomposición de T en U y V precisa un tiempo lineal;
– la fusión de U y V también necesita un tiempo lineal;
– por tanto, si t(n) es el tiempo de ejecución del algoritmo para ordenar n
elementos,
( ) (
t (n) ∈t n / 2 + t n / 2 + Θ (n) )
es decir, t(n)∈Θ(nlog n)

• Además:
La fusión de T[1..k] y T[k+1..n] (ya ordenados) en el mismo T[1..n] puede
hacerse en tiempo lineal utilizando sólo una cantidad fija de variables
auxiliares (independiente de n).
(Ejercicio 18 de la sección 5.2.4 de [Knu87] D.E. Knuth. El arte de programar
ordenadores. Volumen III: Clasificación y búsqueda. Editorial Reverté, 1987,
“nivel [40]” => “realmente difícil o largo”… ver artículo en “material adicional”.)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 15


El algoritmo de ordenación de Hoare

C.A.R. Hoare: “Quicksort”,


Computer Journal, 5(1), pp. 10-15, 1962.

algoritmo ordRápida(e/s T:vect[1..n]de dato; ent iz,de:1..n)


{Ordenación de las componentes iz..de de T.}
variable me:1..n
principio
si de-iz es pequeño
entonces ordInserción(T,iz,de)
sino
divide(T,iz,de,me);
{iz≤k<me ⇒ T[k]≤T[me] ∧ me<k≤de ⇒ T[k]>T[me]}
ordRápida(T,iz,me-1);
ordRápida(T,me+1,de)
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 16


El algoritmo de ordenación de Hoare
algoritmo divide(e/s T:vect[1..n]de dato; ent iz,de:1..n; sal me:1..n)
{Permuta los elementos iz..de de T de forma que:
iz≤me≤de,
∀k t.q. iz≤k<me: T[k]≤p,
T[me]=p,
∀k t.q. me<k≤de: T[k]>p,
p se llama pivote y es, por ejemplo, el valor inicial de T[iz]. }
variables p:dato; k:1..n
principio
p:=T[iz];
k:=iz; me:=de+1;
repetir k:=k+1 hasta que (T[k]>p)or(k≥de);
repetir me:=me-1 hasta que (T[me]≤p);
mq k<me hacer
intercambiar(T[k],T[me]);
repetir k:=k+1 hasta que T[k]>p;
repetir me:=me-1 hasta que T[me]≤p
fmq;
intercambiar(T[iz],T[me])
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 17


El algoritmo de ordenación de Hoare
• Coste en el peor caso: cuadrático
(si la elección del pivote no es adecuada, los subejemplares
no tienen tamaño parecido…)

• Coste promedio: O(n log n)


Dem.: [BB97, pp. 264-266]

(la constante multiplicativa es menor que en los otros


algoritmos de ordenación que hemos visto cuyo coste en el
caso peor es O(n log n): mergesort y heapsort)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 18


Algoritmos de selección y de búsqueda de la mediana
• Dado un vector T[1..n] de enteros, la mediana de T es un
elemento m de T que tiene tantos elementos menores como
mayores que él en T:

{i ∈[1..n]| T [i ]< m} < n / 2, y

{i ∈[1..n]| T [i ]> m}≤ n / 2

(nótese que la definición formal es más general: n puede ser par y además
puede haber elementos repetidos, incluida la mediana)

Primera solución:
– Ordenar T y extraer el elemento n/2-ésimo.
– Tiempo Θ(n log n).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 19


Algoritmos de selección y de búsqueda de la mediana
• Problema más general: la selección (o cálculo de los estadísticos de orden).
Dado un vector T de n elementos y 1≤k≤n, el k-ésimo menor elemento de T
es aquel elemento m de T que satisface:

{i ∈[1..n]| }
T[i ]< m < k , y

{i ∈[1..n]| T[i ]≤ m ≥ k }
Es decir, el elemento en posición k si T estuviese ordenado crecientemente.

• Por tanto, la mediana de T es el n/2-ésimo menor elemento de T.

• Solución del problema: inspirada en el algoritmo de ordenación de Hoare


(pero ahora sólo se resuelve uno de los subejemplares).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 20


Algoritmos de selección y de búsqueda de la mediana
función seleccionar(T:vector[1..n]de dato; k:1..n) devuelve dato
principio
devuelve selRec(T,1,n,k)
fin

función selRec(T:vector[1..n]de dato; i,d,k:1..n) devuelve dato


principio
si d-i es pequeño entonces ordInserción(T,i,d); devuelve T[k]
sino
divide(T,i,d,m);
si m-i+1≥k entonces selRec(T,i,m,k)
sino selRec(T,m+1,d,k-(m-i+1))
fsi
fsi
fin

algoritmo divide(e/s T:vect[1..n]de dato; ent i,d:1..n; sal m:1..n)


{Permuta los elementos i..d de T de forma que:
i≤m≤d; ∀k t.q. i≤k<m: T[k]≤p; T[m]=p; ∀k t.q. m<k≤d: T[k]>p;
p es, por ejemplo, el valor inicial de T[i]. }

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 21


Algoritmos de selección y de búsqueda de la mediana
• Como en el método de ordenación de Hoare, una elección
desafortunada del pivote conduce en el caso peor a un tiempo
cuadrático.

• No obstante, el coste promedio es lineal.

• Existe una mejora que permite un coste lineal también en el peor


caso [CLRS09], aunque en la práctica, en muchos casos, se
comporta mejor el algoritmo anterior.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 22


Multiplicación de enteros grandes
• Coste de realizar las operaciones elementales de suma y
multiplicación:
– Es razonable considerarlo constante si los operandos son directamente
manipulables por el hardware, es decir, no son muy grandes.
– Si se necesitan enteros muy grandes, hay que implementar por software
las operaciones.

• Enteros muy grandes:


– Representación de un entero de n cifras: puede hacerse en un vector con
un espacio en O(n) bits.
– Operaciones de suma, resta: pueden hacerse en tiempo lineal.
– Operaciones de multiplicación y división entera por potencias positivas
de 10: pueden hacerse en tiempo lineal (desplazamientos de las cifras).
– Operación de multiplicación con el algoritmo clásico (o con el de
multiplicación rusa): tiempo cuadrático.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 23
Multiplicación de enteros grandes
A. Karatsuba e Y. Ofman:
“Multiplication of multidigit numbers on automata”,
Dokl. Akad. Nauk SSSR, 145, pp. 293-294, 1962.

• Algoritmo de Karatsuba: Técnica de divide y vencerás para la


multiplicación de enteros muy grandes.
– Sean u y v dos enteros de n cifras.
– Se descomponen en mitades de igual tamaño:
u = 10s w + x s s
s  con 0≤ x < 10 , 0≤ z < 10 , y
v = 10 y + z 
s = n 2

– Por tanto, w e y tienen n/2 cifras n


u w x
v y z
n/2 n/2

– El producto es:
uv = 102s wy + 10s (wz+ xy) + xz

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 24


Multiplicación de enteros grandes

función mult(u,v:granEnt) devuelve granEnt


variables n,s:entero; w,x,y,z:granEnt
principio
n:=máx(tamaño(u),tamaño(v));
si n es pequeño
entonces devuelve multClásica(u,v)
sino
s:=n div 2;
w:=u div 10s; x:=u mod 10s;
y:=v div 10s; z:=v mod 10s;
devuelve mult(w,y)*102s + (mult(w,z)+mult(x.y))*10s + mult(x,z)
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 25


Multiplicación de enteros grandes
• Coste temporal:
– Las sumas, multiplicaciones por potencias de 10 y divisiones por
potencias de 10: tiempo lineal.
– Operación módulo una potencia de 10: tiempo lineal (puede hacerse con
una división, una multiplicación y una resta).
– Por tanto, si t(n) es el tiempo del algoritmo:

( ) ( )
t (n) = 3t n 2 + t n 2 + Θ (n)

Si n se supone potencia de 2,

( )
t (n) = 4t n 2 + Θ(n)

La solución de esta recurrencia es:

t (n) ∈O (n 2)

¿¡Y no hemos ganado nada!?


Algoritmia básica - Javier Campos (Universidad de Zaragoza) 26
Multiplicación de enteros grandes
– Truco: calcular wy, wz+xy, y xz haciendo menos de cuatro
multiplicaciones.
Teniendo en cuenta que:
r = (w + x)(y + z) = wy + (wz + xy)+ xz

función mult2(u,v:granEnt) devuelve granEnt


variables n,s:entero; w,x,y,z,r,p,q:granEnt
principio
n:=máx(tamaño(u),tamaño(v));
si n es pequeño entonces devuelve multClásica(u,v)
sino
s:=n div 2;
w:=u div 10s; x:=u mod 10s;
y:=v div 10s; z:=v mod 10s;
r:=mult2(w+x,y+z);
p:=mult2(w,y); q:=mult2(x,z);
devuelve p*102s+(r-p-q)*10s+q
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 27


Multiplicación de enteros grandes
• Eficiencia temporal de la versión 2:
– Teniendo en cuenta que w+x e y+z pueden necesitar 1+n/2 cifras,

( ) ( ) ( )
t 2 (n) ∈t2 n 2 + t2 n 2 + t2 1+ n 2 + Θ(n)

Y por tanto,

( ) (
t 2 (n) ∈Θ nlog 3 ∈O n 1,59 )
– Debido a la constante multiplicativa, el algoritmo sólo es interesante en la
práctica para n grande.
– Una buena implementación no debe usar la base 10 sino la base más
grande posible que permita multiplicar dos “cifras” (de esa base)
directamente en hardware.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 28


Multiplicación de enteros grandes
– La diferencia entre los órdenes n2 y n1,59 es menos espectacular que la existente
entre n2 y nlog n.
– Ejemplo realizado en un computador en base 220:
(que permite multiplicar directamente números de 20 dígitos binarios)
• Multiplicación de números de unas 602 cifras (base decimal):
algoritmo clásico: 400 milisegundos
algoritmo mult2: 300 milisegundos
• Multiplicaciones de números de unas 6000 cifras (base decimal):
algoritmo clásico: 40 segundos
algoritmo mult2: 15 segundos
– Descomponiendo los operandos en más de dos partes se puede lograr la
multiplicación de dos enteros en un tiempo del orden de nα, para
cualquier α>1.
– Descomponiendo los operandos en n1/2 partes y usando la transformada de
Fourier, se pueden multiplicar dos enteros de n cifras en un tiempo
O(n log n loglog n) (algoritmo Schönhage–Strassen, 1971) o incluso en
n log n 2O(log* n) (algoritmo de Martin Fürer, 2007).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 29


Potenciación de enteros
• Problema: Dados los enteros positivos a, n y z,
se trata de calcular an mod z.
• Solución ingenua:
función pot0(a,n,z:entero) devuelve entero
{Devuelve an mod z.}
variables r,i:entero
principio
r:=1;
para i:=1 hasta n hacer
r:=r*a
fpara;
devuelve r mod z
fin

– Si se quita la operación mod z final, sirve para calcular an (no


modular).
– Si “r:=r*a” se considera “operación elemental”, el coste está en Θ(n).
Pero NO es así (p.e., 1517 no cabe en 8 bytes).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 30


Potenciación de enteros
• Inconvenientes de esta solución:
– Su coste (el bucle se ejecuta n veces).
Si se quiere aplicar a un entero a grande (de m cifras), el coste es
prohibitivo.
Θ(m2n2), si se usa el algoritmo clásico de multiplicar.
nº cifras(r1)=m (r1 denota r tras el 1er paso)
nº cifras(ri+1)=m+mi ⇒ nº cifras(ri+1)=i m
n− 1
coste = ∑ M (m ,i m)
i =1

Método clásico de multiplicar


n− 1 n− 1
⇒ coste = ∑cmim = cm2 ∑i = cm2n2
i =1 i =1

Θ(mlog 3n2), si se usa el algoritmo de divide y vencerás para multiplicar.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 31


Potenciación de enteros
• Existe un algoritmo más eficiente para la potenciación de
enteros.
Por ejemplo, con dos multiplicaciones y elevar al cuadrado cuatro veces
se obtiene:
2
 2
2
( )
x 25 =   x 2x   x
  
Nótese que reemplazando en
2
 
2 
( )
2
x =   x × x × 1 × 1 × x
25 2
  
cada x por un 1 y cada 1 por un 0, se obtiene la secuencia de bits 11001
(expresión binaria de 25).

( );
2
En otras palabras, x 25 = x24x ; x24 = x12 etc

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 32


Potenciación de enteros
• Un algoritmo de eficiencia aceptable:

función pot(a,n,z:entero) devuelve entero


{Devuelve an mod z.}
variable r:entero
principio
si n=0 entonces devuelve 1
sino
si n es impar entonces
r:=pot(a,n-1,z); (Es un algoritmo de reducción)
devuelve a*r mod z
sino
r:=pot(a,n/2,z);
devuelve r*r mod z
fsi
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 33


Potenciación de enteros
• Sobre la eficiencia de este algoritmo:

– Tiempo O(h(n) × M(z))


• h(n) = nº de multiplicaciones módulo z.
• M(z) = cota del tiempo para multiplicar dos enteros menores que z y
calcular el módulo.

– Es claro que:
0 si n = 0

h(n) = 1+ h(n − 1) si n es impar

1+ h(n / 2) en otro caso

Y, por tanto, h(n) es logarítmico en n.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 34


Potenciación de enteros
• Una versión iterativa:

función potIter(a,n,z:entero) devuelve entero


{Devuelve an mod z.}
variable i,x,r:entero
principio
i:=n; x:=a; r:=1;
mq i>0 hacer
si i es impar entonces r:=r*x mod z fsi;
x:=x*x mod z;
i:=i div 2
fmq;
devuelve r
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 35


Potenciación de enteros
• Comentarios finales:
– Ni la versión recursiva ni la iterativa del algoritmo de potenciación
presentadas aquí son las óptimas, pero ambas son razonablemente
buenas.
– Suprimiendo de ambos algoritmos los cálculos “mod z”, se obtienen
algoritmos para elevar un entero cualquiera a a otro cualquiera n.
Su eficiencia depende, obviamente, del algoritmo que se utilice para
multiplicar enteros grandes.
– Si a, n y z son números de 200 cifras:
• el algoritmo potIter puede calcular an mod z en menos de 1 segundo,
• el algoritmo ingenuo pot0 requeriría del orden de 10179 veces la edad del
Universo.

Suponiendo que dos enteros de 200 cifras se multiplican en 1 milisegundo.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 36


Introducción a la criptografía
• El problema:
Eva fue un día al teatro con su vecina Alicia y allí
le presentó a ésta a su amigo Roberto.

Por razones que no vienen al caso, Alicia decide


enviar a Roberto un mensaje secreto.
Desea hacerlo en una conversación telefónica, pero ésta puede ser
escuchada por Eva.
Eva puede escuchar la información que circula por la línea pero no puede
introducir mensajes ni modificar los que circulan.

Por supuesto, Alicia no desea que Eva


tenga acceso a sus secretos.
Se trata de encontrar un método que
permita a Alicia conseguir su objetivo.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 37


Introducción a la criptografía
• La solución clásica (¡usada durante siglos!):
– Alicia y Roberto, previamente y en secreto, se han puesto de acuerdo en
una clave k.
– Usando la clave k, Alicia puede cifrar su mensaje m, obteniendo el
mensaje cifrado c.
– Roberto, al recibir el mensaje c, utiliza la clave k para descifrarlo y
obtener el mensaje original m.
– Si Eva intercepta c, como no conoce la clave k, no podrá reconstruir el
mensaje m.

• Problema actual: telecomunicaciones


– Dos ciudadanos necesitan enviarse un mensaje cifrado mediante correo
electrónico por internet pero no pueden verse previamente en secreto para
acordar una clave k.
¡Este problema no se resolvió hasta los años 70!
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 38
Introducción a la criptografía
• Solución:
– Un sistema criptográfico de clave pública.
– El más conocido: el sistema RSA.
R.L. Rivest, A. Shamir y L.M. Adleman:
“A method for obtaining digital signatures and
public-key cryptosystems”,
Communications of the ACM, 21(2), pp. 120-126, 1978.

– Publicado previamente en:


M. Gardner: “Mathematical games: A new kind of cipher
that would take millions of years to break”,
Scientific American, 237(2), pp. 120-124, 1977.

• Planteó un problema cuya solución estimó que necesitaría 2 millones de veces


la edad del Universo de cálculo ininterrumpido del mejor computador de
aquel momento.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 39
Introducción a la criptografía

 p, q: nos primos de 300 cifras


 z=pq
(∗) ¿Cómo?
 φ=(p-1)(q-1)


n: 1≤n≤z-1, mcd(n,φ)=1
s: 1≤s≤z-1: ns mod φ=1 (∗)}
(s es único, ¡me lo guardo!)
 m: mensaje en texto
 z, n  a: codificado (ASCII)
(0≤a≤z-1)
 c: c=an mod z

c

(∗∗)  z, n, c…
 a: a=cs
mod z
 m: mensaje (ASCII)
 Yo también…
(∗∗) ¿Por qué?
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 40
Introducción a la criptografía
• Cálculo de n:

– Se genera un valor de n aleatoriamente en (1, z–1).

– Después se intenta calcular s tal que 1≤s≤z–1 y ns mod φ=1;

• la teoría de números asegura que si existe es único y si no existe es


porque n no verifica mcd(n,φ)=1.

– Si no se encuentra tal s es que n no es adecuado


(mcd(n,φ)≠1), se vuelve a generar otro n; etc.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 41


Introducción a la criptografía
• Cálculo de s (algoritmo de Euclides extendido):
– Lema. Sean u≥v>0 y d=mcd(u,v). Entonces existen a y b tales que
au+bv=d. (a y b pueden ser positivos, negativos o nulos)
Euclides
Dem.: Si u=v entonces d=v, a=0 y b=1.
Si u>v, sea w=u mod v. En particular w<v. Se tiene que d=mcd(v,w).
Por inducción, algoritmo egcd(ent u,v:entero; sal d,a,b:entero)
{Pre: u,v>0} {Post: d=mcd(u,v) ∧ d=au+bv}
existen a’ y b’ variables w,aa,bb:entero
tales que principio
selección
a’v+b’w=d. u=v: d:=v; a:=0; b:=1;
Haciendo: u<v: egcd(v,u,d,b,a);
u>v: w:=u mod v; {w<v}
a=b’ si w=0 ent d:=v; a:=0; b:=1
y sino {d=mcd(v,w)}
egcd(v,w,d,aa,bb);
b=a’–(u div v)b’ a:=bb; b:=aa-(u div v)*bb fsi
se sigue. fselección
fin
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 42
Introducción a la criptografía
– Por tanto, para calcular s tal que n s mod φ = 1 :
• n, φ > 0
• mcd(n,φ) = 1

Calcular s y t tales que n s + t φ = 1.

egcd(n,φ,d,s,t);
si d=1
entonces s es el buscado
sino n no es ‘bueno’
fsi

ns+tφ=1⇒ns=1–tφ
n s mod φ = (1 – t φ) mod φ = 1 – 0 = 1

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 43


Introducción a la criptografía
• Falta comprobar la corrección del mensaje obtenido por Roberto.

– Teorema. Sean p,q dos números primos,


z = pq, φ = (p–1)(q–1) y a tal que 0 ≤ a < z.
Si x mod φ = 1 entonces ax mod z = a.

– Alicia construye su mensaje a, 0 ≤ a < z, y a partir de él, calcula


c = an mod z.

– Roberto calcula
cs mod z = (an mod z)s mod z = ans mod z = a
(porque ns mod φ = 1).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 44


Introducción a la criptografía
• ¿Qué puede hacer Eva?

– Conoce z, n y c.

– Tiene que encontrar a, que es el único nº entre 0 y z–1 tal que


c = an mod z.

– Es decir, tiene que calcular la raíz n-ésima de c módulo z.

– No se conoce ningún algoritmo eficiente para hacerlo.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 45


Introducción a la criptografía
• La mejor solución conocida es factorizar z en p y q.
– Después, calcular φ=(p-1)(q-1), calcular s, y calcular a igual que Roberto.

• Problema: factorizar un número de unas 300 cifras (i.e., unos


1024 bits) parece imposible (o mejor: es difícil) con la tecnología
actual y el estado actual de la teoría de números.
– El problema propuesto por Gardner exigía factorizar un número de 129
cifras (Gardner estimó en 2 millones de veces la edad del Universo el
tiempo necesario para resolverlo).
– En 1989, se estimaba que ese mismo problema podría ser resuelto “ya” en
unos 250 años–CRAY.
Si se trataba de un número de 200 cifras, la estimación subía a 1 millón de
años–CRAY.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 46


Introducción a la criptografía
• Sin embargo:

– En abril de 1994, Atkins, Graff, Lenstra y Leyland


resolvieron el problema propuesto por Gardner en 1977
(que exigía factorizar un nº de 129 cifras):
• 6 meses de cálculo, mediante
• unos 1600 computadores de todo el mundo trabajando como una
máquina paralela virtual.

 

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 47


Introducción a la criptografía
• Extraído de Wikipedia:
– Las claves RSA tienen normalmente entre 1024 a 2048 bits de longitud.
– Algunos expertos creen que las claves de 1024 bits podrían comenzar a
ser débiles en poco tiempo y las de 4096 en un futuro.
– Si n es suficientemente grande el algoritmo RSA es seguro, de momento.
– Si n tiene 256 bits o menos puede ser factorizado en pocas horas con un
computador personal usando software libre.
– Si n tiene 512 bits o menos puede ser factorizado por varios cientos de
computadoras como en 1994.
– Un dispositivo hardware teórico llamado TWIRL descrito por Shamir y
Tromer en el 2003 cuestionó la seguridad de claves de 1024 bits.
– Actualmente se recomienda que n tenga como mínimo 2048 bits.

– ¿Computador cuántico?  Calma: criptografía cuántica.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 48


Multiplicación de matrices
V. Strassen: “Gaussian elimination is not optimal”,
Numerische Mathematik, 13, pp. 354-356, 1969.

• Sean A y B dos matrices n×n y C su producto.


– El algoritmo clásico calcula:

Es decir, precisa un tiempo Θ(n3).

• La idea de Strassen es reducir el número de


multiplicaciones a costa de aumentar el número de
sumas y restas e introducir variables auxiliares
(como en la multiplicación de enteros grandes).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 49


Multiplicación de matrices
• Veamos el caso 2×2:

– Algoritmo clásico: 8 multiplicaciones y 4 sumas


– Reducción:

Es decir, 7 multiplicaciones y 24 sumas y restas.


Notar que el número de sumas y restas puede reducirse a 15 utilizando
más variables auxiliares para evitar cálculos repetidos, como el de

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 50


Multiplicación de matrices
• Caso 2n×2n:
– Si cada elemento de A y B del caso 2×2 lo sustituimos por una matriz n×n,
se pueden multiplicar dos matrices 2n×2n realizando:
• 7 multiplicaciones de matrices de n×n, y
• 15 sumas y restas de matrices de n×n.

• Coste:
– Una suma de matrices n×n está en Θ(n2).
– Suponer que n es potencia de 2; se obtiene la recurrencia:

( )
T (n) = 7T n 2 + Θ(n2)

Es decir, se pueden multiplicar matrices en tiempo Θ(nlog 7)∈O(n2,81).

• Si n no es potencia de 2: añadir filas y columnas nulas hasta que


lo sea (como mucho se duplica el tamaño)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 51


Multiplicación de matrices
• Comentarios finales sobre el algoritmo de Strassen:
– Según algunos estudios empíricos y debido a la constante multiplicativa,
para que se noten mejoras con respecto al algoritmo clásico, n debe ser
superior a 100, y la matriz densa.
– Es menos estable que el algoritmo clásico (i.e., para errores similares en
los datos produce mayores errores en el resultado).
– Es más difícil de implementar que el algoritmo clásico.
– Es difícilmente paralelizable, mientras que el clásico puede ser fácilmente
paralelizado.
– El algoritmo clásico precisa un espacio adicional de tamaño constante,
mientras que el algoritmo de Strassen precisa un espacio adicional mayor.
– El algoritmo de Strassen ha tenido una repercusión fundamentalmente
teórica (dio también ideas para otras operaciones basadas en él: inversión
de matrices, determinantes,…).
– Se conocen algoritmos teóricamente mejores: la actual cota superior está
en O(n2,3728639).
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 52
Calendario de un campeonato
• El problema:

En una competición deportiva se enfrentan n participantes.

Debe confeccionarse un calendario para que cada participante


juegue exactamente una vez con cada adversario.

Además, cada participante debe jugar exactamente un partido


diario.

Supongamos, por simplificar, que n = 2k.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 53


Calendario de un campeonato
• La representación de los datos y de la solución:
Participantes: 1, 2, …, n.
Cada participante debe saber el orden en el que se enfrenta a los n – 1
restantes.
Por tanto, la solución puede
representarse en una matriz n×(n – 1).

El elemento (i,j), 1≤i≤n, 1≤j≤n-1, contiene el número del participante


contra el que el participante i-ésimo compite el día j-ésimo.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 54


Calendario de un campeonato
• Solución de fuerza bruta:
1. Se obtiene para cada participante i, 1≤i≤n, el conjunto P(i) de todas las
permutaciones posibles del resto de los participantes {1..n}\{i}.
2. Se completan las filas de la matriz de todas las formas posibles,
incluyendo en cada fila i algún elemento de P(i).
3. Se elige cualquiera de las matrices resultantes en la que toda columna j,
1≤j≤n-1, contiene números distintos (nadie puede competir el mismo día
contra dos participantes).

– Cada conjunto P(i) consta de (n-1)! elementos.


– La matriz tiene n filas.

Hay n! formas distintas de rellenar la matriz.

¡Es demasiado costoso!


Algoritmia básica - Javier Campos (Universidad de Zaragoza) 55
Calendario de un campeonato
• Una solución mediante la técnica de divide y vencerás (caso
n=2k, k>0):
– Caso básico: n=2, basta con una competición.
– Caso a dividir: n=2k, con k>1.
• Se elaboran independientemente dos sub-calendarios de 2k-1 participantes:
• Uno para los participantes 1..2k-1, y otro para los participantes 2k-1+1..2k.
• Falta elaborar las competiciones cruzadas entre los participantes de
numeración inferior y los de numeración superior.
– Se completa primero la parte de los participantes de numeración inferior:
1er participante: compite en días sucesivos con los participantes de
numeración superior en orden creciente.
2º participante: toma la misma secuencia y realiza una permutación
cíclica de un participante.
Se repite el proceso para todos los participantes de numeración inferior.
– Para los de numeración superior se hace lo análogo con los de inferior.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 56


Calendario de un campeonato

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 57


Calendario de un campeonato
tipo tabla=vector[1..n,1..n-1] de 1..n

algoritmo calendario(sal t:tabla)


{Devuelve en t el calendario de competición de n participantes, con n=2k, k>0.}
principio
formarTabla(t,1,n)
fin

algoritmo formarTabla(sal t:tabla; ent inf,sup:1..n)


{Forma la parte de tabla correspondiente a los enfrentamientos de los
participantes inf..sup}
variable medio:1..n
principio
si inf=sup-1 entonces t[inf,1]:=sup; t[sup,1]:=inf
sino
medio:=(inf+sup) div 2;
formarTabla(t,inf,medio);
formarTabla(t,medio+1,sup);
completarTabla(t,inf,medio,medio,sup-1,medio+1);
completarTabla(t,medio+1,sup,medio,sup-1,inf)
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 58


Calendario de un campeonato

algoritmo completarTabla(e/s t:tabla;


ent eqInf,eqSup,díaInf,díaSup,eqInic:1,,n)
{Rellena t[eqInf..eqSup,díaInf..díaSup] con permutaciones cíclicas
empezando en eqInic}
principio
para j:=díaInf hasta díaSup hacer
t[eqInf,j]:=eqInic+j-díaInf
fpara;
para i:=eqInf+1 hasta eqSup hacer
t[i,díaInf]:=t[i-1,díaSup];
para j:=díaInf+1 hasta díaSup hacer
t[i,j]:=t[i-1,j-1]
fpara
fpara
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 59


Calendario de un campeonato
• Coste temporal:
– Recurrencia: T (n) = 2T (n 2)+ n2 4
– Por tanto, O(n2).

• ¿Y si n no es potencia de 2?
– Supongamos que está resuelto para n par.
– Si n es impar (mayor que 1), no bastan con n-1 días para la competición,
sino que se necesitan n.
Basta con resolver el problema resultante de añadir un participante
(ficticio) más: el n+1.
Como n+1 es par, podemos calcular el calendario, que consta de n días.
Una vez resuelto, si al participante i-ésimo le toca jugar el día j-ésimo
contra el participante n+1 (ficticio), eso significa que j es el día de
descanso para el participante i.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 60


Calendario de un campeonato
• ¿Y si n es par?
– Si n div 2 es par, se puede aplicar el algoritmo “formarTabla” (visto para
el caso n=2k).
– Si n div 2 es impar:
Paso 1:
• Se calcula la 1ª parte de la competición para los n div 2 participantes de
numeración inferior, añadiendo un participante ficticio.
• Se calcula la primera parte de la competición para los otros n div 2
participantes, añadiendo otro participante ficticio.
Paso 2:
• El día j-ésimo, 1≤j≤n div 2, se hace jugar entre sí a los dos participantes, uno
de numeración inferior y otro superior, a los que les había tocado el j como
día de descanso en el Paso anterior.
Paso 3:
• Se completa el resto de la tabla con competiciones cruzadas, de forma
parecida a como se hizo en el algoritmo “completarTabla”.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 61


Calendario de un campeonato

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 62


Programación dinámica

Algoritmia básica - Javier Campos (Universidad de Zaragoza)


Programación dinámica
• Introducción 3
• El problema de la mochila 0-1 8
• Camino de coste mínimo en un grafo multietapa 18
• Multiplicación de una secuencia de matrices 31
• Pasos en una solución de Programación Dinámica 41
• Comparaciones de secuencias 43
• Caminos mínimos entre todos los pares de nodos de un grafo 50
• Árboles binarios de búsqueda óptimos 56
• Un problema de fiabilidad de sistemas 67
• El problema del viajante de comercio 72
• Planificación de trabajos 82
• Una competición internacional 95
• Triangulación de polígonos 101

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 2


Programación dinámica: Introducción
• Recordemos el problema de la mochila (fraccionaria):
– Se tienen n objetos fraccionables y una mochila.
– El objeto i tiene peso pi y una fracción xi (0≤xi≤1) del objeto i produce un
beneficio bixi.
– El objetivo es llenar la mochila,
de capacidad C, maximizar ∑ bi xi
de manera que se 1≤i ≤n
maximice el beneficio.
sujeto a ∑ pi xi ≤ C
1≤i ≤n

con 0≤ xi ≤ 1, bi > 0, pi > 0, 1≤ i ≤ n

• Una variante: la “mochila 0-1” (el “auténtico” problema de la mochila)


– xi sólo toma valores 0 ó 1, indicando que el objeto se deja fuera o se mete en
la mochila.
– Los pesos, pi, y la capacidad son números naturales.
Los beneficios, bi, son reales no negativos.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 3


Programación dinámica: Introducción
• Ejemplo:
n=3 C=15
(b1,b2,b3)=(38,40,24)
(p1,p2,p3)=(9,6,5)

• Recordar la estrategia voraz:


– Tomar siempre el objeto que proporcione mayor beneficio por unidad de
peso.
– Se obtiene esta solución: (x1,x2,x3)=(0,1,1), con beneficio 64
– Sin embargo, la solución óptima es: (x1,x2,x3)=(1,1,0), con beneficio 78

• Por tanto, la estrategia voraz no calcula la solución óptima del


problema de la mochila 0-1.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 4


Programación dinámica: Introducción
R. Bellman: Dynamic Programming,
Princeton University Press, 1957.
• Técnica de programación dinámica
– Se emplea típicamente para resolver problemas de optimización.
– Permite resolver problemas mediante secuencias de decisiones.
Como el esquema voraz
– A diferencia del esquema voraz, se producen varias secuencias de decisiones y
sólamente al final se sabe cuál es la mejor de ellas.

– Descompone un problema en subproblemas del mismo tipo.


Como en divide y vencerás
– A diferencia de divide y vencerás, los subproblemas están superpuestos entre sí,
comparten subproblemas entre ellos  se almacenan y reutilizan sus soluciones
(memoization)

– Está basada en el principio de optimalidad de Bellman (= propiedad de la


subestructura óptima):
“Cualquier subsecuencia de decisiones de una secuencia óptima de decisiones que
resuelve un problema también debe ser óptima respecto al subproblema que resuelve.”

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 5


Programación dinámica: Introducción
– Supongamos que un problema se resuelve tras tomar una
secuencia d1, d2, …, dn de decisiones.

– Si hay d opciones posibles para cada una de las decisiones,


una técnica de fuerza bruta exploraría un total de dn
secuencias posibles de decisiones (explosión combinatoria).

– La técnica de programación dinámica evita explorar todas las


secuencias posibles por medio de la resolución de
subproblemas de tamaño creciente y almacenamiento en una
tabla de las soluciones óptimas de esos subproblemas para
facilitar la solución de los problemas más grandes.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 6


Programación dinámica: Introducción
• Más formalmente:
– Sea E0 el estado inicial del problema.
– Sea el conjunto de valores de decisión
posibles para la decisión d1.
– Sea E1i el estado del problema tras la elección del valor v1i, 1≤i≤n1.
– Sea S1i una secuencia óptima de decisiones respecto al estado E1i.
• Principio de optimalidad de Bellman:
Una secuencia óptima de decisiones respecto a E0 es la mejor de las
secuencias de decisión {v1i,S1i}, 1≤i≤n1.
El mismo razonamiento puede aplicarse a cualquier subsecuencia de
decisiones dk, …, dl, 1≤k≤l≤n, partiendo como estado inicial de Ek-1.
Una solución dinámica para este problema, simbolizado como (k,l),
debe expresarse en términos de los valores de decisión existentes para
la decisión dk y el subproblema (k+1,l), resultante de aplicar cada valor
de decisión.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 7


El problema de la mochila 0-1
l
• Sea mochila(k,l,P) el problema: maximizar ∑ bi xi
i=k
l
sujeto a ∑ pi xi ≤ P
i=k

con xi ∈{0,1}, k ≤ i ≤ l

– El problema de la mochila 0-1 es mochila(1,n,C).


• Principio de optimalidad:
Sea y1,…,yn una secuencia óptima de valores 0-1 para x1,…,xn.
– Si y1=0, entonces y2,…,yn forman una secuencia óptima para el problema
mochila(2,n,C).
– Si y1=1, entonces y2,…,yn forman una secuencia óptima para el problema
mochila(2,n,C-p1).
Demostración: Si existe una solución mejor y˜2 ,Κ , y˜n para el problema
correspondiente, entonces y1 , y˜2 ,Κ , y˜n es mejor que para el
problema mochila(1,n,C), en contra de la hipótesis.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 8


El problema de la mochila 0-1
• Lo mismo se cumple en cualquier etapa de decisión:
– Si y1,…,yn es una solución óptima del problema
mochila(1,n,C), entonces para todo j, 1≤j≤n:

• y1,…,yj es solución óptima de

 j 
mochila  1, j , ∑ pi xi 
 i =1 

• yj+1,…,yn es solución óptima de

 j 
mochila  j + 1,n,C − ∑ pi xi 
 i=1 

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 9


El problema de la mochila 0-1
• Ecuación de recurrencia hacia adelante:
– Si gj(c ) es el beneficio (o ganancia total) de una solución óptima
de mochila(j,n,c), entonces

{
gj (c) = max gj + 1(c), g j+ 1(c − pj ) + bj }
dependiendo de que el objeto j-ésimo entre o no en la solución
(nótese que sólo puede entrar si c-pj≥0).
– Además,
gn+ 1 (c) = 0, para cualquier capacidad c

Ambas ecuaciones permiten calcular g (C ) , que


1
es el valor de una solución óptima de
mochila(1,n,C).

(Nótese que la ecuación de recurrencia es hacia adelante


pero el cálculo se realiza hacia atrás.)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 10


El problema de la mochila 0-1
• Ecuación de recurrencia hacia atrás:
– Si gj (c) es el beneficio (o ganancia total) de una solución óptima de
mochila(1,j,c), entonces

{
gj (c) = max gj − 1(c) , gj − 1(c − pj ) + bj }
dependiendo de que el objeto j-ésimo entre o no en la solución
(nótese que sólo puede entrar si c-pj≥0).
– Además,
g0(c ) = 0, para cualquier capacidad c

Ambas ecuaciones permiten calcular gn(C) , que es el


valor de una solución óptima de mochila(1,n,C).

(Ahora la recurrencia es hacia atrás pero el cálculo se realiza


hacia adelante.)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 11


El problema de la mochila 0-1
• Tanto la recurrencia hacia adelante como hacia atrás permiten escribir
un algoritmo recursivo de forma inmediata.
función mochila1(p,b:vector[1..n] de nat; C:nat) devuelve nat
principio
devuelve g(n,C)
fin

función g(j,c:nat) devuelve nat


principio
si j=0 entonces devuelve 0
sino
si c<p[j] entonces devuelve g(j-1,c)
sino
si g(j-1,c)≥g(j-1,c-p[j])+b[j] entonces devuelve g(j-1,c)
sino
devuelve g(j-1,c-p[j])+b[j]
fsi
fsi
fsi
fin
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 12
El problema de la mochila 0-1
• Problema: ineficiencia
– Un problema de tamaño n se reduce a dos subproblemas de tamaño (n-1).
– Cada uno de los dos subproblemas se reduce a otros dos…
Por tanto, se obtiene un algoritmo exponencial.

• Sin embargo, el número total de subproblemas a resolver no es


tan grande:
La función gj (c) tiene dos parámetros:
• el primero puede tomar n valores distintos y
• el segundo, C valores.
¡Luego sólo hay nC problemas diferentes!
• Por tanto, la solución recursiva está generando y resolviendo el
mismo problema muchas veces.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 13


El problema de la mochila 0-1
• Memoization: las soluciones de los subproblemas se almacenan
en una tabla para evitar hacer más de una vez la misma llamada
recursiva  se obtiene un algoritmo iterativo.
– Matriz n×C cuyo elemento (j,c) almacena g j ( c )
– Para el ejemplo anterior:
En castellano…
n=3 C=15 “memoización”
(b1,b2,b3)=(38,40,24) “memorialización”
(p1,p2,p3)=(9,6,5) ...

c=…

j=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
j=1
j=2
j=3
{
g j (c ) = max g j − 1(c) , g j − 1(c − p j ) + b j }
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 14
El problema de la mochila 0-1
algoritmo mochila(ent p,b:vect[1..n]de nat; ent Cap:nat;
sal g:vect[0..n,0..Cap]de nat)
variables c,j:nat
principio
para c:=0 hasta Cap hacer g[0,c]:=0 fpara;
para j:=1 hasta n hacer g[j,0]:=0 fpara;
para j:=1 hasta n hacer
para c:=1 hasta Cap hacer
si c<p[j] entonces
g[j,c]:=g[j-1,c]
sino
si g[j-1,c]≥g[j-1,c-p[j]]+b[j] entonces
g[j,c]:=g[j-1,c]
sino
g[j,c]:=g[j-1,c-p[j]]+b[j]
fsi
fsi
fpara
fpara
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 15


El problema de la mochila 0-1
• Cálculos posibles a partir de la tabla g:
– beneficio total: g[n,Cap]
– los objetos metidos en la mochila:
algoritmo objetos(ent p,b:vect[1..n]de nat; ent Cap:nat;
ent g:vect[0..n,0..Cap]de nat)
principio
test(n,Cap)
fin

algoritmo test(ent j,c:nat)


principio
si j>0 entonces
si c<p[j] entonces test(j-1,c)
sino
si g[j-1,c-p[j]]+b[j]>g[j-1,c] entonces
test(j-1,c-p[j]); escribir('meter ',j)
sino test(j-1,c)
fsi fsi fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 16


El problema de la mochila 0-1
• Consideraciones finales

– Cada componente de la tabla g se calcula en tiempo


constante, luego el coste de construcción de la tabla es O(nC).

– El algoritmo test se ejecuta una vez por cada valor de j,


desde n descendiendo hasta 0, luego su coste es O(n).

– Si C es muy grande, entonces esta solución no es buena.

– Si los pesos pi o la capacidad C son reales, esta solución no


sirve.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 17
Camino de coste mínimo en un grafo multietapa
• Grafo multietapa:
– Un grafo multietapa G=(V,A) es un grafo dirigido en el que se puede hacer
una partición del conjunto V de vértices en k (k≥2) conjuntos distintos
Vi, 1≤i≤k, tal que todo arco del grafo (u,v) es tal que u∈Vi y v∈Vi+1 para
algún i, 1≤i<k.
– Los conjuntos V1 y Vk tienen un solo vértice que se llama vértice origen, o,
y vértice destino, d, respectivamente.
V1 V2 V3 V4 V5
2 3 7
8 5
5 1 5 1
7 1 9
o 1 3 4 6 8 10 d

2 5 6 4
12
4 9 9

– Consideraremos grafos etiquetados.


Denotamos por c(u,v) el coste del arco (u,v).
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 18
Camino de coste mínimo en un grafo multietapa
• El problema: Encontrar un camino de coste mínimo que
vaya de o a d.

– Todo camino de o a d tiene exactamente un vértice en cada


Vi, por eso se dice que cada Vi define una etapa del grafo.

V1 V2 V3 V4 V5
2 3
8
7 5
5 1 5 11
7 9
o 1 3 4 6 8 10 d
2 5 6 4
12
4 9 9

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 19


Camino de coste mínimo en un grafo multietapa
• Ejemplo de aplicación:
– Se tienen n unidades de un recurso que deben asignarse a r
proyectos.
– Si se asignan j, 0≤j≤n, unidades al proyecto i se obtiene un
beneficio Ni,j.
– El problema es asignar
el recurso a los r proyectos
maximizando
el beneficio total.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 20


Camino de coste mínimo en un grafo multietapa
– Formulación como grafo multietapa:
• Número de etapas: r+1
• La etapa i, 1≤i≤r, representa el proyecto i.
• Hay n+1 vértices vi,j, 0≤j≤n, en cada etapa i, 2≤i≤r.
• Las etapas 1 y r+1 tienen un vértice, o=v1,0 y d=vr+1,n,
respectivamente.
• El vértice vi,j, 2≤i≤r, representa el estado en el que se asignan un total
de j unidades del recurso a los proyectos 1, 2, …, i-1.
• Los arcos son de la forma (vi,j,vi+1,l) para todo j≤l y 1≤i<r.
• El arco (vi,j,vi+1,l), j≤l, tiene asignado un coste Ni,l-j que corresponde a
asignar l-j unidades del recurso al proyecto i, 1≤i<r.
• Además hay arcos de la forma (vr,j,vr+1,n), que tienen asignado un coste
max {Nr , p}.
0≤ p ≤n − j

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 21


Camino de coste mínimo en un grafo multietapa
– Grafo resultante para r=3 y n=4.
• La asignación óptima está
definida por un camino de N 2,0
v2,0 v3,0
coste máximo de o a d. N 1,0
max {N 3,i }
i= 0,1,2,3,4
• Para convertirlo en un N 2,1

problema de camino de v2,1 N 2,0


v3,1
N 1,1
coste mínimo basta N 2,2 max {N 3,i }
N 2,3 i= 0,1,2,3
cambiar los signos de
N 2,1 max {N 3,i }
las etiquetas. N 1,2 N 2,0 i= 0,1,2
o = v1,0 v2,2 v3,2 d = v4,4

N max {N 3,i }
N 2,1 N 2,2 2,3 i= 0,1
N 1,3 N 2,2
v2,3 v3,3
N 2,0
N 2,1 N 3,0
N 1,4 N 2,4

v2,4 v3,4
N 2,0
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 22
Camino de coste mínimo en un grafo multietapa
• Solución de programación dinámica:
V1 V2 V3 V4 V5
2 3
8
7 5
5 1 5 11
7 9
o 1 3 4 6 8 10 d
2 5 6 4
12
4 9 9

– Cada camino de o a d es el resultado de una secuencia de k-2 decisiones.


– Decisión i-ésima: determinar, a partir de un vértice vi de Vi, un arco que
tenga a vi como origen y algún nodo de Vi+1 como destino.
– Principio de optimalidad:
El camino de coste mínimo debe contener subcaminos de coste mínimo
entre otros nodos.
Dem.: En otro caso, podrían sustituirse dichos subcaminos por otros mejores,
resultando un camino total de coste menor.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 23
Camino de coste mínimo en un grafo multietapa
– Ecuación de recurrencia hacia adelante:
• Sea s(i,j) un camino de coste mínimo C*(i,j) desde el vértice j del
conjunto Vi hasta el vértice destino d.
• Entonces:

C∗ (i , j ) = min
l ∈V i+ 1
{c( j ,l )+ C∗ (i + 1,l )}, para 1≤ i ≤ k − 2
( j ,l )∈A

V1 V2 V3 V4 V5
2 3
8
7 5
5 1 5 11
7 9
o 1 3 4 6 8 10 d
2 5 6 4
12
4 9 9

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 24


Camino de coste mínimo en un grafo multietapa

C∗ (i , j ) = min
l ∈V i+ 1
{c( j ,l )+ C∗ (i + 1,l )}, para 1≤ i ≤ k − 2
( j ,l )∈A
V1 V2 V3 V4 V5
2 3
8
7 5
5 1 5 11
7 9
o 1 3 4 6 8 10 d
2 5 6 4
12
4 9 9
C∗ (3,5)= min {8+ C ∗(4,7),11+ C ∗ (4,8),6+ C ∗(4,9)}= 13
C ∗ (3,6)= 4+ C ∗(4,8) = 13
C ∗ (2,2)= min {3+ C ∗(3,5),1+ C ∗ (3,6)}= 14
C ∗ (2,3)= 4+ C ∗(3,5) = 17
C ∗ (2,4)= min {5+ C ∗(3,5),9+ C ∗ (3,6)}= 18
C ∗ (1,1)= min {5+ C ∗(2,2),7+ C ∗ (2,3),2+ C ∗(2,4)}= 19

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 25


Camino de coste mínimo en un grafo multietapa
– Falta almacenar las decisiones hechas en cada etapa que
minimizan el coste:
• Sea D(i,j) el valor de l que minimiza c( j,l) + C∗ (i + 1,l).
• Entonces el camino de coste mínimo es:
v1=1; v2=D(1,1); v3=D(2,D(1,1)); etc.
V1 V2 V3 V4 V5
2 3
8
7 5
5 1 5 11
7 9
o 1 3 4 6 8 10 d
D(3, 5) = 7; D (3,6) = 8 2 5 6 4
12
4 9 9
D (2,2)= 6; D (2,3) = 5; D (2,4) = 5
D (1,1)= 2
v1 = 1
v2 = D (1,1) = 2
v3 = D (2,D (1,1))= 6
v4 = D (3,D (2,D (1,1)))= 8
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 26
Camino de coste mínimo en un grafo multietapa
algoritmo multietapa(ent G=(V,A,c):grafo; ent k,n:nat;
sal P:vect[1..k]de 1..n)
{Los vértices están numerados de forma que los índices de los
vértices de una etapa son mayores que los índices de los de la
etapa anterior.
El primer índice de C* y D, que sólo identificaba la etapa, se ha
suprimido.}
variables C:vect[1..n]de real; D:vect[1..n]de 1..n; j,r:1..n
principio
C[n]:=0.0; {Cálculo de C* y D}
para j:=n-1 descendiendo hasta 1 hacer
r:=vértice t.q. (j,r)∈A ∧ c(j,r)+C[r] es mínimo;
C[j]:=c(j,r)+C[r];
D[j]:=r
fpara;
P[1]:=1; P[k]:=n; {Construcción del camino}
para j:=2 hasta k-1 hacer
P[j]:=D[P[j-1]]
fpara
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 27


Camino de coste mínimo en un grafo multietapa
• Coste del algoritmo:

– Si G está representado mediante listas de adyacencia,


entonces el cálculo de r en el interior del primer bucle lleva
un tiempo proporcional al grado del vértice j.

– Por tanto, si a es el número de arcos del grafo, el coste total


del algoritmo es Θ(a).

(El segundo bucle lleva un tiempo Θ(k).)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 28


Camino de coste mínimo en un grafo multietapa
• Análogamente, se desarrolla la recurrencia hacia atrás.
– Ecuación de recurrencia hacia atrás:
• Sea s(i,j) un camino de coste mínimo C*(i,j) desde el vértice origen o
hasta el vértice j del conjunto Vi.
• Entonces:

C∗ (i , j ) = min
l ∈V i− 1
{c(l , j )+ C∗ (i − 1,l )}, para 3≤ i ≤ k
(l , j )∈A

V1 V2 V3 V4 V5
2 3
8
7 5
5 1 5 11
7 9
o 1 3 4 6 8 10 d
2 5 6 4
12
4 9 9

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 29


Camino de coste mínimo en un grafo multietapa
algoritmo multietapaB(ent G=(V,A,c):grafo; ent k,n:nat;
sal P:vect[1..k]de 1..n)
{Los vértices están numerados de forma que los índices de los
vértices de una etapa son mayores que los índices de los de la etapa
anterior. El primer índice de C* y D, que sólo identificaba la
etapa, se ha suprimido.}
variables C:vect[1..n]de real; D:vect[1..n]de 1..n; j,r:1..n
principio
C[1]:=0.0; {Cálculo de C* y D}
para j:=2 hasta n hacer
r:=vértice t.q. (r,j)∈ A ∧ c(r,j)+C[r] es mínimo;
C[j]:=c(r,j)+C[r];
D[j]:=r
fpara;
P[1]:=1; P[k]:=n; {Construcción del camino}
para j:=k-1 descendiendo hasta 2 hacer
P[j]:=D[P[j+1]]
fpara
fin

Nota: La eficiencia es la misma si G está representado mediante listas de adyacencia inversa.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 30


Multiplicación de una secuencia de matrices
• Se desea calcular el producto matricial:
Como es asociativo, existen varias formas…
(Recordar que el algoritmo resultante de la definición del producto de dos
matrices p×q y q×r necesita pqr multiplicaciones de escalares.)

– Ejemplo: se quiere calcular el producto ABCD, de las matrices A(13×5),


B(5×89), C(89×3) y D(3×34).
nº multip.
((AB)C)D) 10582
(AB)(CD) 54201
(A(BC))D 2856
A((BC)D) 4055
A(B(CD)) 26418

¡El caso más eficiente es casi 19 veces más rápido que el más lento!

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 31


Multiplicación de una secuencia de matrices
• ¿Cómo hallar el mejor método?
1. Insertar los paréntesis de todas las formas posibles (significativamente
diferentes).
2. Calcular para cada una el número de multiplicaciones escalares
requeridas.
• ¿Cuántas formas posibles T(n) de insertar paréntesis existen en
un producto de n matrices?
– Si cortamos entre la i y la (i+1)-ésima:
Entonces tenemos T(i)T(n-i) formas distintas.
– Como i puede tomar valores entre 1 y n-1:

n −1
T (n) = ∑ T (i )T (n − i ), para n > 1
i =1
T (1) = 1 Números de Catalan

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 32


Multiplicación de una secuencia de matrices
• Los números de Catalan crecen exponencialmente.
– De hecho puede demostrarse que:

1 2n − 2
T (n) =
n n− 1 

Por ejemplo:
n 1 2 3 4 5 10 15
T (n) 1 1 2 5 14 4862 2674440

• Luego el método directo “no sirve” (por costoso).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 33


Multiplicación de una secuencia de matrices

S. Godbole: “On efficient computation of matrix chain products”,


IEEE Transactions on Computers, 22(9), pp. 864-866, 1973.

• Aplicación del principio de optimalidad:


Si el mejor modo de realizar el producto exige dividir inicialmente entre
las matrices i e (i+1)-ésima, los productos

deberán ser realizados de forma óptima para que el total también sea
óptimo.
• Método:
– Construir la matriz [mij], 1≤i≤j≤n, donde mij da el óptimo (i.e., el número
de multiplicaciones escalares requeridas) para la parte
del producto total.
– La solución final vendrá dada por m1n.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 34
Multiplicación de una secuencia de matrices
– Construcción de [mij], 1≤i≤j≤n:
• Guardar las dimensiones de las Mi, 1≤i≤n, en un vector d, de
0..n componentes, de forma que Mi tiene dimensiones di-1×di.
• La diagonal s de [mij] contiene los mij tales que j-i=s:

• El tercer caso representa que para calcular se


intentan todas las posibilidades
y se escoge la mejor.
• De forma más compacta:
0, si i = j
mij =  min {mik + mk + 1, j + di − 1dkdj }, si i < j
i ≤ k< j
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 35
Multiplicación de una secuencia de matrices
• Para el ejemplo anterior:
– A(13×5), B(5×89), C(89×3) y D(3×34). Se tiene d=(13,5,89,3,34).
– Para s=1: m12=5785, m23=1335, m34=9078.
– Para s=2:

– Para s=3:

– La matriz es:

(s = j – i,
es decir,
j = i + s)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 36


Multiplicación de una secuencia de matrices
• Solución recursiva inmediata:
– Aplicación de la ecuación recurrente.
– Problema: complejidad exponencial.

• Almacenamiento de las soluciones de los subproblemas


en una tabla:
– Número de subproblemas: Θ(n2).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 37


Multiplicación de una secuencia de matrices
algoritmo parentOpt(ent d:vect[0..n]de nat;
sal m:vect[1..n,1..n]de nat; sal km:vect[1..n,1..n]de 1..n)
{m es la matriz [mij] definida antes; km[i,j] guarda el índice k para
el que se alcanza el mínimo al calcular m[i,j].}
variables i,s,j,k,q:nat
principio
para i:=1 hasta n hacer m[i,i]:=0 fpara;
para s:=1 hasta n-1 hacer
para i:=1 hasta n-s hacer
j:=i+s;
m[i,j]:=∞;
para k:=i hasta j-1 hacer
q:=m[i,k]+m[k+1,j]+d[i-1]*d[k]*d[j];
si q<m[i,j] entonces
m[i,j]:=q; km[i,j]:=k
fsi
fpara
fpara
fpara
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 38


Multiplicación de una secuencia de matrices
• Coste en tiempo:

– Θ(n3)

• Coste en memoria:

– Θ(n2)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 39


Multiplicación de una secuencia de matrices
• ¡Falta hacer el producto!
– El elemento km[i,j] guarda el valor de k tal que la división
óptima de parte el producto entre Mk y Mk+1.
– Por tanto:
función multSec(M:vect[1..n]de matriz;
km:vect[1..n,1..n]de 1..n;
i,j:1..n) devuelve matriz
variables X,Y:matriz
principio
si j>i entonces
X:=multSec(M,km,i,km[i,j]);
Y:=multSec(M,km,km[i,j]+1,j];
devuelve mult(X,Y)
sino
devuelve M[i]
fsi
Fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 40


Pasos en una solución de Programación Dinámica
Para plantear una solución de programación dinámica deben seguirse los pasos
siguientes:
1. Definir de manera precisa una función parametrizada tal que, para algunos
valores de sus parámetros, nos aporte la solución del problema propuesto.
2. Escribir una ecuación recurrente (o relación de recurrencia) para esa función
parametrizada, detallando para qué valores de sus parámetros es válida la
ecuación, y escribir los casos base de la función (casos particulares de sus
parámetros para los que se puede expresar el valor de la función sin necesidad
de recurrencias).
3. Detallar qué tabla es necesaria para almacenar los valores de la función
parametrizada, y qué orden puede seguirse para calcularla. Detallar si se
precisa alguna otra tabla auxiliar para reconstruir la solución para la que la
función alcanza el óptimo.
4. Escribir en pseudocódigo el algoritmo para rellenar la tabla de los valores
óptimos de la función parametrizada y, si se solicita, escribir el algoritmo
para construir la solución del problema original.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 41


Pasos en una solución de Programación Dinámica
Ejemplo para el problema de multiplicación de una secuencia de matrices:
1. Función m(i,j) = número mínimo de multiplicaciones de escalares necesarias
para multiplicar la subsecuencia de matrices Mi, …, Mj.
El problema originalmente propuesto es calcular m(1,n).
2. m(i,i) = 0, para i = 1..n (casos base).
m(i,j) = min1≤k<j {m(i,k) + m(k+1,j) + di-1dkdj}, para los i, j tales que 1≤i<j≤n.
3. Matriz triangular superior para almacenar los m(i,j), con 1≤i≤j≤n.
Puede calcularse por diagonales, empezando por la diagonal principal y,
desde ahí, hacia arriba.
Matriz auxiliar de iguales dimensiones para almacenar los índices k para los
que se consigue el mínimo de la ecuación recurrente para cada uno de
los m(i,j). Es la matriz km[i,j] en el algoritmo de la transparencia nº 38.
4. Algoritmos de la página 38 y de la página 40.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 42


Comparaciones de secuencias

D. Gusfield: Algorithms on Strings, Trees, and Sequences.


Computer Science and Computational Biology,
Cambridge University Press, 1997.

• Problemas relacionados con biología molecular.


• Problema de la distancia de edición:
“Mínimo número de pasos de edición para transformar una cadena en otra.”

– Sean A=a1a2…an y B=b1b2…bm dos cadenas de caracteres.


– Se quiere modificar A, carácter a carácter, hasta convertirlo en B.
– Se permiten tres tipos de cambios (pasos de edición) y cada uno tiene
coste unidad:
1. Insertar un carácter en la cadena.
2. Borrar un carácter de la cadena.
3. Sustituir un carácter por otro diferente.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 43


Comparaciones de secuencias

– Ejemplo: ¿nº de pasos?


abbc babb

Una solución: Otra solución (mejor):


abbc babb abbc babb

1: borrar a 3: sustituir c por b


1: insertar b 2: borrar c

bbc babc babbc


2: insertar a

• Aplicaciones en comparación y mantenimiento de versiones de


ficheros:
– Si se tienen varias versiones parecidas de un fichero es más eficiente
almacenar sólo la 1ª versión y para el resto de versiones almacenar los
pasos de edición (normalmente inserciones y borrados) desde la 1ª.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 44


Comparaciones de secuencias

R.A. Wagner y M.J. Fischer:


“The string-to-string correction problem”,
Journal of the ACM, 21, pp. 168-173, 1974.

• Solución de programación dinámica:


– Sean A(i) y B(j) las subcadenas prefijo de A y B
(i.e., A(i)=a1a2…ai, B(j)=b1b2…bj).
– C(i,j) el coste mínimo de transformar A(i) en B(j).
– Se considera el problema: A(n) → B(m)
– Fijémonos en los posibles tratamientos de an:
• bien es borrado, y el problema se reduce a transformar A(n-1) en B(m) y luego borrarlo;
• bien se le hace coincidir con algún carácter de B anterior a bm, en cuyo caso el
problema se reduce a transformar A(n) en B(m-1) y luego insertar un carácter igual a
bm;
• bien se le sustituye por un carácter igual a bm, y el problema se reduce a transformar
A(n-1) en B(m-1) y luego sustituir an;
• o bien an coincide con bm, y entonces basta con transformar A(n-1) en B(m-1).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 45


Comparaciones de secuencias
– Si denotamos:
0, si ai = bj
c (i , j) = 
1, si ai ≠ bj
– Se tiene:
C (n − 1, m) + 1 (borrandoan )
C (n, m) = min C (n, m -1)+1 (insertandobm)
C (n − 1, m − 1) + c(n, m) (otros casos)
- No hacer nada
C (i ,0) = i , for all i , 0≤ i ≤ n - Cambiar an por bm
C (0, j) = j , for all j , 0≤ j ≤ m
– Solución recursiva obvia: ¡coste exponencial!
– Sin embargo, sólo existen nm subproblemas diferentes
(C(i,j), 1≤i≤n,1≤j≤m).
– Orden de cálculo (a partir de la ecuación): j

i ?
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 46
Comparaciones de secuencias
algoritmo compSec(ent A:cad[n]; ent B:cad[m];
sal C:vect[0..n,0..m]de nat; sal T:vect[1..n,1..m]de Transf)
{Transf=(borrar,insert,sustit,nada); i.e. posibles transformaciones}
variables i,j,x,y,z:nat
principio
para i:=0 hasta n hacer C[i,0]:=i fpara;
para j:=0 hasta m hacer C[0,j]:=j fpara;
para i:=1 hasta n hacer
para j:=1 hasta m hacer
x:=C[i-1,j]+1; y:=C[i,j-1]+1;
si A[i]=B[j] entonces z:=C[i-1,j-1]
sino z:=C[i-1,j-1]+1
fsi;
C[i,j]:=min(x,y,z);
T[i,j]:= (min=x) => borrar; {último cambio de A[i] a B[j]}
(min=y) => insert;
(min=z) & A[i]=B[j]) => nada;
(min=z) & A[i]≠B[j]) => sustit;
fpara
fpara
Fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 47


Comparaciones de secuencias
algoritmo res(ent i,j:nat)
{Para resolver el problema, ejecutar res(n,m).}
variable k:nat
principio
selección
i=0: para k:=1 hasta j hacer
escribir('Añadir',B[k],'en el lugar',k) fpara
j=0: para k:=1 hasta i hacer
escribir('Borrar car.nº',k) fpara
otros:
selección
T[i,j]=borrar: res(i-1,j); escribir('Borrar car.nº',i)
T[i,j]=insert: res(i,j-1); escribir('Insertar car.nº',j,
'de B tras la posición',i)
T[i,j]=sustit: res(i-1,j-1); escribir('Sustit. car.nº',i,
'de A por nº',j,'de B')
T[i,j]=nada: res(i-1,j-1)
fselección
fselección
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 48


Comparaciones de secuencias
• Coste:

– En tiempo: Θ(nm)

– En espacio: Θ(nm)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 49


Caminos mínimos entre todos los pares de nodos de un grafo
R.W. Floyd:
“Algorithm 97: Shortest path”, Bernard Roy (1959)
Communications of the ACM, 5(6), p. 345, 1962. Robert Floyd (1962)
Stephen Warshall (1962)
• Problema:
Cálculo de los caminos de coste mínimo entre todos los pares de vértices de un
grafo dirigido sin ciclos de peso negativo.
• Principio de optimalidad:
Si i1, i2, …, ik, ik+1, …, in es un camino de coste mínimo de i1 a in, entonces:
• i1, i2, …, ik es un camino de coste mínimo de i1 a ik, y
• ik, ik+1, …, in es un camino de coste mínimo de ik a in.
• Aplicación del principio:
– Si k es el vértice intermedio de mayor índice en el camino óptimo de i a j,
entonces el subcamino de i a k es un camino óptimo de i a k que, además, sólo
pasa por vértices de índice menor que k.
– Lo análogo ocurre con el subcamino de k a j.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 50


Caminos mínimos entre todos los pares de nodos de un grafo
– Sea C(i,j) el peso de la arista (i,j) o infinito si esa arista no existe.
Sea C(i,i)=0.
– Sea Dk(i,j) la longitud (o distancia) del camino de coste mínimo de i a j
que no pasa por ningún vértice de índice mayor que k.
– Sea D(i,j) la longitud del camino de coste mínimo de i a j.
– Entonces:
D(i,j) = Dn(i,j), 1≤ i ≤ n, 1≤ j ≤ n

– Ahora, un camino óptimo de i a j que no pase por ningún vértice de índice


mayor que k, o bien pasa por el vértice k o no pasa.
• Si pasa por k entonces: Dk (i , j) = Dk−1(i ,k) + Dk−1(k , j )
• Si no pasa por k entonces
ningún vértice intermedio
tiene índice superior a k-1: Dk (i , j) = Dk−1(i , j )

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 51


Caminos mínimos entre todos los pares de nodos de un grafo

• En resumen:
– Se tiene la siguiente ecuación recurrente que define el método
de programación dinámica.

{ }
Dk (i , j) = min Dk − 1(i , j ), Dk − 1(i , k) + Dk − 1(k , j ) ,
k ≥1
D0 (i , j) = C (i , j ), 1≤ i ≤ n, 1≤ j ≤ n

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 52


Caminos mínimos entre todos los pares de nodos de un grafo

{Pre: g es un grafo dirigido etiquetado sin ciclos negativos}


función Floyd(g:grafo) devuelve vector[vért,vért] de etiq
variables D:vector[vért,vért] de etiq;
i,j,k:vért
principio
{inicialmente la distancia entre dos vértices tiene el valor de la
arista que los une; las diagonales se ponen a cero}
para todo i en vért hacer
para todo j en vért hacer
D[i,j]:=etiqueta(g,i,j) {∞ si no hay arco}
fpara;
D[i,i]:=0
fpara;
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 53


Caminos mínimos entre todos los pares de nodos de un grafo

...
para todo k en vért hacer
para todo i en vért hacer
para todo j en vért hacer
si D[i,k]+D[k,j]<D[i,j] entonces
D[i,j]:=D[i,k]+D[k,j]
fsi
fpara
fpara
fpara;
devuelve D
fin
{Post: D=caminosMínimos(g)}

Ver en la web (material adicional) por qué se puede eliminar el subíndice k de la


ecuación en recurrencias y por tanto evitar el uso de otra matriz.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 54


Caminos mínimos entre todos los pares de nodos de un grafo
• Eficiencia temporal: Θ(n3)
– representación con matriz de adyacencia:
igual que reiterar Dijkstra (Algoritmos voraces, pág. 28), aunque el
interior del bucle en Floyd es más simple
– representación con listas de adyacencia:
reiterando Dijkstra + colas con prioridad está en Θ(anlog n)
• Espacio:
– Floyd exige Θ(n2) mientras que Dijkstra precisa Θ(n)
• Ejercicio: cálculo de las secuencias de nodos que componen los
caminos mínimos
– si el camino mínimo de m a n pasa primero por p y después por q, la
secuencia de vértices que forman el camino mínimo de p a q forma parte
de la secuencia de vértices que forman el camino mínimo de m a n
– usar un vector bidimensional C indexado por vértices: C[v,w] contiene un
nodo u que forma parte del camino mínimo entre v y w
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 55
Árboles binarios de búsqueda óptimos
• Recordar árbol binario de búsqueda:
– La clave de todo nodo es mayor o igual que las de sus descendientes
izquierdos y menor que las de sus descendientes derechos.
• El problema:
– Se tiene un conjunto de claves distintas:
(ordenadas alfab) que deben almacenarse en un árbol binario de búsqueda.
– Se conoce la probabilidad pi, 1≤i≤n, con la que se pide buscar la clave wi
y su información asociada.
– Se conoce también la probabilidad qi, 0≤i≤n, de búsqueda de una clave
inexistente situada entre wi y wi+1 (con el significado obvio para q0 y qn).
– Se tiene que

– Se quiere construir un árbol binario de búsqueda para guardar las claves


que minimice el número medio de comparaciones para encontrar una
clave o para garantizar que no está.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 56
Árboles binarios de búsqueda óptimos
– Recordar que la profundidad de la raíz es 0, la de sus hijos es 1, etc.
– Si construimos un árbol en el que la clave wi está en un nodo de
profundidad di, 1≤i≤n, entonces se necesitan di+1 comparaciones para
encontrarla.
– Si con probabilidad qi, 0≤i≤n, buscamos una clave que no está en el
árbol pero que, en caso de estar, ocuparía un nodo de profundidad di
entonces se necesitan di comparaciones para garantizar que no está.
– Por tanto, el número medio de comparaciones para encontrar una clave
o para garantizar que no está (función que queremos minimizar) es:

Palabra Probabilidad
• Ejemplo: a 0, 22
qi = 0, 0≤ i ≤ 7 al 0,18
ama 0, 20
eso 0,05
si 0, 25
sin 0,02
Algoritmia básica - Javier Campos (Universidad de Zaragoza) su 0,08 57
Árboles binarios de búsqueda óptimos

si
• Solución 1:
eso • Solución 2:
a su
Creada con
estrategia voraz. Árbol perfectamente
ama sin al sin equilibrado.
C=2,43
al eso a ama si su C=2,70

ama
• Solución 3:
a si
Es óptima.

C=2,15 al eso su

sin
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 58
Árboles binarios de búsqueda óptimos
E.N. Gilbert y E.F. Moore: “Variable length encodings”,
Bell System Technical Journal, 38(4), pp. 933-968, 1959.

• Solución de programación dinámica:


Principio de optimalidad:
“Todos los subárboles de un árbol óptimo son
óptimos con respecto a las claves que contienen.”
– Consideremos un subárbol óptimo que contenga las claves wi+1, wi+2, …, wj.
– La probabilidad de que una clave buscada esté o debiera estar en ese subárbol es:
j j
mij = ∑ pk + ∑ qk
k= i + 1 k= i
– Denotemos por Cij el número medio de comparaciones efectuadas en un subárbol
óptimo que contiene las claves wi+1, wi+2, …, wj durante la búsqueda de una clave
en el árbol principal (y convenimos en que Cii=0).
– Supongamos ahora que wk ocupa la raíz de ese subárbol.
– Sea CijK el número medio de comparaciones efectuadas en ese subárbol durante la
búsqueda de una clave en el árbol principal.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 59


Árboles binarios de búsqueda óptimos
– Entonces:

• Ci,k-1 es el nº medio de comparaciones en el subárbol izquierdo.


• Ckj es el nº medio de comparaciones en el subárbol derecho.
• mij es el el nº medio de comparaciones con la raíz.

– Ahora se trata de escoger la raíz de forma que se minimice Cij:

{ }
Cij = mij + min Ci , k − 1 + Ckj , si 0≤ i < j ≤ n
i < k≤ j

Cii = 0, si 0≤ i ≤ n

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 60


Árboles binarios de búsqueda óptimos
• El ejemplo: qi = 0, 0≤ i ≤ 7

Palabra Probabilidad
a 0, 22
al 0,18
ama
eso
0, 20
0,05 { }
Cij = mij + min Ci , k− 1 + Ckj , si 0≤ i < j ≤ n
i < k≤ j
si 0, 25
sin 0,02 Cii = 0, si 0≤ i ≤ n
su 0,08
0 1 2 3 4 5 6 7
0 0 0,22 0,58 1,02 1,17 1,83 1,89 2,15

1 0 0,18 0,56 0,66 1,21 1,27 1,53

2 0 0,20 0,30 0,80 0,84 1,02

3 0 0,05 0,35 0,39 0,57
C= 4º
4 0 0,25 0,29 0,47

5 0 0,02 0,12

6 0 0,08

7 0

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 61


Árboles binarios de búsqueda óptimos
tipos probP=vector[1..n] de real;
probQ=vector[0..n] de real;
matC=vector[0..n,0..n] de real;
matSol=vector[0..n,0..n] de entero

algoritmo abbÓpt(ent p:probP; ent q:probQ; sal C:matC; sal r:matSol)


{C es la matriz definida previamente. En cada componente i,j de r se
guarda el k para el que C[i,j] resulta mínimo.}
variables i,j,k,d:entero; min,aux:real; m:matC
principio
para i:=0 hasta n hacer
C[i,i]:=0; m[i,i]:=q[i];
para j:=i+1 hasta n hacer
m[i,j]:=m[i,j-1]+p[j]+q[j]
fpara
fpara;
para j:=1 hasta n hacer
C[j-1,j]:=m[j-1,j]; r[j-1,j]:=j
fpara;
{Ya están determinados los árboles de 1 nodo.} ...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 62


Árboles binarios de búsqueda óptimos

...
para d:=2 hasta n hacer
para j:=d hasta n hacer
i:=j-d;
min:=maxEntero;
para k:=i+1 hasta j hacer
aux:=C[i,k-1]+C[k,j];
si aux<min entonces
min:=aux;
r[i,j]:=k
fsi
fpara;
C[i,j]:=m[i,j]+min
fpara
fpara
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 63


Árboles binarios de búsqueda óptimos
tipos vectClaves=vector[1..n] de cadena;
árbol=↑nodo;
nodo=registro
dato:cadena;
iz,de:árbol
freg

algoritmo creaABB(ent w:vectClaves; ent r:matSol; sal a:árbol)


algoritmo creaRec(sal a:árbol; ent i,j:entero)
principio
si i=j entonces a:=nil
sino
nuevoDato(a);
a↑.dato:=w[r[i,j]];
creaRec(a↑.iz,i,r[i,j]-1);
creaRec(a↑.de,r[i,j],j)
fsi
fin
principio
creaRec(a,0,n)
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 64


Árboles binarios de búsqueda óptimos
• Complejidad:

Θ(n3), usando Θ(n2) posiciones de memoria.

• Es posible transformar automáticamente ciertos algoritmos


cúbicos de programación dinámica, como este, en algoritmos
cuadráticos…

F.F. Yao: “Efficient dynamic programming using


quadrangle inequalities”,
Proceedings of the 12th Annual ACM Symposium on the
Theory of Computing, pp. 429-435, 1980.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 65


Árboles binarios de búsqueda óptimos
D.E. Knuth: “Optimum binary search trees”,
Acta Informatica, 1, pp. 14-25, 1971.

• En este caso concreto basta con demostrar que:


r[i,j-1] ≤ r[i,j] ≤ r[i+1,j], si j-i≥2

(por inducción en j-i [Knu87, p. 492] D.E. Knuth. El arte de programar


ordenadores. Volumen III: Clasificación y búsqueda. Editorial Reverté, 1987)

Ahora, el coste de los dos bucles internos de abbÓpt es:

∑ (r[i + 1, j ]− r [i , j − 1]+ 1)
d ≤ j ≤n
i = j−d
= r [n − d + 1, n ]− r [0, d − 1]+ n − d + 1< 2n

Por tanto, el coste es Θ(n2).


Algoritmia básica - Javier Campos (Universidad de Zaragoza) 66
Un problema de fiabilidad de sistemas
• El problema:
– Diseñar un sistema compuesto de varios dispositivos conectados en serie.

D1 D2 D3 ••• Dn

– Sea ri la fiabilidad de Di, i.e., la probabilidad de que funcione


correctamente.

– Entonces, la fiabilidad del sistema sistema entero es:


n
∏i = 1ri

– Por ejemplo, si n=10 y ri=0,99, 1≤i≤10, la fiabilidad de cada dispositivo


es muy alta y sin embargo

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 67


Un problema de fiabilidad de sistemas
– Una forma de aumentar la D1 D2 D3 Dn
fiabilidad es replicar los D1 D2 D3 ••• Dn
dispositivos (en paralelo). D1 D3 Dn
D3
Fase 1 Fase 2 Fase 3 Fase n

– Si la fase i contiene mi copias de Di, la


probabilidad de que toda la fase falle es (1 − ri )mi
– Luego la fiabilidad de la fase i es 1 − (1− r i )mi
– Por tanto, si ri=0,99 y mi=2, la fiabilidad de la fase i es 0,9999.
– En realidad, la fiabilidad de la fase i es algo menor que 1 − (1− r i )mi
(las copias de un mismo dispositivo no son completamente
independientes pues su diseño es común, por ejemplo);
si denotamos la fiabilidad de la fase i por φi (mi )
– entonces la fiabilidad del sistema es:
∏1≤i ≤n φi (mi )
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 68
Un problema de fiabilidad de sistemas
– El problema: maximizar la fiabilidad replicando los
dispositivos y con alguna limitación en el coste.

Donde ci es el coste de cada unidad de dispositivo i.


– Como ci>0 y mj≥1, entonces 1≤mi≤ui con

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 69


Un problema de fiabilidad de sistemas
– Una solución óptima m1, m2, …, mn es el resultado de una
secuencia de decisiones, una por cada mi.

– Denotemos:
fi (x) = máximo ∏ φ j (mj )
1≤ j ≤i
sujeto a ∑ cj m j ≤ x
1≤ j ≤i
1≤ mj ≤ u j , 1≤ j ≤ i

Entonces el valor de una solución óptima es fn(c).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 70


Un problema de fiabilidad de sistemas
– La última decisión requiere elegir mn de entre {1,2,3,…,un}.
– Una vez tomada la última decisión, las restantes decisiones deben utilizar
el resto de fondos c – cnmn de forma óptima.
– Se cumple el principio de optimalidad y

f n (c) = max
1 ≤mn ≤u
{
n
φn ( mn ) f n − 1 (c − cn m n ) }

– En general, para fi(x), i≥1, se tiene:

f i (x ) = max
1 ≤ m i ≤ ui
{φ i ( m i ) f i − 1 (x − ci m i ) }
f 0 (x) = 1, para todox , 0≤ x ≤ c

(ver, además, http://webdiis.unizar.es/asignaturas/AB/?p=1292 )


– Se resuelve de forma similar al problema de la mochila 0-1 (ejercicio).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 71


El problema del viajante de comercio
• Recordar:

– Encontrar un recorrido de longitud mínima para un viajante que tiene que


visitar varias ciudades y volver al punto de partida, conocida la distancia
existente entre cada dos ciudades.

– Es decir, dado un grafo dirigido con arcos de ¡Más


vueltas!
longitud no negativa, se trata de encontrar
un circuito de longitud mínima que comience
y termine en el mismo vértice y pase
exactamente una vez por cada uno de los
vértices restantes (circuito hamiltoniano).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 72


El problema del viajante de comercio
– Sean G=(V,A) un grafo orientado,
V={1,2,…,n},
Lij la longitud de (i,j)∈A,
Lij=∞ si no existe el arco (i,j).
– El circuito buscado empieza en el vértice 1.
Se compone de (1,j), con j≠1, seguido de un camino de j a 1 que pasa
exactamente una vez por cada vértice de V \ {1,j}.
– Principio de optimalidad: si el circuito es óptimo, el camino de j a 1 debe
serlo también.
– Sea S⊆V \ {1} un subconjunto de vértices e i∈V \ S un vértice;
llamamos g(i,S) a la longitud del camino mínimo desde i hasta 1 que pase
exactamente una vez por cada vértice de S.
Entonces:
longitud del circuito óptimo = g(1,V \ {1}) =

{ }
= min L1j + g( j ,V \ {1, j })
2≤ j ≤n
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 73
El problema del viajante de comercio
– Más en general, si i≠1, S≠Ø e i∉S:

{ }
g (i ,S) = min Lij + g( j ,S \ { j })
j ∈S
(*)

Además:
g (i ,∅) = Li 1, i = 2,3,…, n

– Método de resolución:
• Usar (*) y calcular g para todos los conjunto S con un solo vértice (distinto
del 1).
• Volver a usar (*) y calcular g para todos los conjuntos S de dos vértices
(distintos del 1) y así sucesivamente.
• Cuando se conoce el valor de g para todos los conjuntos S a los que sólo les
falta un vértice (distinto del 1) basta calcular g(1,V \ {1}).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 74


El problema del viajante de comercio
• Ejemplo. Sea G el grafo completo
de cuatro vértices con longitudes: 0 10 15 20
L = 5 0 9 10
6 13 0 12
8 8 9 0 

– Inicialización:
g(2,Ø) = 5; g(3,Ø) = 6; g(4,Ø) = 8.

Usar
j ∈S
{
g (i ,S) = min Lij + g( j ,S \ { j }) } para obtener:

g(2,{3}) = L23 + g(3,Ø) = 15;


g(2,{4}) = L24 + g(4,Ø) = 18;

g(3,{2}) = 18; g(3,{4}) = 20;


g(4,{2}) = 13; g(4,{3}) = 15.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 75


El problema del viajante de comercio
– Ahora, utilizando de nuevo (*) para conjuntos de dos elementos:
{
g (2,{ 3, 4}) = min L23+ g(3,{4}), L24+ g(4,{3}) = }
= min{29,25} = 25;

{
g (3,{ 2, 4}) = min L32+ g(2,{4}), L24+ g(4,{2}) = }
= min{31,25} = 25;

{
g (4 ,{ 2, 3}) = min L42+ g(2,{3}), L43+ g(3,{2}) =}
= min{23,27} = 23.

– Finalmente:
g (1,{ 2, 3, 4}) = min{ L12+ g(2,{3,4}),
L13+ g(3,{2,4}),
L14 + g(4,{2,3}) } =
= min{ 35,40,43 } = 35.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 76
El problema del viajante de comercio
• Si además se quiere saber cómo se construye el circuito óptimo:
Utilizar una función adicional
J(i,S) es el valor de j que minimiza g(i,S) al aplicar la fórmula (*).
• En el ejemplo:
J(2,{3,4}) = 4; J(3,{2,4}) = 4;
J(4,{2,3}) = 2; J(1,{2,3,4}) = 2.

Y el circuito óptimo será:


1 →J(1,{2,3,4}) = 2
→J(2,{3,4}) = 4
→J(4,{3}) = 3
→1

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 77


El problema del viajante de comercio
• Implementación recursiva ineficiente:
función g(i,S) devuelve nat
variables másCorto,distancia,j:nat
principio
si S=Ø entonces devuelve L[i,1]
sino
másCorto:=∞;
para todo j en S hacer
distancia:=L[i,j]+g(j,S\{j});
si distancia<másCorto entonces
másCorto:=distancia
fsi
fpara;
devuelve másCorto
fsi
fin

Se calcula repetidas veces el mismo valor de g: Ω((n-1)!)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 78


El problema del viajante de comercio
• Utilización de una “función con memoria”:
{se usa una tabla gtab cuyos elementos se inicializan con -1}
función g(i,S) devuelve nat
variables másCorto,distancia,j:nat
principio
si S=Ø entonces devuelve L[i,1]
sino
si gtab[i,S]≥0 entonces devuelve gtab[i,S]
sino
másCorto:=∞;
para todo j en S hacer
distancia:=L[i,j]+g(j,S\{j});
si distancia<másCorto entonces másCorto:=distancia fsi
fpara;
gtab[i,S]:=másCorto;
devuelve másCorto
fsi
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 79


El problema del viajante de comercio
• Coste del algoritmo:
– cálculo de g(j,Ø): n-1 consultas a una tabla,
– cálculo de los g(j,S) tales que 1≤card(S)=k≤n-2:

– cálculo de g(1,V\{1}): n-1 sumas.

 n− 2 
Tiempo de cálculo:
 k= 1

 k  (
Θ  2(n − 1) + ∑ (n − 1)k n − 2  = Θ n22n )
r  
puesto que ∑ k  rk  = r 2r − 1
k= 1

(Este tiempo es mejor que Ω(n!) que resultaría de la estrategia de fuerza


bruta, pero…)
– Coste en espacio (para conservar g y J): Ω(n2n)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 80


El problema del viajante de comercio
• Para hacernos una idea del coste…

número de tiempo tiempo espacio


vértices fuerza bruta prog . dinámica prog . dinámica
n n! n2 2n n2n

5 120 800 160


10 3.628.800 102.400 10.240
Si las unidades
son microsegundos:

menos de 7 minutos 15 1, 31 × 10 12 7.372.800 491.520

20 2, 43 × 10 18 419.430.400 20.971.520
más de 77.000 años
25 1, 55 × 10 25 20.971.520.000 838.860.800

30 2, 65 × 10 32 966.367.641.600 32.212.254.720

50 3, 04 × 10 64 2, 81 × 10 18 5, 62 × 10 16

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 81


Planificación de trabajos
• El problema:
Sea un sistema en el que la realización de un conjunto de trabajos requiere
la ejecución por parte de un conjunto de agentes (o procesadores) de una
serie de tareas diferentes para cada trabajo.
• n trabajos requiriendo cada uno m tareas:
T1i, T2i, …, Tmi, 1≤i≤n
• la tarea Tji la realiza el procesador Pj, 1≤j≤m, y requiere un tiempo tji
• Planificación para los n trabajos:
Es una asignación de tareas a intervalos de tiempo en los procesadores.
• la tarea Tji debe asignarse a Pj
• un procesador no puede tener más de una tarea asignada en cada instante de
tiempo
• para todo trabajo i, el procesamiento de Tji, j>1, no puede empezar hasta que
Tj-1,i haya terminado

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 82


Planificación de trabajos
• Ejemplo:
Se tiene que planificar la ejecución de dos trabajos en tres procesa- 2 0
dores, de forma que los tiempos de cada tarea vienen dados por: T = 3 3
Dos planificaciones posibles: 5 2

(a)

(b)

La planificación (b) se dice no-interruptiva (non-preemptive) porque el


procesamiento de una tarea no se interrumpe hasta que ésta ha terminado.
La planificación (a) se dice interruptiva (preemptive) porque el trabajo 1 se
apropia del procesador 2 antes de que éste termine con el trabajo 2.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 83


Planificación de trabajos
– El tiempo de terminación del trabajo i en la planificación S es el instante,
fi(S), en que todas las tareas del trabajo i han terminado.

En el ejemplo (a), f1(Sa)=10 y f2(Sa)=12.


En el ejemplo (b), f1(Sb)=11 y f2(Sb)=5.

– El tiempo de terminación, f(S), de la planificación S es:

{
F (S) = max fi (S)
1≤i ≤n
}
– El tiempo medio de terminación, MFT(S), se define como:

1
MFT(S) = ∑ fi (S)
n 1≤i ≤n

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 84


Planificación de trabajos
– Planificación con tiempo de terminación óptimo (OFT) para un conjunto
de trabajos:
es una planificación no-interruptiva, S, para la que F(S) es mínimo entre
todas las planificaciones no-interruptivas.
– Planificación interruptiva y con tiempo de terminación óptimo (POFT):
es una planificación interruptiva, S, para la que F(S) es mínimo entre
todas las planificaciones interruptivas.
– Planificación con tiempo medio de terminación óptimo (OMFT):
es una planificación no-interruptiva, S, para la que MFT(S) es mínimo
entre todas las planificaciones no-interruptivas.
– Planificación interruptiva y con tiempo medio de terminación óptimo
(POMFT):
es una planificación interruptiva, S, para la que MFT(S) es mínimo entre
todas las planificaciones interruptivas.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 85


Planificación de trabajos
– El cálculo de OFT y POFT para m>2 y el cálculo de OMFT es
computacionalmente difícil (es NP-duro).
– El cálculo de OFT para m=2 puede hacerse mediante programación
dinámica.
• Caso m=2:
– Denotemos T1i como ai y T2i como bi.
– Una planificación está completamente especificada fijando una
permutación de los trabajos en uno de los procesadores (coincidirá con el
otro procesador).
Cada tarea empezará tan pronto como sea posible.
Ejemplo con 5 trabajos:

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 86


Planificación de trabajos
– Supongamos, para simplificar, que ai≠0, 1≤i≤n
(si hay trabajos con ai=0, se construye primero la planificación óptima
para los trabajos con ai≠0 y después se añaden delante los trabajos con
ai=0).

– Principio de optimalidad:

Una permutación (planificación) óptima es tal que, fijado el primer trabajo


de la permutación, el resto de la permutación es óptimo con respecto al
estado en que quedan los dos procesadores después de terminar el primer
trabajo.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 87


Planificación de trabajos
– Sea g(S,t) la longitud (duración) de una planificación óptima para el
subconjunto de trabajos S suponiendo que el procesador 2 no estará
disponible hasta el instante t.
Entonces:
{ (
g (S, t) = min ai + g S \ {i }, bi + max{t − ai ,0}
i ∈S
)}
con g(Ø,t) = max{t,0} y ai≠0, 1≤i≤n.
caso t≥ai: 0 ai t t+bi
ai aj, j∈S\{i}
bi bj, j∈S\{i}

0 t+bi-ai

caso t<ai: 0 t ai ai+bi

ai aj, j∈S\{i}
bi bj, j∈S\{i}

0 bi
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 88
Planificación de trabajos
– La ecuación recursiva resultante podría resolverse de forma análoga a la
del problema del viajante de comercio, pero existe una solución mejor…
– Supongamos que i y j son los dos primeros trabajos (y en ese orden) en la
planificación óptima del subconjunto S; entonces:

Pero: tij = bj + max{bi + max{t − ai ,0}− aj ,0} =

= bj + bi − aj + max{max{t − ai ,0}, aj − bi } =

= bj + bi − aj + max{t − ai , aj − bi ,0} =

= bj + bi − aj − ai + max{t, ai + aj − bi , ai }

Si los dos primeros trabajos fueran j e i:


g′ (S, t) = aj + ai + g′ (S \ { j , i }, bi + bj − ai − aj + max{t, aj + ai − bj , aj })

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 89


Planificación de trabajos
– Entonces: g (S, t) ≤ g′ (S, t) ⇔
⇔ max{t, ai + aj − bi , ai } ≤ max{t, aj + ai − bj , aj }

Para que esto sea cierto para todo valor de t, se precisa:


max{ai + aj − bi , ai } ≤ max{aj + ai − bj , aj }

Es decir:
ai + aj + max{− bi ,− aj } ≤ aj + ai + max{− bj ,−ai }

O sea:
min{bi ,a j } ≥ min{bj , ai } (*)

– Luego existe una planificación óptima en la que cada par (i,j) de trabajos
adyacentes verifica (*).
– Puede demostrarse que todas las planificaciones que verifican (*) tienen la
misma longitud.
Por tanto, basta generar una permutación para la que se cumpla (*) para
todo par de trabajos adyacentes.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 90
Planificación de trabajos
– Ahora, si

Entonces el trabajo i debería ser el primero en una planificación óptima.


– En cambio, si

Entonces el trabajo j debería ser el último en una planificación óptima.

– Luego podemos decidir la posición de uno de los trabajos (el primero o el


último).
Repitiendo el proceso, se puede construir la planificación óptima.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 91


Planificación de trabajos
• Por tanto la solución es:

i) ordenar los ai y bi en orden no decreciente;

ii) si el siguiente número de la secuencia es ai y el trabajo i no ha sido


planificado todavía, planificar el trabajo i en la posición más a la
izquierda de entre los que restan;
si el siguiente número es bj y el trabajo j no ha sido planificado
todavía, planificar el trabajo j en la posición más a la derecha de entre
los que restan;

(nótese que el algoritmo sirve también si hay trabajos con ai=0)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 92


Planificación de trabajos
• Ejemplo:
– Sean n=4, (a1,a2,a3,a4) = (3,4,8,10) y (b1,b2,b3,b4) = (6,2,9,15).
– La secuencia ordenada de los ai y los bi es:
(b2,a1,a2,b1,a3,b3,a4,b4) = (2,3,4,6,8,9,10,15).

– Sea σ1,σ2,σ3,σ4 la secuencia óptima.


• Como el número menor es b2, entonces σ4=2.
• El siguiente número es a1 luego σ1=1.
• El siguiente es a2 pero el trabajo 2 ya ha sido planificado.
• El siguiente es b1 pero 1 ya ha sido planificado.
• El siguiente es a3 luego hacemos σ2=3.
• Por tanto, σ3=4.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 93


Planificación de trabajos
• Coste: O(n log n)

• Nótese que la solución directa de


{ (
g (S, t) = min ai + g S \ {i }, bi + max{t − ai ,0}
i ∈S
)}

hubiera llevado al menos O(2n), que es el número de


subconjuntos S diferentes para los que habría que calcular g(S,t).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 94


Una competición internacional
• El problema:
Dos equipos A y B se enfrentan un máximo de 2n – 1 veces, ganando el
primer equipo que acumule n victorias.
Supongamos que no es posible un partido nulo, que los resultados de cada
partido son independientes y que hay una probabilidad constante p de que
A gane un partido y q = 1 – p de que lo gane B.
¿Cuál es la probabilidad, a priori, de que gane A?
• El planteamiento:
– Sea P(i,j) la probabilidad de que A gane la competición sabiendo que le
faltan todavía i victorias y a B le faltan j.
– Entonces, antes del primer partido, la probabilidad de que A gane la
competición es P(n,n).
– Si A ya ha acumulado todas las victorias necesarias entonces es el ganador
de la competición, es decir: P(0,j) = 1, 1≤j≤n.
– Igualmente, P(i,0) = 0, para 1≤i≤n.
– La ecuación recurrente es:
P(i,j) = pP(i – 1,j) + qP(i,j – 1), para i,j≥1.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 95


Una competición internacional
• La solución directa:

función P(i,j) devuelve real


{pp (pq) es la probabilidad de que gane A (B)}
principio
si i=0 entonces
devuelve 1
sino
si j=0 entonces
devuelve 0
sino
devuelve pp*P(i-1,j)+pq*P(i,j-1)
fsi
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 96


Una competición internacional
• Coste de la solución directa:
– Sea T(k) el tiempo necesario en el caso peor para calcular P(i,j) con i+j=k.
T (1) = c
T (k) ≤ 2T (k − 1) + d, k > 1

donde c y d son dos constantes.


– Luego, T(k) es O(2k) y por tanto T(2n) es O(22n).
 i + j
– Exactamente el número de llamadas recursivas es 2 −2
 j 

 n
– Por tanto, el tiempo para calcular P(n,n) es Ω( 2 )
 n
y puede demostrarse que  2n 2n
≥2 (2n + 1)
 n

– En definitiva, el tiempo de la solución directa para calcular P(n,n) es


O(4n) y Ω(4n/n).
Puede demostrarse que el tiempo es Θ 4n n ( )
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 97
Una competición internacional
• El problema de la solución directa:
– Como siempre en programación dinámica, se calcula muchas veces el
valor de cada P(i,j).
– Solución mejor: usar una tabla para almacenar los P(i,j).
– Ejemplo (para p = q = 1/2):

1 2 21 32 13 16 15 16 1 4
11 32 1 2 11 16 7 8 1 3 P(i,j) = pP(i-1,j) + qP(i,j-1)
3 16 5 16 1 2 3 4 1 2
j
1 16 1 8 1 4 1 2 1 1
0 0 0 0 0
4 3 2 1 0
i
la matriz se completa, por ejemplo,
por filas (de abajo a arriba, j=0, 1, …, n)
y en cada fila por columnas (de dch. a izq., i=0, 1, …, n)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 98


Una competición internacional
• La solución:

función apuestas(n:natural; p:real) devuelve real


variables tabP:vector[0..n,0..n]de real;
q:real; i,j:natural
principio
q:=1-p;
para j:=1 hasta n hacer
tabP[0,j]:=1; tabP[j,0]:=0;
para i:=1 hasta n hacer
tabP[i,j]:=p*tabP[i-1,j] + q*tabP[i,j-1]
fpara
fpara;
devuelve tabP[n,n]
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 99


Una competición internacional
• Coste:

– En tiempo: Θ(n2)

– En espacio: Θ(n2), aunque se puede reducir fácilmente a Θ(n)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 100


Triangulación de polígonos
• Problema:
(8,26) (15,26)
Dados los vértices de un polígono, v2 v3
se trata de seleccionar un conjunto de
cuerdas (líneas entre vértices no (0,20) v1 v4 (27,21)
adyacentes) de modo que ningún par
de cuerdas se cruce entre sí y que todo v5 (22,12)
(0,10) v0
el polígono quede dividido en
triángulos.
v6 (10,0)

Además, la longitud total de las cuerdas debe ser mínima (triangulación


minimal).
– Utilidad: se puede emplear para sombrear objetos tridimensionales en una
imagen virtual (bidimensional).
– Otra: interpolación numérica de funciones de dos variables.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 101


Triangulación de polígonos
• Resolución de programación dinámica:
– Consideremos un polígono definido por sus vértices v0, v1, …, vn-1.
– Sea Sis el subproblema de tamaño s partiendo del vértice vi, es decir, el
problema de la triangulación minimal del polígono formado por los s
vértices que comienzan en vi y siguen en el sentido de las agujas del reloj
(vi, vi+1, …, vi+s-1), contando con la cuerda (vi,vi+s-1).

v2 v3

v1 v4
S65

v5
v0

v6

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 102


Triangulación de polígonos
– Ahora, para triangular el polígono Sis, hay s – 2 posibilidades:

1. Tomar el vértice vi+1 v2 v3 2. Tomar el vértice vi+s-2


para formar un para formar un triángulo v2 v3
triángulo con S04 con las cuerdas
las cuerdas v1
(vi,vi+s-1) y v1
(vi,vi+s-1) y (vi,vi+s-2) y con el
(vi+1,vi+s-1) y
S65
tercer lado S64 S65
con el tercer v0 (vi+s-2,vi+s-1),
lado (vi,vi+1), y después resolver el v0
y después resolver el subproblema Si,s-1.
subproblema Si+1,s-1. v6
v6

v2 v3
3. Para algún k entre 2 y s-3, S13
tomar el vértice vi+k y formar v1
un triángulo con lados
(vi,vi+k), (vi+k,vi+s-1) y (vi,vi+s-1), S65
S63
y después resolver los
subproblemas Si,k+1 y Si+k,s-k. v0

v6
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 103
Triangulación de polígonos
– Por tanto, si denotamos por Cis el coste de la triangulación Sis,
se obtiene la siguiente relación recursiva:
Cis = min
1≤k ≤s −2
{
Ci , k + 1 + Ci + k , s − k + D(vi ,vi + k ) +
+ D(vi + k ,vi + s − 1 ) }
para 0≤i≤n-1, 4≤s≤n;

donde:
D(vp,vq) es la longitud de la cuerda entre los vértices vp y vq si
vp y vq no son vértices adyacentes en el polígono;
y D(vp,vq) es 0 si vp y vq son adyacentes.

Además, Cis = 0 para 0≤i≤n-1, 2≤s<4.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 104


Triangulación de polígonos
• Solución recursiva inmediata:

– Aplicando la ecuación recurrente anterior


– Problema: el número de llamadas crece exponencialmente con el número
de vértices
– Sin embargo, sin contar el problema original, sólo hay n(n-4)
subproblemas diferentes que hay que resolver
– Por tanto, la solución recursiva resuelve muchas veces un mismo
subproblema

• Solución eficiente:

– Utilización de una tabla para almacenar los costes de las soluciones de los
subproblemas

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 105


Triangulación de polígonos
(1) (8,26) (15,26)
C65 = min{ C62 + C04 + D(v6 ,v0) + D(v0 ,v3), v2 v3
(2)
C63 + C13 + D(v6 ,v1) + D(v1 ,v3),
(3) (0,20) v1 v4 (27,21)
C64 + C23 + D(v6 ,v2) + D(v2 ,v3) } =
= min {38,09 ; 38,52 ; 43,97 } = 38,09
v5 (22,12)
(0,10) v0
C07 =
7
75,43 v6 (10,0)
C06 = C16 = C26 = C36 = C46 = C56= C66 =
6
53,54 55,22 57,58 64,69 59,78 59,78 63,62
C05 = C15 = C25 = C35 = C45 = C55= C65=
5
37,54 31,81 35,49 37,74 45,50 39,98 38,09
(1) C04 = C14 = C24 = C34 = C44 = C54 = C64 = (3)
4
16,16 16,16 15,65 15,65 22,69 22,69 17,89
C03 = C13 = C23= C33= C43= C53 = C63 =
3
0 0 (2) 0 (3) 0 0 0 0 (2)
C02 = C12 = C22= C32= C42= C52 = C62 =
2
0 0 0 0 0 0 0 (1)
s i=0 1 2 3 4 5 6

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 106


Triangulación de polígonos
• Hemos calculado el coste de la triangulación mínima pero,
¿cuál es esa triangulación?

– Para cada posición (i,s) de la tabla se necesita almacenar, además del


coste, el valor del índice k que produjo el mínimo.

– Entonces la solución consta de las cuerdas (vi,vi+k) y (vi+k,vi+s-1)


(a menos que una de ellas no sea cuerda, porque k=1 o k=s-2),
más las cuerdas que estén implicadas por las soluciones de Si,k+1 y Si+k,s-k.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 107


Triangulación de polígonos
• En el ejemplo: v2 v3
– El valor de C07 procede de k=5. Es decir, el problema
S07 se divide en S06 y S53. v1 v4
2 3
2
S53 es un problema trivial, de coste 0.
Así, se introduce la cuerda (v0,v5), de coste 22’09,
v5
y se debe resolver S06. v0
1

v6

– El valor de C06 procede de k=2. Por tanto, el problema se divide en S03 y S24.
S03 es un triángulo con vértices v0, v1 y v2, luego no precisa ser resuelto, mientras
que S24 es un cuadrilátero, definido por v2, v3, v4 y v5, y debe ser resuelto.
Además, hay que incluir los costes de las cuerdas (v0,v2) y (v2,v5), que son 17’89 y
19’80.
– El valor de C24 se obtiene con k=1, dando los subproblemas S22 y S33, que tienen
tamaño menor o igual que tres y, por tanto, coste 0.
Se introduce la cuerda (v3,v5), con coste 15’65.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 108


Búsqueda con retroceso

Algoritmia básica - Javier Campos (Universidad de Zaragoza)


Búsqueda con retroceso
• Introducción 3
• El problema de las ocho reinas 17
• El problema de la suma de subconjuntos 27
• Coloreado de grafos 37
• Ciclos hamiltonianos 45
• Atravesar un laberinto 53
• El recorrido del caballo de ajedrez 57
• El problema de la mochila 0-1 75
• Reconstrucción de puntos a partir de las distancias 86
• Árboles de juego: tic-tac-toe 97

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 2


Búsqueda con retroceso: Introducción
• Problemas que consideraremos:
– Búsqueda de la mejor o del conjunto de todas las soluciones que
satisfacen ciertas condiciones.
– Cada solución es el resultado de una secuencia de decisiones.
– Existe una función objetivo que debe ser satisfecha por cada selección u
optimizada (si sólo queremos la mejor).

– En algunos problemas de este tipo se conoce un criterio óptimo de


selección en cada decisión: técnica voraz.

– En otros problemas se cumple el principio de optimalidad de Bellman y se


puede aplicar la técnica de la programación dinámica.

– Existen otros problemas en los que no hay más remedio que buscar.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 3


Búsqueda con retroceso: Introducción
• Planteamiento del problema:
– Se trata de hallar todas las soluciones que satisfagan un predicado P.
– La solución debe poder expresarse como una tupla (x1,…,xn) donde cada
xi pertenece a un Ci.
n
– Si |Ci|=ti, entonces hay t  ti
i 1

n-tuplas candidatas para satisfacer P.

– Método de fuerza bruta: examinar las t n-tuplas y seleccionar las que


satisfacen P.

– Búsqueda con retroceso (backtracking, en inglés): formar cada tupla de


manera progresiva, elemento a elemento, comprobando para cada
elemento xi añadido a la tupla que (x1,…,xi) puede conducir a una tupla
completa satisfactoria.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 4
Búsqueda con retroceso: Introducción
– Deben existir unas funciones objetivo parciales o
predicados acotadores Pi(x1,…,xi).

Dicen si (x1,…,xi) puede conducir a una solución.

– Diferencia entre fuerza bruta y búsqueda con retroceso:


si se comprueba que (x1,…,xi) no puede conducir a ninguna solución, se
evita formar las ti+1tn tuplas que comienzan por (x1,…,xi)

– Para saber si una n-tupla es solución, suele haber dos tipos de


restricciones:
• explícitas: describen el conjunto Ci de valores que puede tomar xi (todas
las tuplas que satisfacen estas restricciones definen un espacio de
soluciones posibles);
• implícitas: describen las relaciones que deben cumplirse entre los xi
(qué soluciones posibles satisfacen el predicado objetivo P).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 5


Búsqueda con retroceso: Introducción
• Ejemplo: el problema de las ocho reinas
– El problema consiste en colocar ocho reinas en un tablero de ajedrez sin
que se den jaque (dos reinas se dan jaque si comparten fila, columna o
diagonal).
Fuerza bruta: 64
   4.426.165.368
 8 
– Puesto que no puede haber más de una reina por fila, podemos replantear
el problema como:
“colocar una reina en cada fila del tablero de forma que no se den jaque”.
En este caso, para ver si dos reinas se dan jaque basta con ver si
comparten columna o diagonal.

– Por lo tanto, toda solución del problema puede representarse con una
8-tupla (x1,…,x8) en la que xi es la columna en la que se coloca la reina
que está en la fila i del tablero.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 6


Búsqueda con retroceso: Introducción
– Restricciones explícitas: Ci = {1,2,3,4,5,6,7,8}, 1≤i≤8
 El espacio de soluciones consta de 88 8-tuplas (16.777.216 8-tuplas)
– Restricciones implícitas:
no puede haber dos reinas en la misma columna ni en la misma diagonal
– En particular, se deduce que todas las soluciones son permutaciones de la
8-tupla (1,2,3,4,5,6,7,8).
 El espacio de soluciones se
reduce de 88 8-tuplas (16.777.216) a 1 2 3 4 5 6 7 8
8! 8-tuplas (40.320) 1
2
3
4
5
6
7
Una solución: (4,6,8,2,7,1,3,5)
8
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 7
Búsqueda con retroceso: Introducción
• Volviendo al planteamiento general:
– Para facilitar la búsqueda, se adopta una organización en árbol del
espacio de soluciones.
1

• En el ejemplo, para el x1=1 x1=4


x1=2 x1=3
problema de las 2 18 34 50
cuatro reinas x2=2 x2= x2= x2= x2= x2 =
x2= x2=
(en un tablero 44): x2 = 4 1 x2= 4 1 x2= 4 1 x2 = 3
3 3 8 13 19 3 24 29 35 2 40 45 51 2 56 61

x3= 3 4 2 4 2 3 3 4 1 4 1 3 2 4 1 4 1 2 2 3 1 3 1 2

4 6 9 11 14 16 20 22 25 27 30 32 36 38 41 43 46 48 52 54 57 59 62 64

4 4 4 3 3 2
x4= 4 4 3 4 3 2
2
3 2 2 3 1 1 2 1 2 1 1

5 7 10 12 15 17 21 23 26 28 31 33 37 39 42 44 47 49 53 55 58 60 63 65

El espacio de soluciones está definido por todos los


caminos desde la raíz a cada hoja (hay 4! hojas).
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 8
Búsqueda con retroceso: Introducción
• Esquema algorítmico:
– Sea (x1,…,xi) un camino de la raíz hasta un nodo del árbol del espacio de
estados.
– Sea G(x1,…,xi) el conjunto de los valores posibles de xi+1 tales que
(x1,…,xi+1) es un camino hasta un nodo del árbol.
– Suponemos que existe algún predicado acotador A tal que A(x1,…,xi+1) es
falso si el camino (x1,…,xi+1) no puede extenderse para alcanzar un nodo
de respuesta (i.e., una solución).

– Por tanto, los candidatos para xi+1 son los valores de G tales que satisfacen
A.

– Supongamos, finalmente, que existe un predicado R que determina si un


camino (x1,…,xi+1) termina en un nodo respuesta (i.e., es ya una solución).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 9


Búsqueda con retroceso: Introducción
algoritmo buscarSol(ent k:entero; e/s solución:vector[1..n]de elmto)
{Pre: solución[1..k-1] es ‘prometedora’}
variable nodo:elmto
principio
para todo nodo en G(solución,1,k-1) hacer
solución[k]:=nodo;
si A(solución,1,k) entonces
si R(solución,1,k) entonces
guardar(solución,1,k)
fsi;
buscarSol(k+1,solución)
fsi
fpara
fin

...
La llamada inicial es:
buscarSol(1,solución);
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 10


Búsqueda con retroceso: Introducción
• En el ejemplo de las cuatro reinas:

  x1=1 x1=2

     2 18

x2=2 x2=4 x2=1 x2=4


(a) (b) (c) (d) x2=3 x2=3
3 8 13 19 24 29

x3 = 2 4 2 3 1
  
9 11 14 16 30

x4 = 3 3
     
(e) (f) (g) (h) 15 31

(16 nodos frente a


los 65 del árbol completo)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 11


Búsqueda con retroceso: Introducción
• De nuevo, en general:

– Nótese que el árbol no se construye explícitamente sino implícitamente


mediante las llamadas recursivas del algoritmo de búsqueda.

– El algoritmo no hace llamadas recursivas cuando:


• k = n+1, o cuando
• ningún nodo generado por G satisface A.

– Backtracking =

= búsqueda de primero en profundidad y con predicados acotadores

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 12


Búsqueda con retroceso: Introducción
– El algoritmo anterior halla todas las soluciones y además éstas pueden ser de
longitud variable.
• Variantes:
– Limitar el número de soluciones a una sola añadiendo un parámetro booleano de
salida que indique si se ha encontrado una solución.
– Forzar a que sólo los nodos hoja puedan significar solución (realizando la
recursión sólo si no se ha encontrado un nodo solución):
si R(solución,1,k) entonces
guardar(solución,1,k)
sino
buscarSol(k+1,solución)
fsi
– Resolver problemas de optimización: además de la solución actual en
construcción hay que guardar la mejor solución encontrada hasta el momento.
Se mejora la eficiencia de la búsqueda si los predicados acotadores permiten
eliminar los nodos de los que se sabe que no pueden llevar a una solución mejor
que la ahora disponible (poda: métodos de ramificación y poda).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 13


Búsqueda con retroceso: Introducción
• Sobre la eficiencia:
– Depende de:
• el tiempo necesario para generar un elemento solución[k],
• el número de elementos solución que satisfacen las restricciones explícitas G,
• el tiempo de ejecución de los predicados acotadores A, y
• el número de elementos solución[k] que satisfacen los predicados A.
– Mejoras:
• Si se consigue que los predicados acotadores reduzcan mucho el número de
nodos generados (aunque un buen predicado acotador precisa mucho tiempo
de evaluación; compromiso…)
– Si lo reducen a un solo nodo generado (solución voraz): O(n) nodos a
generar en total
– En el peor caso, O(p(n)2n) ó O(p(n)n!), con p(n) un polinomio
• Si es posible: reordenar las selecciones de forma que |C1|<|C2|<<|Cn|, y así
cabe esperar que se explorarán menos caminos.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 14


Búsqueda con retroceso: Introducción
– Estimación a priori del número de nodos generados:
• Idea: generar un camino aleatorio en el árbol del espacio de estados.
• Sea xi el nodo del camino aleatorio en el nivel i y sea mi el número de
hijos de xi que satisfacen el predicado acotador A.
• El siguiente nodo del camino aleatorio se obtiene aleatoriamente de
entre esos mi.
• La generación termina en un nodo de respuesta (solución) o en un
nodo por el que no se puede seguir (ninguno de sus hijos satisfacen el
predicado acotador).
• Si los predicados acotadores son estáticos (no cambian en toda la
búsqueda; esto no es lo habitual; lo habitual es que se hagan cada vez
más restrictivos) y más aún si los nodos de un mismo nivel tienen
todos igual grado, entonces:
El número estimado de nodos que se generará con el algoritmo de
búsqueda con retroceso es:
   1  m 1  m 1m 2  m 1m 2m 3  L…
m
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 15
Búsqueda con retroceso: Introducción
función estimación devuelve entero
variables k,m,r,card:entero; nodo:elmto; sol:vector[1..n]de elmto
principio
k:=1; m:=0; r:=1;
repetir
card:=0;
para todo nodo en G(sol,1,k-1) hacer
sol[k]:=nodo;
si A(sol,1,k) entonces card:=card+1 fsi
fpara;
si card0 entonces
r:=r*card;
m:=m+r;
sol[k]:=eleccAleat(G(sol,1,k-1));
k:=k+1
fsi
hastaQue R(sol,1,k) or (card=0);
devuelve m
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 16


El problema de las ocho reinas
• Consideraremos el problema más general de colocar n reinas en
un tablero de dimensiones nn, sin que se den jaque.

– Cada solución se representa por una n-tupla (x1,…,xn), en la que xi es la


columna de la i-ésima fila en la que se coloca la i-ésima reina.

– El espacio de soluciones se reduce a n! elementos teniendo en cuenta que


todas ellas han de ser permutaciones de (1,2,…,n), es decir, todas las xi
han de ser distintas.

– Además, no deben compartir diagonal.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 17


El problema de las ocho reinas
• Representación de la información
Debe permitir interpretar fácilmente la solución:
x:vector[1..n]de entero;
{x[i]=columna de la reina en i-ésima fila}

• Evaluación del predicado acotador:


– Utilizaremos una función buenSitio que devuelva el valor verdad si la
k-ésima reina se puede colocar en el valor x[k], es decir, si está en
distinta columna y diagonal que las k-1 reinas anteriores.
– Dos reinas están en la misma diagonal  si tienen el mismo valor de
“fila+columna”, mientras que están en la misma diagonal  si tienen el
mismo valor de “fila-columna”.
( f 1  c1  f 2  c2)  ( f 1  c1  f 2  c2)
 (c1  c2  f 1  f 2)  (c1  c2  f 2  f 1)
 c1  c2  f 1  f 2

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 18


El problema de las ocho reinas

funcion buenSitio(k:entero; x:vector[1..n]de entero) devuelve bool


{devuelve verdad si y sólo si se puede colocar una reina en la
fila k y columna x[k], habiendo sido colocadas ya las k-1 reinas
anteriores}
variables i:entero; amenaza:bool
principio
i:=1; amenaza:=falso;
mq (i<k) and not amenaza hacer
si x[i]=x[k] or abs(x[i]-x[k])=abs(i-k) entonces
amenaza:=verdad
sino
i:=i+1
fsi
fmq;
devuelve not amenaza
fin

El coste de la función es O(k-1).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 19


El problema de las ocho reinas
Versión recursiva:
algoritmo colocarReinas(ent k:entero; e/s sol:vector[1..n]de entero)
{sol[1..k-1] están bien colocadas}
variables i:entero
principio
para i:=1 hasta n hacer
sol[k]:=i;
si buenSitio(k,sol) entonces
si k=n entonces escribir(sol)
sino colocarReinas(k+1,sol)
fsi
fsi
fpara
fin

...
colocarReinas(1,sol);
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 20


El problema de las ocho reinas
Versión iterativa:
algoritmo nReinas(ent n:entero)
variables k:entero; x:vector[1..n]de entero
principio
x[1]:=0; k:=1;
mq k>0 hacer {para frenar el último retroceso}
x[k]:=x[k]+1;
mq x[k]n and not buenSitio(k,x) hacer x[k]:=x[k]+1 fmq;
si x[k]n entonces {se ha encontrado un buen sitio}
si k=n entonces {¿es una solución completa?}
escribir(x) {si: escribirla}
sino
k:=k+1; x[k]:=0 {ir a la siguiente fila}
fsi
sino
k:=k-1 {retroceso}
fsi
fmq
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 21


El problema de las ocho reinas
• Estimación del coste:
– Se realizaron cinco evaluaciones de la función estimación, con los
siguientes resultados:

(8,5,4,3,2)1649 (8,6,4,2,1,1,1)1401 (8,5,3,2,2,1,1,1)2329


(8,5,3,1,2,1)749 (8,6,4,3,2)1977

Con cada elección se guarda el número de columnas en que es posible


colocar la reina y a partir de él se calcula el valor que devuelve la función.
Recordar:
   1  m 1  m 1m 2  m 1m 2m 3  L
m …

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 22


El problema de las ocho reinas
– La media para las cinco evaluaciones es 1625.
7  j 
– El nºtotal de nodos del espacio de estados es: 1     (8  i )   69281
j  0 i  0 
– Por tanto, únicamente se recorrería un 2’34% del
número total de nodos (si la estimación es acertada).

( En este caso, la estimación es algo optimista pues se puede comprobar que


el número de nodos explorados es 2057 y, por tanto, se recorre un 2’97%. )
– Número de soluciones para n=8: 92.
– Mejora adicional: observar que algunas
soluciones son simplemente rotaciones
o reflexiones de otras.

Para encontrar soluciones “no equivalentes”,


el algoritmo sólo debe probar con x[1] 2, 3,, n 2
 
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 23
El problema de las ocho reinas
• Para n mayor:
la mejora se hace más considerable.

• Por ejemplo, n=12:


– número de permutaciones: 12! = 479.001.600
– número total de nodos del espacio de estados: 1.302.061.345

– número de nodos explorados: 856.189

se recorre sólo un 0’065%

(se obtiene la primera solución tras visitar 262 nodos)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 24


El problema de las ocho reinas
• Por otra parte:
Se conoce también una solución compacta para el problema
general de las n reinas en un tablero nn (excepto para n=2, n=3,
n=8 y n=9):
– Si n es impar (n=2p-1) y n3 y n9:
• Si n no es múltiplo de 3:
(2k-1,k), 1kp
(2m,m+p), 1mp-1
• Si n es múltiplo de 3 y n3 y n9:
(2k,k), 1kp-1, k4
(2m+1,m+p-1), 1mp-2
(n,4)
(8,n-1)
(1,n)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 25


El problema de las ocho reinas
– Si n es par (n=2p) y n2 y n8:
• Si not(n2 mód 3):
(2k,k), 1kp
(2m-1,m+p), 1mp
• Si n2 mód 3 y n2 y n8:
(2k-1,k), 1kp, k4
(2m,m+p), 1mp-1
(n,4)
(7,n)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 26


El problema de la suma de subconjuntos
• Problema:
– Dados un conjunto W={w1,…,wn} de n números positivos y otro número
positivo M, se trata de encontrar todos los subconjuntos de W cuya suma
es M.

– Ejemplo: si W={11,13,24,7} y M=31, entonces la solución es {11,13,7} y


{24,7}.

• Primera representación de la solución:


– La solución puede representarse simplemente con los índices de los
elementos de W.
– En el ejemplo: (1,2,4) y (3,4).

– En general, todas las soluciones son k-tuplas (x1,x2,…,xk), 1kn.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 27


El problema de la suma de subconjuntos
• Restricciones sobre las soluciones
(para la primera representación):
– Explícitas:

xi  j j es un entero y 1  j  n 
– Implícitas:

i  j  xi  x j
k
 wxi M
i1 (para evitar generar varias
xi  xi  1, 1 i  n instancias de la misma tupla)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 28


El problema de la suma de subconjuntos
• Segunda representación de la solución:
– Cada solución puede representarse con una n-tupla (x1,x2,…,xn), tal que
xi  {0,1}, 1in, de forma que:
• xi = 0 si wi no se elige y
• xi = 1 si wi se elige.
– En el ejemplo anterior: (1,1,0,1) y (0,0,1,1).

• Conclusión:
– Pueden existir varias formas de formular un problema, con distintas
representaciones de las soluciones (aunque siempre verificando éstas un
conjunto de restricciones explícitas e implícitas).

– En el problema que consideramos, ambas representaciones nos llevan a un


espacio de estados que consta de 2n tuplas.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 29


El problema de la suma de subconjuntos
• Arbol del espacio de soluciones (n=4) para la primera
representación (tuplas de tamaño variable):
– Un arco del nivel i al nivel i+1 representa un valor para xi.
– El espacio de soluciones está definido por todos los caminos desde la raíz
hasta cualquier nodo del árbol. 1

x1=1 x1=4
x1=2
x1=3
2 3 4 5

x2=2 x2=3 x2=4


x2=4
x2=3 x =4
2
6 7 8 9 10 11

x3=3 x3=4 x3=4 x3=4


– Los nodos se han numerado
según un recorrido en anchura 12 13 14 15

(utilizando para ello una cola). x4=4

16

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 30


El problema de la suma de subconjuntos
• Arbol del espacio de soluciones (n=4) para la segunda
representación (tuplas de tamaño fijo):
– Los arcos del nivel i al nivel i+1 están etiquetados con el valor de xi (1 ó
0).
– Todos los caminos desde la raíz a una hoja definen el espacio de
soluciones (24 hojas que representan las 16 posibles 4-tuplas).
1
x1=1
– Los nodos están numerados de x1=0

acuerdo con un recorrido de 2 3

“D-búsqueda” (consiste en x2=1 x2=0 x2=1 x2=0


explorar primero el último 18 19 4 5
de los nodos añadido a la
x =1 x3=0 x3=1 x3=0 x3=1 x3=0 x3=1 x3=0
lista de nodos por explorar, 3

es decir, utilizando una pila). 26 27 20 21 12 13 6 7


x4=0 x4=0 x4=0 x4=0 x4=0 x4=0
x4=0 x4=0
x4=1 x4=1 x4=1 x4=1 x4=1
x4=1 x4=1 x4=1
30 31 28 29 24 25 22 23 16 17 14 15 10 11 8 9

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 31


El problema de la suma de subconjuntos
• Estudiemos una solución de búsqueda con retroceso basada en la
segunda representación (tuplas de tamaño fijo).

– El elemento x[i] del vector solución toma el valor 1 ó 0 dependiendo de si


el número w[i] se incluye o no en la solución.

– Generación de los hijos de un nodo:


• para un nodo del nivel i el hijo izquierdo corresponde a x[i]=1 y el derecho a
x[i]=0.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 32


El problema de la suma de subconjuntos
– Función acotadora:
La tupla (x[1],…x[k]) sólo puede conducir a una solución si:
k n
 w[i ] x[i ]  w[i ] M
i =1 i =k+1
Si además se sabe que los w[i] están ordenados de forma no-decreciente,
la tupla (x[1],…x[k]) no puede conducir a una solución si:
k
 w[i ] x[i ]  w[k +1] M
i =1
– Es decir, una función acotadora es:
 
Bk x[1], ,x[k ]  verdad si y sólo si
 k n 
 w [i ] x[i ]   w [i ] M 
i =1 i =k +1 
 k 
  w [i ] x[i ]  w [k  1] M 
i =1 

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 33


El problema de la suma de subconjuntos
algoritmo sumasub(ent s,k,r:entero)
{Encuentra todos los subconjuntos del vector global w cuya suma es M.
Los valores de x[j], que es otro vector global, 1j<k ya han sido
calculados.
n
s= kj=1
-1
w[j]*x[j]; r=  j=k w[j].
Los w[j] están en orden no decreciente. Se asume w[1]M y ni=1 w[i]M.}
principio
{Generación del hijo izquierdo.
Nótese que s+w[k]M porque Bk1(x[1],,x[k-1])=verdad }
x[k]:=1;
si s+w[k]=M entonces {se ha encontrado un subconjunto}
escribir(x[1..k])
sino
si s+w[k]+w[k+1]M entonces {Bk (x[1],,x[k])=verdad}
sumasub(s+w[k],k+1,r-w[k])
fsi
fsi
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 34


El problema de la suma de subconjuntos

...
{Generación del hijo derecho y evaluación de Bk}
si (s+r-w[k]M) and (s+w[k+1]M) entonces {Bk =verdad}
x[k]:=0;
sumasub(s,k+1,r-w[k])
fsi
fin

Nótese que el algoritmo evita calcular


k n
i =1w[ i ]x[ i ] y i =k +1 w[ i ]
cada vez, guardando esos valores en s y r.

La llamada inicial es: ...


n
sumasub(0,1, i =1w[i])
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 35


El problema de la suma de subconjuntos
– Ejemplo: n=6, M=30, W=(5,10,12,13,15,18)
Los rectángulos son s,k,r en cada llamada.
A=(1,1,0,0,1); 0,1,73
B=(1,0,1,1); x[1]=1
C=(0,0,1,0,0,1).
5,2,68 0,2,68
x[2]=1 x[2]=0

15,3,58 5,3,58 10,3,58 0,3,58


x[3]=1 x[3]=0 x[3]=1 x[3]=0

27,4,46 15,4,46 17,4,46 5,4,46 10,4,46 12,4,46 0,4,46


x[4]=0 x[4]=1 x[4]=0
15,5,33 B 5,5,33 10,5,33 12,5,33 13,5,33 0,5,33
Se construyen x[5]=1 x[5]=1
23 nodos A 20,6,18 12,6,18 13,6,18
6
(del total de 2 -1=63)

C
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 36
Coloreado de grafos
• Problema de decisión:
– Dados un grafo G y un número entero positivo m, ¿es G m-coloreable?
– Es decir, ¿se puede pintar con colores los nodos de G de modo que no
haya dos vértices adyacentes con el mismo color y se usen sólo m colores?

• Problema de optimización:
– Dado un grafo G, ¿cuál es su número cromático?
– Es decir, ¿cuál es el menor número m de colores con el que se puede
colorear G?

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 37


Coloreado de grafos
• Un subproblema muy famoso:
– Dado un mapa, ¿pueden pintarse sus 1
regiones (autonomías, países, o lo que 4 5
sea) de tal forma que no haya dos 2 2 3
regiones adyacentes de igual color y 1
no se empleen más de 4 colores? 3
4
5
– Cada región se modela con un nodo y si dos regiones son adyacentes sus
correspondientes nodos se conectan con un arco.
– Así se obtiene siempre un grafo “plano” (puede dibujarse en un plano sin cruzar
sus arcos).
– El mapa de la figura requiere 4 colores.
– Desde hace muchos años se sabía que 5 colores eran suficientes para pintar
cualquier mapa, pero no se había encontrado ningún mapa que requiriera más de
4.
– “Recientemente”, después de varios cientos de años, se demostró que 4 colores
siempre son suficientes.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 38


Coloreado de grafos
• El problema que consideraremos aquí:
– Dado un grafo cualquiera, determinar todas las formas posibles en las que
puede pintarse utilizando no más de m colores.

– Representación elegida: matriz de adyacencias.


tipo grafo = vector[1..n,1..n] de bool

– Justificación de la elección: sólo necesitaremos saber si un arco existe o


no.
– Representación de los colores: enteros de 1 a m.
tipo color = 0..m

– Representación de la solución: vector de colores.


tipo sol = vector[1..n] de color

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 39


Coloreado de grafos
• Espacio de estados para n=3 y m=3.

x[1]=1 x[1]=3
x[1]=2

x[2]=1 x[2]=3
x[2]=2

x[3]=
x[3]=1
3

x[3]
=2

Grado m y altura n.
Cada nodo de nivel i tiene m hijos que corresponden a las m posibles
asignaciones a x[i], 1in.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 40


Coloreado de grafos
• Solución de búsqueda con retroceso:
algoritmo m_coloreado(ent k:entero; e/s x:sol)
{Se usa una variable global g de tipo grafo.
En x se tiene la parte de la solución ya calculada
(es decir, hasta x[k-1]) y k es el índice del
siguiente vértice al que se va a asignar color.}
principio
repetir
{generar todos los colores ‘legales’ para x[k]}
siguienteValor(x,k); {x[k]:=un color legal}
si x[k]0 entonces {se ha encontrado un color legal}
si k=n entonces
escribir(x)
sino m_coloreado(k+1,x)
fsi
fsi
hastaQue x[k]=0
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 41


Coloreado de grafos
algoritmo siguienteValor(e/s x:sol; ent k:entero)
{x[1]x[k-1] tienen colores asociados de forma que todos los
vértices adyacentes tienen distinto color. x[k] tiene el anterior
color para el que se ha probado (0 si no se ha probado con
ninguno). Se calcula el siguiente color para x[k] diferente del de
todos los vértices adyacentes a k (0 si no hay ninguno).}
variables encontrado:booleano; j:entero
principio
repetir
x[k]:=(x[k]+1) mod (m+1); {siguiente color}
si x[k]0 entonces
encontrado:=verdad; j:=1;
mq (jn) and encontrado hacer
si g[k,j] and (x[k]=x[j]) entonces encontrado:=falso
sino j:=j+1
fsi
fmq
fsi
hastaQue (x[k]=0) or encontrado
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 42


Coloreado de grafos
• La llamada inicial es:

...
{g contiene la matriz de adyacencia del grafo}
para i:=1 hasta n hacer
x[i]:=0
fpara;
m_coloreado(1,x);
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 43


Coloreado de grafos
• Cota superior del coste temporal:
– Número de nodos internos del árbol del espacio de estados:
n 1
 m i
i  0
– Coste de ‘siguienteValor’ para cada nodo interno:

O (mn )

– Cota del tiempo total:


n
 m i n  n mn  1  1 m  1  O nm n 
i1

• Recordar que ya vimos una heurística voraz muy eficiente…

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 44


Ciclos hamiltonianos
• Problema: encontrar todos los ciclos hamiltonianos de un grafo.
– Sea G=(V,A) un grafo conexo con n vértices.
– Un ciclo hamiltoniano es un camino que visita una vez cada vértice y
vuelve al vértice inicial.
Es decir, v1v2…vn+1 tal que:

• viV, i=1,…,n+1,

• (vi,vi+1)A, i=1,…,n,

• v1=vn+1,

• vivj, i,j=1,…,n tales que ij.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 45


Ciclos hamiltonianos
• Ejemplos:

1 2 3 4

8 7 6 5

Hamiltoniano: 1-2-8-7-6-5-4-3-1

1 2 3

5 4
No contiene ningún hamiltoniano.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 46


Ciclos hamiltonianos
• No se conoce un algoritmo eficiente para resolver el problema.

• Nótese la relación entre el problema del cálculo de un


hamiltoniano y el problema del viajante de comercio
(para el caso de un grafo con todas las distancias entre vértices
iguales)
– Recordar que ya vimos una heurística voraz muy eficiente pero subóptima
para el problema del viajante de comercio.

– Recordar que vimos también la solución de programación dinámica y


comparamos su eficiencia con la solución de “fuerza bruta”.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 47


Ciclos hamiltonianos
• Solución de búsqueda con retroceso:
– En el vector solución (x1,…,xn), xi representa el vértice visitado en i-ésimo
lugar en el ciclo.

– Cálculo de los posibles valores para xk si x1,…,xk-1 ya tienen valores


asignados:

• k=1: x1 puede ser cualquiera de los n vértices, pero para evitar escribir el
mismo ciclo n veces obligamos que x1=1;

• 1<k<n: xk puede ser cualquier vértice distinto de x1,…,xk-1 y conectado por un


arco con xk-1.

• k=n: xn sólo puede ser el vértice que queda sin visitar y debe estar conectado
por sendos arcos con x1 y xn-1.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 48


Ciclos hamiltonianos
– Representación elegida: matriz de adyacencias.
tipo grafo = vector[1..n,1..n] de bool

– Justificación de la elección: sólo se necesita saber si un arco existe o no.


– Representación de la solución: vector de vértices.
tipo sol = vector[1..n] de 1..n

algoritmo siguienteValor(e/s x:sol; ent k:entero)


{x[1],,x[k-1] es un camino de k-1 vértices distintos.
Si x[k]=0, no se ha asignado ningún vértice todavía a x[k].
Al terminar, x[k] toma el valor del siguiente (en orden
ascendente) vértice tal que:
(1) no aparece ya en x[1],,x[k-1], y
(2) está conectado por un arco a x[k-1].
Además, si k=n, se debe exigir a x[k] que:
(3) está conectado por un arco a x[1].
Si no hay tal vértice, x[k]=0.}
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 49


Ciclos hamiltonianos
...
variables encontrado:booleano; j:entero
principio
repetir
x[k]:=(x[k]+1) mod (n+1);
si x[k]0 entonces
encontrado:=falso;
si g[x[k-1],x[k]] entonces
j:=1; encontrado:=verdad;
mq (jk-1) and encontrado hacer
si x[j]=x[k] entonces encontrado:=falso
sino j:=j+1
fsi
fmq;
si encontrado entonces
si (k=n) and not g[x[n],1] entonces encontrado:=falso fsi
fsi
fsi
fsi
hastaQue (x[k]=0) or encontrado
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 50


Ciclos hamiltonianos
algoritmo hamiltoniano(ent k:entero; e/s x:sol)
{Se usa una variable global g de tipo grafo. Cálculo de los ciclos
hamiltonianos de un grafo mediante búsqueda con retroceso.
En x se tiene la parte de la solución ya calculada
(es decir, hasta x[k-1]) y k es el índice del siguiente vértice
del ciclo que se va a asignar.}
principio
repetir
{generar todos los valores ‘legales’ para x[k]}
siguienteValor(x,k);
si x[k]0 entonces
si k=n entonces
escribir(x,’1’)
sino
hamiltoniano(k+1,x)
fsi
fsi
hastaQue x[k]=0
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 51


Ciclos hamiltonianos
• La llamada inicial es:

...
{g contiene la matriz de adyacencia del grafo}
x[1]:=1;
para i:=2 hasta n hacer
x[i]:=0
fpara;
hamiltoniano(2,x);
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 52


Atravesar un laberinto
• Problema:
– Nos encontramos en una entrada de
un laberinto y debemos intentar
atravesarlo.

– Representación: matriz de dimensión


nn de casillas marcadas como
libre u ocupada por una pared.

– Es posible pasar de una casilla a otra


moviéndose sólamente en vertical u horizontal.

– Se debe ir de la casilla (1,1) a la casilla (n,n).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 53


Atravesar un laberinto
– Diseñaremos un algoritmo  
de búsqueda con retroceso 
de forma que se marcará   
  
en la misma matriz del     
laberinto un camino   
solución (si existe). 

– Si por un camino recorrido 
se llega a una casilla desde   
la que es imposible
encontrar una solución,    
 
hay que volver atrás y  
buscar otro camino.
– Además hay que marcar las casillas
por donde ya se ha pasado para evitar
meterse varias veces en el mismo
callejón sin salida, dar vueltas
alrededor de columnas…
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 54
Atravesar un laberinto
• Estructura de datos:
tipos
casilla = (libre,pared,camino,imposible)
laberinto = vector[1..n,1..n] de casilla

• Solución de búsqueda con retroceso:


algoritmo buscarCamino(e/s lab:laberinto; sal éxito:booleano)
principio
ensayar(1,1,lab,éxito)
fin

algoritmo ensayar(ent x,y:entero; e/s lab:laberinto;


sal encontrado:booleano)
principio
si (x<1)(x>n)(y<1)(y>n) entonces
{posición fuera del laberinto}
encontrado:=falso
sino
si lab[x,y]libre entonces encontrado:=falso
sino
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 55


Atravesar un laberinto

...
lab[x,y]:=camino;
si (x=n)(y=n) entonces {se ha encontrado una solución}
encontrado:=verdad
sino
ensayar(x+1,y,lab,encontrado);
si not encontrado entonces ensayar(x,y+1,lab,encontrado) fsi;
si not encontrado entonces ensayar(x-1,y,lab,encontrado) fsi;
si not encontrado entonces ensayar(x,y-1,lab,encontrado) fsi;
si not encontrado entonces lab[x,y]:=imposible fsi
fsi
fsi
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 56


El recorrido del caballo de ajedrez
• Problema:

– Se trata de encontrar una sucesión de movimientos “legales” de un caballo


de ajedrez de forma que éste pueda visitar todos y cada uno de los
escaques (cuadros) de un tablero sin repetir ninguno.

1 2 3 4 5 6 7 8
1
2
3
4
5
6
7
8

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 57


El recorrido del caballo de ajedrez
– Movimientos “legales”:
6 7
5 8

4 1
3 2

variables dx,dy:vector[1..8] de entero


...
dx:=[2,1,-1,-2,-2,-1,1,2]
dy:=[1,2,2,1,-1,-2,-2,-1]

– Estructura de datos: matriz de naturales


• inicialmente: todos cero
• al terminar: cada componente guarda el número de orden en que se visitó el
escaque correspondiente
variable tab:vector[1..n,1..n] de entero

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 58


El recorrido del caballo de ajedrez
algoritmo ensaya(ent i,x,y:entero; sal éxito:booleano)
{Ensaya el movimiento al i-ésimo escaque desde el x,y. Si el
movimiento es posible y tras él se puede seguir moviendo hasta
encontrar la sol. entonces éxito devuelve verdad, si no, no.}
variables k,u,v:entero
principio
k:=0;
repetir {se ensaya con los 8 mov. posibles}
k:=k+1; éxito:=falso; u:=x+dx[k]; v:=y+dy[k];
si (1u)(un)(1v)(vn) entonces
si tab[u,v]=0 entonces
tab[u,v]:=i;
si i<n*n entonces
ensaya(i+1,u,v,éxito);
si not éxito entonces tab[u,v]:=0 fsi
sino éxito:=verdad
fsi
fsi
fsi
hastaQue éxito or (k=8)
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 59


El recorrido del caballo de ajedrez
algoritmo caballo
constante n=8
variables dx,dy:vector[1..8] de entero;
tab:vector[1..n,1..n] de entero;
i,j:entero; éxito:booleano
principio
dx[1]:=2; dx[2]:=1; dx[3]:=-1; dx[4]:=-2;
dx[5]:=-2; dx[6]:=-1; dx[7]:=1; dx[8]:=2;
dy[1]:=1; dy[2]:=2; dy[3]:=2; dy[4]:=1;
dy[5]:=-1; dy[6]:=-2; dy[7]:=-2; dy[8]:=-1;
para i:=1 hasta n hacer
para j:=1 hasta n hacer
tab[i,j]:=0
fpara;
fpara;
escribir(‘Introduce i inicial:’); leer(i);
escribir(‘Introduce j inicial:’); leer(j);
tab[i,j]:=1;
ensaya(2,i,j,éxito);
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 60


El recorrido del caballo de ajedrez

...
si éxito entonces
para i:=1 hasta n hacer
para j:=1 hasta n hacer
escribir(tab[i,j]);
fpara;
escribirLínea
fpara
sino
escribir(‘No hay solución’)
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 61


El recorrido del caballo de ajedrez
• Resultado de la ejecución:
Introduce i inicial: 1
Introduce j inicial: 1
1 60 39 34 31 18 9 64
38 35 32 61 10 63 30 17
59 2 37 40 33 28 19 8
36 49 42 27 62 11 16 29
43 58 3 50 41 24 7 20
48 51 46 55 26 21 12 15
57 44 53 4 23 14 25 6
52 47 56 45 54 5 22 13

• Inconveniente de esta solución: su ineficiencia


(7’24” en un 68040LC 50/25 MHz)
(se visitan 8.250.733 nodos)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 62


El recorrido del caballo de ajedrez
• Una heurística voraz:
– En cada escaque, seleccionar el siguiente a visitar con la regla:
Se elige aquel escaque no visitado desde el cual se puede acceder a un
menor número de escaques no visitados.

– La heurística se basa en la idea: si ahora tenemos oportunidad de


desplazarnos a un escaque “muy aislado” debemos hacerlo, pues más
adelante será más difícil llegar a él de nuevo.

– El algoritmo resultante no es de búsqueda con retroceso.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 63


El recorrido del caballo de ajedrez

función accesibles(x,y:entero) devuelve entero


{Devuelve el nº de escaques no visitados accesibles desde x,y.}
variables k,u,v,num:entero
principio
num:=0;
para k:=1 hasta 8 hacer
u:=x+dx[k];
v:=y+dy[k];
si (1u)(un)(1v)(vn) entonces
si tab[u,v]=0 entonces
num:=num+1
fsi
fsi
fpara
devuelve num
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 64


El recorrido del caballo de ajedrez

algoritmo caballo
constante n=8
variables dx,dy:vector[1..8] de entero;
tab:vector[1..n,1..n] de entero;
x,y,i,j,k,kk,u,v,num,menor:entero; parar:booleano
principio
dx[1]:=2; dx[2]:=1; dx[3]:=-1; dx[4]:=-2;
dx[5]:=-2; dx[6]:=-1; dx[7]:=1; dx[8]:=2;
dy[1]:=1; dy[2]:=2; dy[3]:=2; dy[4]:=1;
dy[5]:=-1; dy[6]:=-2; dy[7]:=-2; dy[8]:=-1;
para i:=1 hasta n hacer
para j:=1 hasta n hacer
tab[i,j]:=0
fpara;
fpara;
escribir(‘Introduce x inicial:’); leer(x);
escribir(‘Introduce y inicial:’); leer(y);
tab[x,y]:=1; i:=1; parar:=falso;
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 65


El recorrido del caballo de ajedrez

...
mq (i<n*n) and not parar hacer
i:=i+1; menor:=9;
para k:=1 hasta 8 hacer
u:=x+dx[k]; v:=y+dy[k];
si (1u)(un)(1v)(vn) entonces
si tab[u,v]=0 entonces
num:=accesibles(u,v);
si num<menor entonces menor:=num; kk:=k fsi
fsi
fsi
fpara;
si menor=9 entonces
parar:=verdad
sino
x:=x+dx[kk]; y:=y+dy[kk]; tab[x,y]:=i
fsi
fmq;
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 66


El recorrido del caballo de ajedrez

...
si not parar entonces
para i:=1 hasta n hacer
para j:=1 hasta n hacer
escribir(tab[i,j])
fpara;
escribirLínea
fpara
sino
escribir(‘No encuentro solución’)
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 67


El recorrido del caballo de ajedrez
• Resultado de la ejecución:
Introduce x inicial: 1
Introduce y inicial: 1
1 34 3 18 49 32 13 16
4 19 56 33 14 17 50 31
57 2 35 48 55 52 15 12
20 5 60 53 36 47 30 51
41 58 37 46 61 54 11 26
6 21 42 59 38 27 64 29
43 40 23 8 45 62 25 10
22 7 44 39 24 9 28 63

• Mucho más eficiente: (n2)

(menos de 1’’ en el mismo computador, frente a los 7’24” anteriores)


(se visitan 64 nodos, frente a los 8.250.733 de antes)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 68


El recorrido del caballo de ajedrez

• Pero la heurística voraz no funciona en todos los casos:


– Si n=5:
Introduce x inicial: 1
Introduce y inicial: 3
No encuentro solución

(se visitan 17 nodos)


Sin embargo, si se ejecuta el algoritmo de búsqueda con retroceso para
n=5:
Introduce i inicial: 1
Introduce j inicial: 3
25 14 1 8 19
4 9 18 13 2
15 24 3 20 7
10 5 22 17 12
23 16 11 6 21

(se visitan 365.421 nodos)


(18” de ejecución en el mismo computador)
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 69
El recorrido del caballo de ajedrez
• Solución:
– Mejorar el algoritmo de búsqueda con retroceso cambiando el orden de
ensayo de las casillas accesibles desde una dada.
– En lugar de ensayar de forma consecutiva en el sentido de las agujas del
reloj,
• se ensayará en primer lugar la casilla desde la que se pueda acceder al menor
número de casillas no visitadas;
• si desde esa casilla no se llega a una solución, se intentará con la casilla con
siguiente menor número de casillas accesibles no visitadas; etc.
– Para poder implementar el retroceso:
• cada vez que se llegue a una casilla se almacenan los movimientos posibles en
una cola de movimientos con prioridades, donde la prioridad de un
movimiento es el número de casillas accesibles no visitadas tras realizar ese
movimiento

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 70


El recorrido del caballo de ajedrez
• Colas de movimientos con prioridades:
módulo colasMovPri
exporta tipo mov = registro valor:1..8; peso:0..8 freg
{‘valor’ es el mov. según sentido de las agujas del reloj;
‘peso’ es el nº de casillas no visitadas accesibles si se
realiza el movimiento}
función menor(m1,m2:mov) dev booleano
principio
devuelve m1.peso<m2.peso
fin
tipo cmp {tipo opaco: cola de mov. con prioridades; un mov.
m1 tiene prioridad sobre otro m2 si menor(m1,m2)=verdad}
algoritmo creaVacía(sal c:cmp)
algoritmo añadir(e/s c:cmp; ent m:mov)
función min(c:cmp) devuelve mov
algoritmo eliminarMin(e/s c:cmp)
función esVacía(c:cmp) dev booleano
implementación ...
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 71


El recorrido del caballo de ajedrez
algoritmo ensaya(ent i,x,y:entero; sal éxito:booleano)
{...}
variables k,u,v:entero;
m:mov; cola:cmp
principio
{se almacenan los movimientos posibles}
creaVacía(cola);
para k:=1 hasta 8 hacer
u:=x+dx[k]; v:=y+dy[k];
si (1u)(un)(1v)(vn) entonces
si tab[u,v]=0 entonces
m.valor:=k; m.peso:=accesibles(u,v);
añadir(cola,m)
fsi
fsi
fpara;
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 72


El recorrido del caballo de ajedrez
...
{se ensaya por orden de menor a mayor nº de casillas
accesibles no visitadas}
éxito:=falso;
mq not esVacía(cola) and not éxito hacer
m:=min(cola); eliminarMin(cola);
k:=m.valor;
u:=x+dx[k]; v:=y+dy[k];
tab[u,v]:=i;
si i<n*n entonces
ensaya(i+1,u,v,éxito);
si not éxito entonces
tab[u,v]:=0
fsi
sino
éxito:=verdad
fsi
fmq
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 73


El recorrido del caballo de ajedrez
• El algoritmo resultante es mucho más eficiente que el original.

– Y ahora sí encuentra la solución para el caso n=5:

Introduce i inicial: 1
Introduce j inicial: 3
23 6 1 16 21
12 17 22 7 2
5 24 11 20 15
10 13 18 3 8
25 4 9 14 19

(se visitan 1.734 nodos, en menos de un segundo)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 74


El problema de la mochila 0-1
• Recordar…
– Se tienen n objetos y una mochila.
– El objeto i tiene peso pi y la inclusión del objeto i en la mochila produce
un beneficio bi.
maximizar  bi xi
– El objetivo es llenar la mochila, 1 i  n
de capacidad C, de manera que sujeto a  pi xi  C
se maximice el beneficio. 1 i  n

con xi  {0,1}, bi  0, pi  0, 1  i  n

• Soluciones a problemas parecidos:


– Mochila con objetos fraccionables, es decir, 0xi1, 1in:
solución voraz.
– Mochila 0-1 pero siendo los pesos, beneficios y capacidad de la mochila
números naturales: solución de programación dinámica.
Ninguna de las dos soluciones funciona en el caso general de la
mochila 0-1.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 75
El problema de la mochila 0-1
• Espacio de soluciones:
– 2n modos de asignar los valores 0 ó 1 a las xi.
– Dos formas de representar la solución: tuplas de tamaño fijo o variable.

– Tuplas de tamaño variable:


1

x1=4
xi=objeto introducido en i-ésimo lugar x1=1
x1=2
x1=3
2 10 14 16

x2=3 x2=4
x2=2 x2=4
x2=3 x =4
2
3 7 9 11 13 15

x3=3 x3=4 x3=4 x3=4

4 6 8 12

x4=4

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 76


El problema de la mochila 0-1
– Tuplas de tamaño fijo:
xi=0 si el objeto i-ésimo no se introduce
xi=1 si el objeto se introduce
1
x1=0 x1=1

2 17

x2=0 x2=1 x2=0 x2=1

3 10 18 25

x3=0 x3=1 x3=0 x3=1 x3=0 x3=1 x3=0 x3=1

4 7 11 14 19 22 26 29
x4=1 x4=1 x4=1 x4=1 x4=1 x4=1
x4=1 x4=1
x4=0 x4=0 x4=0 x4=0 x4=0
x4=0 x4=0 x4=0
5 6 8 9 12 13 15 16 20 21 23 24 27 28 30 31

Elegimos ésta última representación.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 77


El problema de la mochila 0-1
• Elección de funciones acotadoras:
intentar podar ramas que no puedan producir soluciones mejores
que la disponible actualmente
– se llama “poda basada en el coste de la mejor solución en curso”
– calcular una cota superior del valor de la mejor solución posible al
expandir un nodo y sus descendientes
– si esa cota es menor o igual que el valor de la mejor solución disponible
hasta el momento, no expandir ese nodo
– ¿cómo calcular esa cota superior?
• suponer que en el nodo actual ya se han determinado xi, 1ik;
• relajar el requisito de integridad:
xi{0,1}, k+1in se sustituye por 0xi1, k+1in
• aplicar el algoritmo voraz

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 78


El problema de la mochila 0-1
constante n=... {número de objetos}
tipo vectReal=vector[1..n] de real

{Pre: i1..n:peso[i]>0 
i1..n-1:benef[i]/peso[i]benef[i+1]/peso[i+1]}
función cota(benef,peso:vectReal; cap,ben:real; obj:entero)
devuelve real
{cap=capacidad aún libre de la mochila;
ben=beneficio actual;
obj=índice del primer objeto a considerar}
principio
si obj>n or cap=0.0 entonces devuelve ben
sino
si peso[obj]>cap entonces devuelve ben+cap/peso[obj]*benef[obj]
sino
devuelve cota(benef,peso,cap-peso[obj],ben+benef[obj],obj+1)
fsi
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 79


El problema de la mochila 0-1
tipo solución=vector[1..n] de 0..1

{variables globales: benef,peso:vectReal; cap:real}


algoritmo búsqueda(ent solAct:solución; ent benAct,pesAct:real;
ent obj:entero; e/s sol:solución; e/s ben:real)
variable decisión:0..1
principio
para decisión:=1 descendiendo hasta 0 hacer
solAct[obj]:=decisión;
benAct:=benAct+decisión*benef[obj];
pesAct:=pesAct+decisión*peso[obj];
si pesActcap and ben<cota(benef,peso,cap-pesAct,benAct,obj+1)
entonces
si obj=n entonces
si benAct>ben entonces sol:=solAct; ben:=benAct fsi
sino búsqueda(solAct,benAct,pesAct,obj+1,sol,ben)
fsi
fsi
fpara
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 80


El problema de la mochila 0-1

algoritmo mochila01(ent benef,peso:vectReal;


ent cap:real;
sal sol:solución;
sal ben:real)
variables obj:entero; solAct:solución
principio
para obj:=1 hasta n hacer
solAct[obj]:=0; sol[obj]:=0
fpara;
ben:=0.0;
búsqueda(solAct,0.0,0.0,1,sol,ben)
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 81


El problema de la mochila 0-1
• Ejemplo: 164.88
1 0
– benef=(11,21,31,33,43,53,55,65) 1
155.11
11
1 0
– peso=(1,11,21,23,33,43,45,55)
12 157.44
– cap=110 1
32
0
– n=8 33 159.76
63
1 0 1 0
56 160.22 35
96 65 154.88
1 0 1 0 1 0
89 162.44 66 68 157.11
139 106 108
0 1 0 1 0 157.55 0
164.66 99 109 159.79 159.33
149 159
0 0 1161.63 0 0 0
163.81 101 158 157.63
151
162 160.18
0 0 0 0

139 ben=159
149 151 159 sol=(1,1,1,0,1,1,0,0)
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 82
El problema de la mochila 0-1
– De los 29 – 1 ( = 511) nodos del espacio de estados, sólo se generaron 33.

– Se podía haber reducido a 26 simplemente sustituyendo la condición

ben < cota(...)

en el algoritmo “búsqueda” por:

ben < cota(...)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 83


El problema de la mochila 0-1
• Hasta ahora hemos visto algoritmos de búsqueda con retroceso
basados en árbol de espacio de estados estático.

• Se pueden diseñar algoritmos basados en árboles de espacio de


estados dinámicos.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 84


El problema de la mochila 0-1
• Sol. del pb. de la mochila 0-1 basada en un árbol dinámico:
– Resolver el pb. sin la restricción de integridad (con el algoritmo
voraz): maximizar  bi xi
1 i  n

sujeto a  pi xi C (*)
1 i  n

con 0 xi  1, 1 i  n
• Si la solución es entera (0-1), también es óptima para el problema 0-1.
• Si no es entera, existe exactamente un xi tal que 0<xi<1.
Se parte el espacio de soluciones en dos subespacios: en uno (subárbol
izquierdo) xi=0 y en otro (subárbol derecho) xi=1.
– En general, en cada nodo del árbol, se usa el algoritmo voraz para
resolver el pb. (*) con las restricciones añadidas correspondientes a las
asignaciones ya realizadas a lo largo del camino desde la raíz al nodo.
• Si la solución es entera, ya se tiene el óptimo para ese nodo.
• Si no lo es, existe exactamente un xi tal que 0<xi<1, etc.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 85


Reconstrucción de puntos a partir de las distancias
• Cálculo de las distancias a partir de un conjunto de puntos:
– Se tienen n puntos distintos localizados en el eje x, con coordenadas
x1, x2, …, xn, de forma que x1=0 y que x1< x2< …< xn .
– Esos n puntos determinan m=n(n – 1)/2 distancias d1, d2, …, dm, entre
cada par de puntos (xi – xj, i > j).
– Dado el conjunto de puntos, es fácil construir el conjunto de distancias en
tiempo O(n2).
– Más aún, en tiempo O(n2log n), se puede construir el conjunto de
distancias ordenado.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 86


Reconstrucción de puntos a partir de las distancias
• Problema inverso:
cálculo de las coordenadas de los puntos a partir de las distancias
(si existen).
– Tiene aplicaciones en física y biología molecular.
– No se conoce todavía un algoritmo que lo resuelva en tiempo polinómico.
– El algoritmo que vamos a presentar “parece” comportarse en tiempo
O(n2log n), pero ni se ha demostrado esta conjetura ni se ha encontrado un
contraejemplo.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 87


Reconstrucción de puntos a partir de las distancias
• Veamos un ejemplo: D={1,2,2,2,3,3,3,4,5,5,5,6,7,8,10}
– Como |D| = m = n(n – 1)/2, n = 6.
– Se fija x1=0 (por ejemplo).
– Claramente, x6=10, porque 10 es el máximo de D.

x1=0 x6=10
D={1,2,2,2,3,3,3,4,5,5,5,6,7,8}
– La distancia mayor restante es 8, luego x2=2 ó x5=8. Por simetría, puede
observarse que ambas elecciones dan una misma solución (en realidad,
una da la imagen especular de la otra) o no dan solución. Tomamos x5=8.
– Se borran las distancias x6 – x5 = 2 y x5 – x1 = 8 de D.

x1=0 x5=8 x6=10


D={1,2,2,3,3,3,4,5,5,5,6,7}

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 88


Reconstrucción de puntos a partir de las distancias
– El siguiente valor más grande de D es 7 luego, x4 = 7 ó x2 = 3.
• Si x4 = 7, las distancias x6 – 7 = 3 y x5 – 7 = 1 también deben estar en D.
Lo están.

x1=0 x4=7 x5=8 x6=10


D={2,2,3,3,4,5,5,5,6}

La distancia mayor es ahora 6, así que x3 = 6 ó x2 = 4.


Pero si x3 = 6, entonces x4 – x3 = 1, lo cual es imposible porque 1 ya no está
en D.
Y si x2 = 4, entonces x2 – x1 = 4 y x5 – x2 = 4, lo cual también es imposible
porque 4 sólo aparece una vez en D.

Retroceso...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 89


Reconstrucción de puntos a partir de las distancias
• Si x2=3, las distancias 3 – x1=3 y x5 – 3=5 también deben estar en D. Lo están.

x1=0 x2=3 x5=8 x6=10


D={1,2,2,3,3,4,5,5,6}
Ahora hay que escoger entre x4=6 o x3=4.
x3=4 es imposible porque D sólo tiene una ocurrencia de 4 y harían falta dos.
x4=6 sí es posible.

x1=0 x2=3 x4=6 x5=8 x6=10


D={1,2,3,5,5}
La única elección que queda es x3=5:

x1=0 x2=3 x3=5 x4=6 x5=8 x6=10


D={}

Y se ha llegado a una solución.


Algoritmia básica - Javier Campos (Universidad de Zaragoza) 90
Reconstrucción de puntos a partir de las distancias
– El árbol asociado al proceso anterior es:
x1=0,x6=10

x5=8

x4=7** x2=3

x3=6* x2=4* x3=4* x4=6

x3=5

(*) indica que los puntos elegidos son inconsistentes con las distancias dadas
(**) indica que ese nodo tiene dos nodos imposibles como hijos (luego es un
camino incorrecto)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 91


Reconstrucción de puntos a partir de las distancias
tipos saco = multiconjunto de entero;
sol = vector[1..n] de entero

algoritmo reconstruir(ent D:saco;


sal x:sol; sal éxito:booleano)
{Pre: |D|=n(n-1)/2}
principio
éxito:=falso;
x[1]:=0;
x[n]:=máximo(D);
eliminarMáx(D);
x[n-1]:=máximo(D);
eliminarMáx(D);
si x[n]-x[n-1]D entonces
eliminar(x[n]-x[n-1],D);
colocar(x,D,2,n-2,éxito)
sino
éxito:=falso
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 92


Reconstrucción de puntos a partir de las distancias
algoritmo colocar(e/s x:sol; e/s D:saco; ent iz,de:entero;
sal éxito:booleano)
{Alg. de búsqueda con retroceso para colocar los puntos x[iz]..x[de].
x[1]..x[iz-1] y x[de+1]..x[n] ya se han colocado provisionalmente.}
variable maxD:entero
principio
si D= entonces éxito:=verdad
sino
maxD:=máximo(D); {comprueba si es factible x[de]=maxD}
si |x[j]-maxD|D, 1j<iz, de<jn entonces
x[de]:=maxD; {intenta x[de]=maxD}
para 1j<iz,de<jn hacer eliminar(|x[j]-maxD|,D) fpara;
colocar(x,D,iz,de-1,éxito);
si not éxito entonces {retroceso}
para 1j<iz,de<jn hacer {deshace la eliminación}
insertar(|x[j]-maxD|,D)
fpara
fsi
fsi;
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 93


Reconstrucción de puntos a partir de las distancias
...
{Si falló el primer intento, se intenta ver si x[iz]=x[n]-maxD}
si not éxito and |x[n]-maxD-x[j]|D,  1j<iz,  de<jn entonces
x[iz]:=x[n]-maxD;
para 1j<iz,de<jn hacer
eliminar(|x[n]-maxD-x[j]|,D)
fpara;
colocar(x,D,iz+1,de,éxito);
si not éxito entonces {retroceso}
para 1j<iz,de<jn hacer
{deshace la eliminación}
insertar(|x[n]-maxD-x[j]|,D)
fpara
fsi
fsi
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 94


Reconstrucción de puntos a partir de las distancias
• Análisis de la eficiencia:
– Caso fácil: No se realiza ningún retroceso.

• Hay como máximo O(n2) operaciones de “eliminar” un elemento de D.


En efecto, porque no se realiza ninguna inserción en D e inicialmente tiene
O(n2) elementos.
• Hay como máximo O(n2) operaciones de búsqueda () de un elemento.
En efecto, en cada ejecución de colocar hay como máximo 2n búsquedas y
colocar se ejecuta O(n) veces (si no hay retrocesos).
• Si D se guarda en un árbol AVL, el coste de las operaciones de eliminar y
buscar es O(log n).

el coste es O(n2log n)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 95


Reconstrucción de puntos a partir de las distancias
– En general, ocurren retrocesos, y:
• No se conoce ninguna cota polinómica del número de retrocesos (luego, en
principio, no se conoce ninguna solución polinómica).

Sin embargo:
• ¡ No se conoce ningún ejemplo en el que el número de retrocesos sea mayor
que O(1) !

Luego, es posible que el algoritmo sea O(n2log n).

Por ejemplo, se ha demostrado que si los n puntos se generan de acuerdo


con una distribución uniforme en el intervalo [0,max], con max=(n2),
entonces con probabilidad 1 se efectúa como máximo un retroceso
durante todo el algoritmo.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 96


Árboles de juego: tic-tac-toe
• Estudio de ciertos juegos de estrategia que pueden representarse
mediante árboles:
– cada nodo se corresponde con una configuración posible del juego (por
ejemplo, estado de un tablero), y
– cada arco es una transición legal, o jugada, desde una configuración
posible a una de sus sucesoras.

• Por simplificar, consideremos que:


– hay dos jugadores que juegan alternadamente,
– los dos jugadores están sometidos a las mismas reglas (juego simétrico),
– el azar no interviene (juego determinista),
– una partida no puede durar indefinidamente, y
– ninguna configuración tiene un número infinito de posibles sucesoras.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 97


Árboles de juego: tic-tac-toe
– La configuración inicial del juego es la raíz del árbol correspondiente.

– Las hojas del árbol corresponden a las configuraciones terminales del


juego, en las que no existe jugada siguiente

• bien porque uno de los jugadores ha ganado


• bien porque no ha ganado ninguno (situación de empate)

– Los niveles impares del árbol están asociados con las configuraciones en
las que debe jugar uno de los dos jugadores, mientras que los niveles
pares se asocian a las configuraciones en las que debe jugar el otro.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 98


Árboles de juego: tic-tac-toe
– A cada nodo del árbol se le asocia una etiqueta llamada función de
utilidad.

– Por ejemplo, una función de utilidad habitual toma tres valores posibles:
• “configuración ganadora”,
• “configuración perdedora” y
• “configuración empatadora o nula”.

– Interpretación:
Situación (o posibilidades) que tiene el jugador (tomamos partido por uno
de ellos) en esa configuración, suponiendo que ninguno de los dos
jugadores se equivocará y ambos realizarán en lo sucesivo la mejor jugada
posible.

– La función de utilidad puede asignarse de forma sistemática.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 99


Árboles de juego: tic-tac-toe
• Ejemplo: el juego del tic-tac-toe.
– Una especie de tres nivel 0 0
mueve “yo”
en raya con más de
tres fichas por jugador. • •
•••



– Llamaremos a los dos •
• •
• •

jugadores “él” y “yo”. yo yo


nivel 6
– Supondremos, mueve “yo” él
yo él
él
1

por ejemplo,
que empieza “yo”. yo yo yo yo yo yo yo
nivel 7 yo él 1 yo yo él -1 yo él 0
– El árbol tiene la mueve “él”
él él él él él yo él

forma siguiente: GANA “yo”

yo él yo yo yo yo él yo yo yo
nivel 8 yo yo él 0 yo yo él -1 yo él 0 él yo él 1
mueve “yo” él él él él él él yo él él yo él

GANA “él”

yo él yo yo él yo yo yo yo
nivel 9 yo yo él 0 yo yo él 0 él yo él 1
él yo él él yo él él yo él

EMPATE EMPATE GANA “yo”

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 100


Árboles de juego: tic-tac-toe
• Cálculo de la utilidad:
– Se da valor, en primer lugar, a las hojas:
• la utilidad en una hoja vale 1, 0 ó -1 si la configuración del juego corresponde a una
victoria, empate o derrota, respectivamente, del jugador por el que hemos tomado
partido (“yo”).
– Los valores de la función de utilidad se propagan hacia arriba del árbol de acuerdo
a la siguiente regla (estrategia minimax):
• si un nodo corresponde a una configuración del juego en la que juega “yo” (nivel 0 ó
par), se supone que ese jugador hará la mejor jugada de entre las posibles y, por tanto,
el valor de la función de utilidad en la configuración actual coincide con el valor de esa
función en la configuración de la mejor jugada posible (para “yo”) que se puede
realizar desde la actual (nodo max);
• si un nodo corresponde a una configuración del juego en la que juega “él” (nivel impar
del árbol), se supone que ese jugador hará la mejor jugada de entre las posibles y, por
tanto, el valor de la función de utilidad en la configuración actual coincide con el valor
de esa función en la configuración de la peor jugada posible (para “yo”) (nodo min).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 101


Árboles de juego: tic-tac-toe
– Si la raíz tuviera el valor 1, entonces “yo” tendría una estrategia que le
permitiría ganar siempre
(no es el caso del tic-tac-toe).

– En el tic-tac-toe la función de utilidad de la raíz vale 0 (ningún jugador


tiene una estrategia ganadora):
si no se cometen errores, se puede garantizar al menos un empate.

– Si la raíz tuviera un valor -1, el otro jugador (“él/ella”) tendría una


estrategia ganadora.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 102


Árboles de juego: tic-tac-toe
– La función de utilidad puede tener un rango más amplio (por ejemplo, los
números enteros).
– Ejemplo: Ajedrez
• se ha estimado que el árbol del juego tiene más de 10100 nodos
• si un computador pudiera generar 1011 nodos por segundo, necesitaría más de
1080 años para construirlo
• es imposible dar valor a la función de utilidad de cada nodo de abajo hacia
arriba (como en el caso del tic-tac-toe)
• para cada configuración actual del juego, se toma dicha configuración como
raíz del árbol
• se construyen varios niveles del árbol (el número depende de la velocidad del
computador o puede ser seleccionado por el usuario)
• la mayor parte de las hojas del árbol construido son ambiguas (no indican
triunfos, derrotas ni empates)
• la función de utilidad de las posiciones del tablero intenta estimar la
probabilidad de que el computador gane desde esa posición

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 103


Árboles de juego: tic-tac-toe
• Implementación (±) detallada:

– representación de una configuración del juego (definición del tipo de dato


configuración)

– enumeración de las configuraciones accesibles desde una dada mediante


la ejecución de una jugada, y

– cálculo de la función de utilidad para una configuración dada, sabiendo


quién juega en ese momento

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 104


Árboles de juego: tic-tac-toe
algoritmo juegaElComputador(e/s c:config)
{c es una configuración no final; el alg. realiza la mejor jugada
posible a partir de c, la comunica al usuario y actualiza c}
variables maxUtilidad,laUtilidad:entero; i:1..maxEntero;
mejorJugada,unaJugada:config
principio
i:=1; {cálculo de la 1ª config. accesible desde c}
jugada(c,i,unaJugada);
mejorJugada:=unaJugada;
maxUtilidad:=utilidad(mejorJugada,falso);
{"falso" -> cuando la config. sea "mejorJugada", no juego yo}
mq not esLaUltimaJugada(c,i) hacer
i:=i+1;
jugada(c,i,unaJugada);
laUtilidad:=utilidad(unaJugada,falso);
si laUtilidad>maxUtilidad entonces
mejorJugada:=unaJugada; maxUtilidad:=laUtilidad
fsi
fmq;
comunicaAlUsuario(mejorJugada); c:=mejorJugada
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 105


Árboles de juego: tic-tac-toe
algoritmo jugada(ent c:config; ent i:1..maxEntero;
sal unaJugada:config)
{Pre: c admite al menos i jugadas diferentes.}
{Post: unaJugada es la i-ésima jugada posible desde c.}
...
función esLaÚltimaJug(c:config; i:0..maxEntero)
devuelve booleano
{Devuelve verdad si y sólo si c admite exactamente i jugadas
diferentes.}
...
algoritmo comunicaAlUsuario(ent c:config)
{Muestra en pantalla la configuración c.}
...
función utilidadFinal(c:config) devuelve entero
{Pre: c es una configuración final del juego.}
{Post: devuelve la utilidad de c.}
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 106


Árboles de juego: tic-tac-toe

función utilidad(c:config; juegoYo:booleano)


devuelve entero
{Calcula la utilidad de c teniendo en cuenta quién juega.}
variables laUtilidad:entero;
i:1..maxEntero;
unaJugada:config
principio
si esLaUltimaJug(c,0) entonces
devuelve utilidadFinal(c)
sino
i:=1;
jugada(c,i,unaJugada);
laUtilidad:=utilidad(unaJugada,not juegoYo);
...

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 107


Árboles de juego: tic-tac-toe

...
mq not esLaUltimaJug(c,i) hacer
i:=i+1;
jugada(c,i,unaJugada);
si juegoYo entonces
laUtilidad:=max(laUtilidad,utilidad(unaJugada,falso))
sino
laUtilidad:=min(laUtilidad,utilidad(unaJugada,verdad))
fsi
fmq;
devuelve laUtilidad
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 108


Árboles de juego: tic-tac-toe
• Sobre el tamaño del árbol:
– Si empieza el computador, se examinan 97.162 nodos.
– Si el computador juega en segundo lugar:
• se examinan 5.185, si el jugador humano colocó primero en el centro,
• se examinan 9.761, si el humano colocó en una esquina,
• se examinan 13.233, si el humano colocó en una casilla que no es ni el centro
ni una esquina.
• Se precisan métodos para evaluar menos nodos sin perder
información…
• El más conocido es el método de “poda ”

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 109


Árboles de juego: tic-tac-toe
• Poda :

nodo max n ≥20

nodo min c1 20 c2 ≤15 c3

d
15

– Una vez que se encuentra el descendiente d de c2, no es necesario seguir


calculando descendientes de c2 (porque c2 es un nodo “min”, tendrá un
valor menor o igual a 15, y su padre es “max” y ya tiene un valor mayor o
igual a 20).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 110


Árboles de juego: tic-tac-toe
• Poda :

nodo min n ≤44

nodo max c1 44 c2 ≥68 c3

– Una vez que se encuentra el descendiente d de c2, no es necesario seguir


calculando descendientes de c2 (porque c2 es un nodo “max”, tendrá un
valor mayor o igual a 68, y su padre es “min” y ya tiene un valor menor o
igual a 44).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 111


Árboles de juego: tic-tac-toe
• Resultados prácticos:

– La poda  restringe la búsqueda a O( n ) nodos (si el número original


es n).

– Este ahorro es muy grande y supone que las búsquedas que usan la poda
 pueden ir al doble de la profundidad en comparación con un árbol no
podado.

– En el ejemplo del tic-tac-toe, el número inicial de 97.162 nodos se reduce


a 4.493.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 112


Ramificación y poda

Algoritmia básica - Javier Campos (Universidad de Zaragoza)


Ramificación y poda
• Introducción: (1) Ramificación… 3
• Un primer ejemplo: El juego del 15 8
• Aplicación a problemas de optimización 20
• Introducción: (2) … y poda 25
• Un problema de planificación de tareas a plazo fijo 29
• El problema de la mochila 0-1 44
• El problema del viajante de comercio 56
• Consideraciones finales sobre eficiencia 74

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 2


Introducción: (1) Ramificación…
• Al igual que los métodos de búsqueda con retroceso:
– se aplica a problemas de optimización con restricciones,
– se genera el espacio de soluciones, organizándolo en un árbol
(en general en un grafo),
– no se genera el espacio de soluciones completo, sino que se podan
bastantes estados.
• Terminología:
– Nodo vivo: nodo del espacio de soluciones del que no se han generado
aún todos sus hijos.
– Nodo muerto: nodo del que no se van a generar más hijos porque:
• no hay más
• no es completable, i.e., viola las restricciones
• no producirá una solución mejor que la solución en curso
– Nodo en curso (o en expansión): nodo del que se están generando hijos

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 3


Introducción: (1) Ramificación…
• Diferencia fundamental con el método de búsqueda con
retroceso:
– Búsqueda con retroceso: Tan pronto como se genera un nuevo hijo del
nodo en curso, este hijo pasa a ser el nodo en curso.
– Ramificación y acotación: Se generan todos los hijos del nodo en curso
antes de que cualquier otro nodo vivo pase a ser el nuevo nodo en curso.
• En consecuencia:
– Búsqueda con retroceso:
Los únicos nodos vivos son los que están en el camino de la raíz al nodo
en curso.
– Ramificación y acotación:
Puede haber más nodos vivos.
Se deben almacenar en una estructura de datos auxiliar:
lista de nodos vivos.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 4


Introducción: (1) Ramificación…
• Diferentes estrategias de Distintos órdenes de
elegir el siguiente nodo ⇒ recorrido del árbol de
de la lista de nodos vivos soluciones

– FIFO: la lista de nodos vivos es una cola


⇒ recorrido por niveles (en anchura)
– LIFO: la lista de nodos vivos es una pila
⇒ ≈ recorr. en profundidad (D–búsqueda)

– Mínimo coste: la lista es una cola con prioridades


⇒ recorrido “extraño”

La prioridad de un nodo se calcula de acuerdo con una función de


estimación que mide cuánto de “prometedor” es un nodo.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 5
Introducción: (1) Ramificación…
• Primer punto clave de los métodos de ramificación y poda:

Encontrar un buen orden de recorrido (o ramificación) de los


nodos,

es decir,

definir una buena función de prioridad de los nodos vivos,

para que las soluciones buenas se encuentren rápidamente.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 6


Introducción: (1) Ramificación…
• El esquema es el siguiente:
repetir
expandir el nodo vivo más prometedor;
generar todos sus hijos;
una vez generados, el padre se mata;
para cada hijo hacer
si tiene un coste esperado peor que
el de la mejor solución en curso
entonces se mata
sino_si tiene un coste esperado mejor que el de la
mejor solución en curso y no es solución
entonces se pasa a la lista de nodos vivos
sino {tiene un coste esperado mejor que el de la mejor
solución en curso y es solución (el coste no es
estimado sino real)}
pasa a ser la mejor solución en curso y se revisa toda la
lista de nodos vivos, eliminando los que prometen algo peor
de lo conseguido
fsi
fpara
hasta que la lista está vacía
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 7
Un primer ejemplo: El juego del 15
Samuel Loyd: El juego del 15 o “taken”.
Problema publicado en un periódico de Nueva York
en 1878 y por cuya solución se ofrecieron 1000 dólares.

• El problema original:
1 2 3 4 1 2 3 4
5 6 7 8
? 5 6 7 8
9 10 11 12 9 10 11 12
13 15 14 13 14 15

Problema de Loyd El objetivo


• La solución de “fuerza bruta”:
– Buscar en el espacio de estados (es decir en todos los estados posibles
alcanzados desde el problema propuesto) hasta encontrar el objetivo.
– Nótese que hay 16! ≈ 20’9×1012 posiciones,
aunque sólo (?) la mitad pueden alcanzarse desde la posición inicial
propuesta por Lloyd…
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 8
Un primer ejemplo: El juego del 15
• ¿Qué estados son alcanzables?
– Numeremos las casillas de 1 a 16.
– Dada una configuración o estado, sea Pos(i) la posición (entre 1 y 15) de
la ficha con el nº i, y sea Pos(16) la posición de la casilla vacía.
– Dado un estado, para cada ficha i, sea m(i) el número de fichas j tales que
j<i y Pos(j)>Pos(i).
m(i)=0, i=1,2,3,4,5,6,7
1 2 3 4 m(8)=m(9)=m(10)=1
5 6 8 m(11)=0
9 10 7 11 m(12)=0
m(13)=m(14)=m(15)=1
13 14 15 12
m(16)=9

– Dado un estado, sea x=1 si


la casilla vacía está en alguna
de las posiciones sombreadas
y x=0 en caso contrario.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 9
Un primer ejemplo: El juego del 15
• Teorema. El estado objetivo es alcanzable desde un cierto
estado si para ese estado:

16
∑ m(i) + x es par
i =1

– Para el ejemplo anterior, dicha función vale 16, luego el estado objetivo es
alcanzable.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 10


Un primer ejemplo: El juego del 15
– Hijos de cada nodo = movimientos de la casilla vacía (arriba, abajo,
izquierda, derecha)
– poda inicial: ningún nodo
tiene un hijo igual a su padre 1 1 2 3 4
5 6 8
9 10 7 11
13 14 15 12
↑ ←
→ ↓
1 2 4 1 2 3 4 1 2 3 4 1 2 3 4
2 5 6 3 8 3 5 6 8 4 5 6 7 8 5 5 6 8
9 10 7 11 9 10 7 11 9 10 11 9 10 7 11
13 14 15 12 13 14 15 12 13 14 15 12 13 14 15 12

6 → ←7 8 ↑ ↓ 9 10 → 11 ↓ ← 12 13 ↑ 14 ↓ ← 15
1 2 4 1 2 4 1 2 3 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 3 4 1 2 3 4 1 2 3 4
5 6 3 8 5 6 3 8 5 6 8 4 5 6 8 11 5 6 7 8 5 6 7 8 5 6 7 8 5 2 6 8 5 10 6 8 5 6 8
9 10 7 11 9 10 7 11 9 10 7 11 9 10 7 9 10 11 9 10 15 11 9 10 11 9 10 7 11 9 7 11 9 10 7 11
13 14 15 12 13 14 15 12 13 14 15 12 13 14 15 12 13 14 15 12 13 14 12 13 14 15 12 13 14 15 12 13 14 15 12 13 14 15 12

16 ↓ 19 ← ↓ ← 22 ↑ ↓ 23
1 2 4 8 ↓ ← 1 2 3 1 2 3 4 1 2 3 4
5 6 3 5 6 8 4 5 6 7 5 6 7 8
9 10 7 11 9 10 7 11 9 10 11 8 9 10 11 12
13 14 15 12 13 14 15 12 13 14 15 12 13 14 15

18 20 21 objetivo
17 1 6 2 4 1 2 4 1 2 3 4 1 2 3 4
5 3 8 5 6 3 8 5 6 8 11 5 6 8 11
9 10 7 11 9 10 7 11 9 10 7 12 9 10 7
13 14 15 12 13 14 15 12 13 14 15 13 14 15 12

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 11


Un primer ejemplo: El juego del 15
• Estrategias ciegas de elección del siguiente nodo en la lista de nodos vivos:
– FIFO = recorrido por niveles o en anchura
• tal como aparecen numerados en la figura
• relativamente útil si el nodo solución está cerca de la raíz
– Recorrido en profundidad
• orden de los 1 2 3 4 5 6
movimientos: 1 2 3 4
5 6 8
↑ 1 2
5 6 3 8
4
→ 1 2
5 6
4
3 8
↓ 1 2
5 6
4 8
3
↓ 1 2
5 6
4 8
3 11 ↓ 1 2
5 6
4 8
3 11
↑→↓← 9 10 7 11 9 10 7 11 9 10 7 11 9 10 7 11 9 10 7 9 10 7 12
13 14 15 12 13 14 15 12 13 14 15 12 13 14 15 12 13 14 15 12 13 14 15

12 11 10 9 8 7 ←
1 2 8 11 1 2 8 1 2 8 1 2 4 8 1 2 4 8 1 2 4 8
5 6 4 5 6 4 11 5 6 4 11 5 6 11 5 6 3 11 5 6 3 11
9 10 3 12 9 10 3 12 9 10 3 12 9 10 3 12 9 10 12 9 10 7 12
13 14 7 15
↓ 13 14 7 15 → 13 14 7 15 ↑ 13 14 7 15 ↑ 13 14 7 15 ↑ 13 14 15


• sigue la rama izquierda del árbol
• no encuentra nunca la solución (a menos que exista una solución en esa rama)
– LIFO = D-búsqueda
• problemas similares al recorrido en profundidad
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 12
Un primer ejemplo: El juego del 15
• Estrategias no ciegas

– en inteligencia artificial  estrategias informadas


– también se llaman técnicas de investigación de operaciones

– Supongamos que fuese posible calcular la siguiente función para cada


nodo x del árbol:

c(x) = longitud desde la raíz hasta el estado objetivo más cercano que es
descendiente de x

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 13


Un primer ejemplo: El juego del 15
1 1
5
2 3 4
6 8 c(1)=3
9 10 7 11
13 14 15 12
↑ ←
→ ↓
1 2 4 1 2 3 4 1 2 3 4 1 2 3 4
2 3 4 5
5
9
6 3 8
10 7 11
5
9
6
10
8
7 11
5
9
6 7 8
10 11
c(4)=3 5 6 8
9 10 7 11
13 14 15 12 13 14 15 12 c(10)=3 13 14 15 12 13 14 15 12

6 → ←7 8 ↑ ↓ 9 10 → 11 ↓ ← 12 13 ↑ 14 ↓ ← 15
1 2 4 1 2 4 1 2 3 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 3 4 1 2 3 4 1 2 3 4
5 6 3 8 5 6 3 8 5 6 8 4 5 6 8 11 5 6 7 8 5 6 7 8 5 6 7 8 5 2 6 8 5 10 6 8 5 6 8
9 10 7 11 9 10 7 11 9 10 7 11 9 10 7 9 10 11 9 10 15 11 9 10 11 9 10 7 11 9 7 11 9 10 7 11
13 14 15 12 13 14 15 12 13 14 15 12 13 14 15 12 13 14 15 12 13 14 12 13 14 15 12 13 14 15 12 13 14 15 12 13 14 15 12

16 ↓ 19 ← ↓ ← 22 ↑ ↓ 23
1 2 4 8 ↓ ← 1 2 3 1 2 3 4 1 2 3 4 – Método:
5 6 3 5 6 8 4 5 6 7 5 6 7 8
9
13
10
14
7 11
15 12
9
13
10 7 11
14 15 12
9
13
10
14
11 8
15 12
9
13
10
14
11 12
15
c(23)=3 • la raíz es el nodo en curso
• generar sus hijos hasta encontrar uno
18 20 21 objetivo
17 1 6 2 4 1 2 4 1 2 3 4 1 2 3 4 con igual valor de c que él (en el
5 3 8 5 6 3 8 5 6 8 11 5 6 8 11
9 10 7 11 9 10 7 11 9 10 7 12 9 10 7
ejemplo, 4)
13 14 15 12 13 14 15 12 13 14 15 13 14 15 12
• repetir lo mismo (en el ejemplo, 10)
• hasta encontrar el objetivo (en el
ejemplo, 23)
Los únicos nodos en curso son los del
camino desde la raíz hasta la solución
más cercana.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 14
Un primer ejemplo: El juego del 15
– Problema: el cálculo de la función c.
– Un ejemplo de problemas en los que es posible: aquéllos en los que hay
soluciones voraces.
– En general, usar una función de estimación: cˆ (x) = f (x) + gˆ (x),
con f(x) = longitud del camino de la raíz a x
y gˆ (x) = estimación de la longitud del camino desde x hasta la
solución más cercana

– cˆ (x) es una función heurística; debe ser:


• fácil de calcular
• si x es una hoja o una solución: c(x) = cˆ (x)
– Por ejemplo, en el juego del 15:
gˆ (x) = nº de casillas no vacías que no están en su sitio objetivo
(cˆ (x) ≤ c(x), ∀x)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 15


Un primer ejemplo: El juego del 15
• Estrategia de mínimo coste con ˆc(x)
– La lista de nodos vivos es una cola de nodos x con prioridades cˆ (x)
– En el ejemplo: 1 15 26 3 48
9 10 7 11
cˆ (1) = 0 + 3
13 14 15 12

– Se generan sus hijos y se


añaden en la cola: 2 15 2
6 3 8
4
3
1
5
2
6
3 4
8 4
1
5
2 3 4
6 7 8 5
1 2 3 4
5 6 8
9 10 7 11 9 10 7 11 9 10 11 9 10 7 11
13 14 15 12 13 14 15 12 13 14 15 12 13 14 15 12

cˆ (2) = 1 + 4 cˆ (3) = 1 + 4 cˆ (4) = 1 + 2 cˆ (5) = 1 + 4


– Se elige el mínimo, el 4, se elimina 2 1 2 4 1 2 3 4
5
1 2 3 4
5 6 3 8 3 5 6 8 5 6 8
de la cola y se generan sus hijos: 9 10 7 11 9 10 7 11 9 10 7 11
13 14 15 12 13 14 15 12 13 14 15 12

cˆ (2) = 1 + 4 cˆ (3) = 1 + 4 cˆ (5) = 1 + 4

10 1 2 3 4 11 1 2 3 4
12 1 2 3 4
5 6 7 8 5 6 7 8 5 6 7 8
9 10 11 9 10 15 11 9 10 11
13 14 15 12 13 14 12 13 14 15 12

cˆ (10) = 2 + 1 cˆ (11) = 2 + 3 cˆ (12) = 2 + 3


Algoritmia básica - Javier Campos (Universidad de Zaragoza) 16
Un primer ejemplo: El juego del 15
– Se elige el mínimo, el 10, se elimina de la cola y se añaden sus hijos:

2 1 2 4
3
1 2 3 4
5
1 2 3 4
11 1 2 3 4
5 6 3 8 5 6 8 5 6 8 5 6 7 8
9 10 7 11 9 10 7 11 9 10 7 11 9 10 15 11
13 14 15 12 13 14 15 12 13 14 15 12 13 14 12

cˆ (2) = 1 + 4 cˆ (3) = 1 + 4 cˆ (5) = 1 + 4 cˆ (11) = 2 + 3

12 1 2 3 4
5 6 7 8
22 1
5
2
6
3 4
7
23 1
5
2
6
3 4
7 8
9 10 11 9 10 11 8 9 10 11 12
13 14 15 12 13 14 15 12 13 14 15

cˆ (12) = 2 + 3 cˆ (22) = 3 + 2 cˆ (23) = 3 + 0

– El nodo 23 es el objetivo y termina la búsqueda.


– En este caso, el método es casi (hay que almacenar la cola con
prioridades) tan eficiente como si se hubiera utilizado c(x).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 17


Un primer ejemplo: El juego del 15
algoritmo mínimoCoste(ent x0:nodo)
variables c:cola; {cola con prioridades de <x,coste(x)>}
éxito:booleano; xcurso,x:nodo
principio
si esSol(x0) entonces escribir(x0)
sino
creaVacía(c); {cola de nodos vivos}
añadir(c,<x0,coste(x0)>);
éxito:=falso;
mq not éxito and not esVacía(c) hacer
xcurso:=min(c); {nodo en curso}
eliminarMin(c);
mq not éxito and hay otro hijo x de xcurso hacer
si esSol(x) entonces escribir(x); éxito:=verdad
sino añadir(c,<x,coste(x)>)
fsi
fmq
fmq;
si not éxito entonces escribir(“No hay solución”) fsi
fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 18


Un primer ejemplo: El juego del 15
– Comentarios al esquema algorítmico anterior:
• Si se desea escribir todo el camino desde la raíz hasta la solución,
cada vez que se añade un nodo a la cola, hay que guardar en una tabla
auxiliar de padres de nodos ese nodo junto a su padre.
• La terminación del algoritmo sólo está garantizada si el espacio de
estados es finito.
• Si el espacio de estados es infinito y existe al menos una solución, se
puede garantizar la terminación con una elección adecuada de la
función de estimación.
• Si el espacio de estados es infinito y no hay solución, el algoritmo no
termina…
– Se suele restringir la búsqueda a nodos con coste estimado menor
que C.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 19


Aplicación a problemas de optimización
• Problemas de optimización:
– Ahora la función o coste a minimizar ya no es la distancia de la raíz a la
solución, sino una cierta función objetivo dada
– ¿Qué ocurre si interesa buscar una
solución de coste mínimo? c 10
cˆ 0
¿Encuentra el algoritmo esa solución?
20 10
No.
2 4
20 ∞ ∞ 10
Se expande la raíz, sus hijos se añaden
20 ∞ ∞ 10
a la cola de nodos vivos, se elige el hijo
izquierdo, se expande y se obtiene una
nodos solución
solución de coste 20
(cuando la solución óptima tiene coste 10).
¿Por qué?
Porque ∃x , y: cˆ (x) < cˆ (y) ∧ c(x) > c(y)
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 20
Aplicación a problemas de optimización
– Teorema. Si para cada nodo x del árbol del espacio de estados cˆ (x) es una
estimación de c(x) tal que para todo par de nodos y, z:

cˆ (y) < cˆ (z) ⇔ c(y) < c(z)

entonces el algoritmo mínimoCoste termina y encuentra siempre una


solución de mínimo coste.

– Problema: no es fácil encontrar una función de estimación con tales


características y fácil de calcular.
– Conformarse con…
Una función cˆ (x) fácil de calcular y tal que para todo nodo x: cˆ (x) ≤ c(x)
y para cada solución:
cˆ (x) = c(x)

En este caso, el algoritmo mínimoCoste no siempre encuentra una


solución de mínimo coste, pero puede modificarse ligeramente…
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 21
Aplicación a problemas de optimización
algoritmo mínimoCoste2(ent x0:nodo)
variables c:cola; {cola con prioridades de <x,coste(x)>}
éxito:booleano; xcurso,x:nodo
principio
creaVacía(c); {cola de nodos vivos}
añadir(c,<x0,coste(x0)>);
éxito:=falso;
mq not éxito and not esVacía(c) hacer
xcurso:=min(c); {nodo en curso}
eliminarMin(c);
si esSol(xcurso) entonces
escribir(xcurso); éxito:=verdad
sino
para todo x hijo de xcurso hacer
añadir(c,<x,coste(x)>)
fpara
fsi
fmq;
si not éxito entonces escribir(“No hay solución”) fsi
fin

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 22


Aplicación a problemas de optimización
• Diferencia con el algoritmo anterior:

– el primer algoritmo: si encuentra un hijo que sí es solución factible ya no


incluye el resto de los hijos en la cola de nodos vivos con prioridades;

– el segundo algoritmo: incluye en la cola de nodos vivos con prioridades a


todos sus hijos, sin mirar si son solución factible o no.

• el algoritmo segundo es más “prudente”

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 23


Aplicación a problemas de optimización
– Teorema. Si para cada nodo x del árbol del espacio de estados cˆ (x) es una
estimación de c(x) tal que:
cˆ (x) ≤ c(x)
y para cada nodo solución x se verifica:
cˆ (x) = c(x)
entonces si el algoritmo mínimoCoste2 encuentra una solución, ésta es
de mínimo coste.
Demostración: Si se encuentra la solución xcurso, se tiene que
cˆ (xcurso) ≤ cˆ (x)
para todo nodo x de la cola de nodos vivos.
Además,
cˆ (xcurso) = c(xcurso) y cˆ (x) ≤ c(x)

para todo nodo x de la cola de nodos vivos.


Luego c(xcurso) ≤ c(x), y xcurso es de mínimo coste.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 24


Introducción: (2) … y poda
• Ramificación… y poda:
– Problema de minimización de una función c(x) (función objetivo).

– Se utiliza una función de estimación cˆ (x) que sea una cota inferior de
todas las soluciones obtenidas desde x:

cˆ (x) ≤ c(x)

– Suponer que se conoce una cota superior, U, del valor mínimo de c.

c(x *) = min c(x) ≤ U


x

(i.e. , cota pesimista de la solución del problema)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 25


Introducción: (2) … y poda
– Regla de poda:

x: cˆ (x) > U , x puede ser podado porque


cˆ (x) > U
∀y solución descendiente de x: c(y) ≥ c(x) ≥ cˆ (x) > U

– Si se actualiza el valor de U (al alcanzar una solución con un coste


menor), todos los nodos vivos de coste estimado mayor también se
pueden podar (otra cosa es que no se haga por no disminuir la eficiencia)
– Valor inicial de U:
• utilizar alguna heurística (basada en información extra sobre el problema),
• ∞
– Si el valor inicial de U es mayor o igual que el coste de una solución de
mínimo coste, la regla de poda no elimina ningún nodo ascendente de una
solución de coste mínimo.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 26


Introducción: (2) … y poda
• Construcción del algoritmo:
– Definición de la función de coste c(x) de forma que c(x) sea mínimo
para todos los nodos que representen una solución óptima.
– ¿Cómo?
• si x es solución factible del problema de optimización:
c(x) = función objetivo(x);
• si x no es factible: c(x) = ∞;
• si x representa una sol. parcial (i.e. x puede ser completada a factible):
{
c (x) = min c (y) y es descendiente de x }
¡Esta función es tan difícil de calcular como resolver el problema original!

– Se utiliza cˆ (x) tal que cˆ (x) ≤ c(x) para todo x.



– La función de estimación estima el valor de la función objetivo y no
el coste computacional de alcanzar una solución.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 27
Introducción: (2) … y poda
• Puntos clave del método:

1. (Recordar) Encontrar un buen orden de recorrido o ramificación de los


nodos, es decir, definir una buena función de prioridad de los nodos vivos
para que las soluciones buenas se encuentren rápidamente.

2. Encontrar una buena función de poda, U, para que se produzca el


retroceso lo antes posible.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 28


Introducción: (2) … y poda
algoritmo RamPodaMinCoste(ent x0:nodo)
{Busca en el árbol cuya raíz es x0 una solución de mínimo coste.
Se asume que existe al menos un nodo de mínimo coste y que se
dispone de una función ĉ y de un valor inicial U: ĉ(x)≤c(x)≤U.}
variables q:cola; {cola con prioridades de <x,ĉ(x)>}
xcurso,x:nodo
principio
creaVacía(q); {cola con prioridades de nodos vivos}
añadir(q,<x0,ĉ(x0)>);
mq not esVacía(q) hacer
xcurso:=min(q); {nodo en curso} eliminarMin(q);
para todo x hijo de xcurso hacer
si ĉ(x)≤U entonces
añadir(q,<x,ĉ(x)>);
si esSoluciónFactible(x) and c(x)<U entonces U:=c(x) fsi
fsi
fpara;
si esVacía(q) or ĉ(min(q))≥U entonces
escribir(U); creaVacía(q)
fsi
fmq
fin
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 29
Introducción: (2) … y poda
• Si, como es lógico, se desea escribir la solución óptima además
del valor óptimo (U) de la función objetivo:

– cada vez que se añade un nodo a la cola, hay que guardar en una tabla
auxiliar de padres de nodos ese nodo junto a su padre o bien guardar con
cada nodo una identificación de su padre, y

– hay que mantener una variable auxiliar con el valor del último nodo
solución que ha permitido actualizar U.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 30


Un problema de planificación de tareas a plazo fijo
• Generalización del problema resuelto con un algoritmo voraz
(Algoritmos voraces, pág. 66).
• Se tiene un conjunto C={1,2,…,n} de tareas y en cada instante
sólo se puede realizar una tarea.
• Cada tarea i, 1≤i≤n, tiene asociada una terna (ti,di,wi) de forma
que:
– ti es la duración de la tarea i (el caso ti=1 para todo i fue resuelto con un
algoritmo voraz);
– la tarea i debe terminarse antes del instante (o plazo) di;
– hay una penalización wi si la tarea i no termina antes de su plazo.
• Se trata de encontrar un subconjunto S de tareas de C tal que
todas las tareas de S puedan ser ejecutadas antes de sus plazos y
la penalización total sea mínima.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 31


Un problema de planificación de tareas a plazo fijo
• Ejemplo:
n = 4;
(t1,d1,w1) = (1,1,5)
(t2,d2,w2) = (2,3,10)
(t3,d3,w3) = (1,2,6)
(t4,d4,w4) = (1,1,3)

• Espacio de estados: todos los subconjuntos de {1,2,3,4}.

• Dos representaciones posibles:


– tuplas de tamaño variable y
– tuplas de tamaño fijo.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 32


Un problema de planificación de tareas a plazo fijo
• Representación con tuplas de tamaño variable: c=8
1
x1=1 x1=4
x1=2 x =3
1

2 3 4 5
• Nodos cuadrados: x2=4
estados no factibles x2=2 x2=3 x2=4 x2=4
x2=3
6 7 8 9 10 11
• Nodos circulares:
nodos factibles x3=3 x3=4 x3=4 x3=4
(o soluciones)
12 13 14 15
• Nodo 9:
solución óptima (es la única)
S = {2,3}
Penalización total = 8

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 33


Un problema de planificación de tareas a plazo fijo
• Representación con tuplas de tamaño fijo:
c=8
1
x1=1 x1=0
• Soluciones factibles:
2 3
representadas por
hojas circulares x2=1 x2=0 x2=1 x2=0

4 5 6 7
x3=1 x3=0 x3=1 x3=0

9 10 11 12 13 14 15
x4=1 x4=0
• Solución óptima:
19 21 23 25 26 27 28 29 30 31
nodo 25
S = {2,3}
Penalización total = 8

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 34


Un problema de planificación de tareas a plazo fijo
• Definición de la función de coste c(x).
Caso de representación de tamaño variable:
– Para todo nodo circular x con algún hijo circular:
c(x) = mínima penalización correspondiente a c=8
todos los nodos descendientes de x. 1

– Para todo nodo cuadrado x: x1=1 x1=4


x1=2 x1=3
c(x) = ∞.
c=9 2 c=8 3 c = 15 4 5
x2=4 x2=3 x2=4 c = 21
x2=2 x2=4
x2=3
c=8
c=9 6 c = 13 7 8 9 10 11
c=∞ c = 11 c = 15
x3=3 x3=4 x3=4 x3=4

12 13 14 15 (t1,d1,w1) = (1,1,5)
c=∞ c=∞ c=∞ c=∞ (t2,d2,w2) = (2,3,10)
(t3,d3,w3) = (1,2,6)
(t4,d4,w4) = (1,1,3)
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 35
Un problema de planificación de tareas a plazo fijo
• Definición de la función de coste c(x).
Caso de representación de tamaño fijo:
– Para todo nodo circular x con algún hijo circular: c(x) = mínima
penalización correspondiente a todos los nodos descendientes de x.
– Para todo nodo cuadrado x: c=8 1
c(x) = ∞. x1=1 x1=0

c=9 2 c=8 3
x2=1 x2=0 x2=1 x2=0

c=9 4 c = 13 5 c=8 6 c = 15 7
(t1,d1,w1) = (1,1,5)
x3=1 x3=0 x3=1 x3=0
(t2,d2,w2) = (2,3,10)
c = 13 c = 19 c = 8 c = 11 c = 15 c = 21
(t3,d3,w3) = (1,2,6) c=9
9 10 11 12 13 14 15
(t4,d4,w4) = (1,1,3)
x4=1 x4=0

19 21 23 25 26 27 28 29 30 31
9 13 19 8 11 14 15 18 21 24
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 36
Un problema de planificación de tareas a plazo fijo
• Definición de una función de estimación:
cˆ (x) ≤ c(x)

– Sean
• Sx = {tareas seleccionadas para S hasta el nodo x}
• mx = max {i | i ∈ Sx}

– Entonces:
penalización debida
cˆ (x) = ∑ wi a las tareas que ya
i <m x
i ∉Sx han quedado
excluidas de x

– Para nodos cuadrados:


cˆ (x) = ∞

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 37


Un problema de planificación de tareas a plazo fijo
– En el caso de formulación de tamaño variable:
c=8
cˆ = 0 1

x1=1 x1=4
x1=2 x1=3

cˆ = 0 2 cˆ = 5 3 cˆ = 15 4 5
cˆ = 21
x2=2 x2=4 x2=3 x2=4
x2=3 x2=4

cˆ = 0 6 cˆ = 10 7 8 9 10 11 cˆ = 15
cˆ = ∞ cˆ = 5 cˆ = 11
x3=3 x3=4 x3=4 x3=4

12 13 14 15
cˆ = ∞ cˆ = ∞ cˆ = ∞ cˆ = ∞
(t1,d1,w1) = (1,1,5)
cˆ (x) = ∑ wi (t2,d2,w2) = (2,3,10)
i <m x (t3,d3,w3) = (1,2,6)
i ∉Sx
(t4,d4,w4) = (1,1,3)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 38


Un problema de planificación de tareas a plazo fijo
– En el caso de formulación de tamaño fijo:
c=8
cˆ = 0 1
x1=1 x1=0

cˆ = 0 2 cˆ = 5 3
x2=1 x2=0 x2=1 x2=0 cˆ (x) = ∑ wi
i <m x
cˆ = 0 4 cˆ = 10 5 cˆ = 5 6 cˆ = 15 7 i ∉Sx

x3=1 x3=0 x3=1 x3=0

cˆ = 6 cˆ = 10 cˆ = 16 cˆ = 5 cˆ = 11 cˆ = 15 cˆ = 21
9 10 11 12 13 14 15 (t1,d1,w1) = (1,1,5)
(t2,d2,w2) = (2,3,10)
x4=1 x4=0
(t3,d3,w3) = (1,2,6)
19 21 23 25 26 27 28 29 30 31 (t4,d4,w4) = (1,1,3)
9 13 19 8 11 14 15 18 21 24

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 39


Un problema de planificación de tareas a plazo fijo
• Poda:

– Definición de U:
(Recordar:
U debe ser cota superior del coste de una solución de mínimo coste)

para cada nodo x, se puede calcular un valor de U:

U = ∑ wi
i ∉Sx

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 40


Un problema de planificación de tareas a plazo fijo
• Algoritmo de ramificación y poda con cˆ = 0
estrategia de mínimo coste: U = 24 1
x =1 x1=4
(representación de 1 x1=2 x1=3

tamaño variable) cˆ = 0 cˆ = 5 cˆ = 15 4 cˆ = 21 5
2 U = 14 3
U = 19 U = 18 U = 21
x2=4 x2=3 x2=4
x2=2 x2=4
(t1,d1,w1) = (1,1,5) x2=3
(t2,d2,w2) = (2,3,10) 6 7 8 9 10 11
(t3,d3,w3) = (1,2,6)
x3=3 x3=4 x3=4 x3=4
(t4,d4,w4) = (1,1,3)
12 13 14 15
U = ∑ wi
i ∉Sx

– Empieza con U = ∞ (o U = 24) y con 1 como nodo en curso (único


nodo vivo).
– Se expande 1 generando: 2 , 3 , 4 , 5 .
– U se actualiza a 14 al generar 3 ; 4 y 5 se matan porque
cˆ (4) = 15 > U, cˆ (5) = 21 > U
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 41
Un problema de planificación de tareas a plazo fijo
cˆ = 0
U = 24 1
x1=1 x1=4
x1=2 x1=3
(t1,d1,w1) = (1,1,5)
(t2,d2,w2) = (2,3,10) cˆ = 0 2 cˆ = 5
(t3,d3,w3) = (1,2,6) U = 19 U = 14 3 4 5
x2=3 x2=4 x2=3 x2=4
(t4,d4,w4) = (1,1,3) x2=2 x2=4
cˆ = 0 cˆ = 10
U=9 6 U = 13
7 8 9 10 11
cˆ = ∞ cˆ = 5 cˆ = 11
x3=3 x3=4 x3=4 x3=4

12 13 14 15 U= ∑ wi
cˆ = ∞ cˆ = ∞ cˆ = ∞ i ∉Sx
– El siguiente nodo en curso es 2 . (cˆ (2) = 0 < 5 = cˆ (3) )
– Se añaden a la cola: 6 , 7 , 8 . Se actualiza U a 9 al generar 6 .
– El nodo 7 se mata porque cˆ (7) = 10 > U = 9.
– El nodo 8 se mata porque no es factible.
– Los nodos vivos son 3 y 6 . El siguiente nodo en curso es 6 .

Algoritmia básica - Javier Campos (Universidad de Zaragoza)


(cˆ (6) = 0 < 5 = cˆ (3) ) 42
Un problema de planificación de tareas a plazo fijo
cˆ = 0
U = 24 1
(t1,d1,w1) = (1,1,5)
(t2,d2,w2) = (2,3,10) x1=1 x1=4
x1=2 x1=3
(t3,d3,w3) = (1,2,6)
cˆ = 0 2 cˆ = 5
(t4,d4,w4) = (1,1,3) 3 4 5
x2=4 x2=3 x2=4
x2=2 x2=3 x2=4
cˆ = 5 cˆ = 11
– Los 2 hijos de 6 cˆ = 0 6 7 8 9 10 11
U=9
son no factibles, U=8 U = 11
x3=3 x3=4 x3=4
luego el siguiente x3=4
U = ∑ wi
nodo en curso 12 13 14 15 i ∉Sx
es 3 . ˆ
c = ∞ ˆ
c =∞ cˆ = ∞

– Al generar 9 , U se actualiza a 8. El nodo 10 se mata porque


cˆ (10) = 11 > U = 8.
– El único nodo vivo es 9 , luego se convierte en nodo actual. Su único
hijo es no factible, por tanto se acaba la búsqueda y la sol. es el nodo 9 .

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 43


El problema de la mochila 0-1
• Recordar el problema de la mochila fraccionable…
– Se tienen n objetos fraccionables y una mochila.
– El objeto i tiene peso pi y una fracción xi (0≤xi≤1) del objeto i produce un
beneficio bixi.
– El objetivo es llenar la mochila,
de capacidad C, de manera que maximizar ∑ bi xi
1≤i ≤n
se maximice el beneficio.
sujeto a ∑ pi xi ≤ C
1≤i ≤n

con 0 ≤ xi ≤ 1, bi > 0, pi > 0, 1 ≤ i ≤ n


• … y su versión 0-1…
– xi sólo toma valores 0 ó 1, indicando que el objeto se deja fuera o se mete en
la mochila.
– Los pesos, pi, los beneficios, bi, y la capacidad son números naturales.
• … pero sin exigir ahora que pi, bi y C sean naturales (sino simplemente
reales positivos).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 44


El problema de la mochila 0-1
• Soluciones previas a problemas parecidos:
– Mochila con objetos fraccionables, es decir, 0≤xi≤1, 1≤i≤n: solución
voraz.
– Mochila 0-1 pero siendo los pesos, beneficios y capacidad de la mochila
números naturales: solución de programación dinámica.

Ninguna de las dos soluciones funciona en el caso general de la


mochila 0-1.

– Caso general de la mochila 0-1: solución de búsqueda con retroceso.

Puede mejorarse la eficiencia.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 45


El problema de la mochila 0-1
• Transformación en problema de minimización:
minimizar − ∑ bi xi
1 ≤i ≤n

sujeto a ∑ pi xi ≤ C
1≤i ≤n

{ }
con xi ∈ 0,1 , bi > 0, pi > 0, 1 ≤ i ≤ n
1
• Espacio de soluciones: x1=0 x1=1
– 2n
modos de asignar los
2 17
valores 0 ó 1 a las xi.
x2=0 x2=1 x2=0 x2=1
– Dos formas de representar
3 10 18 25
la solución: tuplas de
tamaño fijo o variable. x3=0 x3=1 x3=0 x3=1 x3=0 x3=1 x3=0 x3=1

4 7 11 14 19 22 26 29

Tamaño fijo: x4=1 x4=1 x4=1 x4=1 x4=1 x4=1


x4=1 x4=1
x4=0 x4=0 x4=0 x4=0 x4=0
x4=0 x4=0 x4=0
5 6 8 9 12 13 15 16 20 21 23 24 27 28 30 31

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 46


El problema de la mochila 0-1
• Definición de la función de coste, c:
– Las hojas x que ponen fin a caminos desde la raíz tales que

∑ pi xi > C
1≤i ≤n

representan soluciones no factibles y para ellas c(x)=∞.

– El resto de las hojas x representan soluciones factibles. Para ellas


c(x) = − ∑ bi xi
1 ≤i ≤n

– Para nodos x que no sean hojas, c(x) es el mínimo entre c(xiz) y c(xde),
siendo xiz y xde los hijos izquierdo y derecho, resp., de x.

Por supuesto, su cálculo es tan difícil como resolver el problema


original…

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 47


El problema de la mochila 0-1
• Definición de función ˆc y de valor U tales que
cˆ (x) ≤ c(x) ≤ U

• Valor U:
– Solución más sencilla:
Si x es un nodo de nivel j, con 0≤j≤n, se han asignado ya valores a xi,
1≤i≤j, por tanto:
c(x) ≤ − ∑ bi xi = U
1 ≤i ≤ j

(i.e., beneficio actual cambiado de signo).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 48


El problema de la mochila 0-1
– Solución mejorada:
constante n=... {número de objetos}
tipo vectReal=vector[1..n] de real
variables C:real; benef,peso:vectReal
{Pre: ∀i∈1..n:peso[i]>0 ∧
∀i∈1..n-1:benef[i]/peso[i]≥ benef[i+1]/peso[i+1]}
función U_mejor(cap,Ufácil:real; obj:entero) devuelve real
{cap=capacidad ya ocupada de la mochila; Ufácil=valor de U calculado
de forma fácil; obj=índice del primer objeto a considerar}
variable ca:real
principio
U:=Ufácil; ca:=cap;
para i:=obj hasta n hacer
si ca+peso[i]≤C entonces ca:=ca+peso[i]; U:=U-benef[i] fsi
fpara;
devuelve U
fin
 
U = U _ mejor  ∑ pi xi , − ∑ bi xi , j + 1 
 1≤i ≤ j 1 ≤i ≤ j 
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 49
El problema de la mochila 0-1
• Función ˆc :
– Utilizar la función de poda que se definió para el método de búsqueda con
retroceso:
• era una cota superior del valor de la mejor solución posible al expandir el
nodo y sus descendientes,
• ahora hemos cambiado de signo a la función objetivo,
luego, cambiada de signo, es una cota inferior de c(x)

– ¿Cómo se calculó esa cota?


• en el nodo actual ya se han determinado xi, 1≤i≤j;
• relajar el requisito de integridad:
xi∈{0,1}, j+1≤i≤n se sustituye por 0≤xi≤1, j+1≤i≤n
• aplicar el algoritmo voraz

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 50


El problema de la mochila 0-1
constante n=... {número de objetos}
tipo vectReal=vector[1..n] de real
variables C:real; benef,peso:vectReal
{Pre: ∀ i∈1..n:peso[i]>0 ∧
∀i∈1..n-1:benef[i]/peso[i]≥benef[i+1]/peso[i+1]}

función cota(cap,ben:real; obj:entero) devuelve real


{cap=capacidad aún libre de la mochila;
ben=beneficio actual;
obj=índice del primer objeto a considerar}
principio
si obj>n or cap=0.0 entonces devuelve ben
sino
si peso[obj]>cap entonces devuelve ben+(cap/peso[obj])*benef[obj]
sino
devuelve cota(cap-peso[obj],ben+benef[obj],obj+1)
fsi
fsi
fin
 
ˆc (x) = − cota C − ∑ pi xi , ∑ bi xi , j + 1
 1≤ i ≤ j 1≤ i ≤ j 
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 51
El problema de la mochila 0-1
• Ejemplo:
n = 4;
(b1,b2,b3,b4) = (10,10,12,18)
(p1,p2,p3,p4) = (2,4,6,9)
C = 15

1 primer nodo vivo (raíz, nivel 0, ninguna xi asignada)

cˆ (1) = −cota (15,0,1) = − cota (13,10, 2) =

= −cota (9, 20, 3) = − cota (3, 32, 4) =

= − (32 + 3 /9 * 18) = −38


U = −32 1
El valor actual de U es -32; el nodo se expande: x1=1 x1=0

cˆ (2) =−38 cˆ (3) =−32


Regla de poda 2 3
U = −32 U = −22
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 52
El problema de la mochila 0-1
1
2 Siguiente nodo en curso. Se expande… x1=1 x1=0

cˆ (2) =−38 cˆ (3) =−32


n = 4; 2 3
U = −32 U = −22
(b1,b2,b3,b4) = (10,10,12,18) x2=1 x2=0
(p1,p2,p3,p4) = (2,4,6,9) cˆ (4) =−38 cˆ (5) =−36
4 5
C = 15 U = −32 U = −22

cˆ (4) =−38
4 Siguiente nodo en curso. Se expande…
U = −32 4
x3=1 x3=0
cˆ (6) =−38 cˆ (7) =−38
6 7
U = −32 U = −38
¿Siguiente nodo en curso?
Hay dos con igual prioridad: 6 y 7.
Si es elegido el 6, se generan sus hijos: el izquierdo es eliminado por no ser factible,
el derecho se añade a la cola de vivos (con prioridad -32, mayor que el nodo 7),
luego el siguiente elegido es el 7.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 53


El problema de la mochila 0-1

n = 4;
7 Siguiente nodo en curso. (b1,b2,b3,b4) = (10,10,12,18)
Nuevo valor de U = -38. Se expande… (p1,p2,p3,p4) = (2,4,6,9)
C = 15
cˆ (7) =−38
U = −38 7

x4=1 x4=0
cˆ (8) =−38 cˆ (9) =−20
8 9
U = −38 U = −20

Los nodos 3 y 9 se matan (no alcanzan el valor de U).


El nodo 8 es el único en la cola.
El valor óptimo es 38.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 54


El problema de la mochila 0-1
• Comentarios adicionales:
– Para poder imprimir la solución (además del valor óptimo) hay que:
• guardar con cada nodo una identificación de su padre (identificador, puntero,
cursor, …),
• mantener una variable auxiliar con el valor del último nodo solución que ha
permitido actualizar U, y
• asociar con cada nodo un booleano que diga si es un hijo izquierdo o derecho
(i.e., si mete en la mochila el objeto correspondiente o no).
– Cabe pensar en una versión con estrategia ciega de ramificación (FIFO,
por ejemplo) en lugar de la de mínimo coste:
• por un lado la intuición nos dice que la estrategia de mínimo coste se acerca
más deprisa a la solución óptima,
• por otra parte, la inserción y borrado en la cola con prioridades de nodos
vivos tiene coste logarítmico, mientras que con una cola FIFO, el coste es
constante…
depende de los datos de entrada…

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 55


El problema del viajante de comercio
• Recordar:
¡Estoy hasta
las θ’s
de viajar !
– Encontrar un recorrido de longitud
mínima para un viajante que tiene
que visitar varias ciudades y volver
al punto de partida, conocida la
distancia existente entre cada
dos ciudades.

– Es decir, dado un grafo dirigido con arcos de longitud no negativa, se trata


de encontrar un circuito de longitud mínima que comience y termine en el
mismo vértice y pase exactamente una vez por cada uno de los vértices
restantes (circuito hamiltoniano).

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 56


El problema del viajante de comercio
• Soluciones ensayadas hasta ahora:
– Heurística voraz: calcula una solución subóptima
– Programación dinámica:
• coste en tiempo: Θ(n22n)
• coste en espacio: Ω(n2n)
• ¡Hay muchas más soluciones!
– “…El problema del viajante de comercio es probablemente el problema
NP-completo más estudiado en términos de soluciones propuestas…”

(U. Manber: Introduction to Algorithms. A Creative Approach. Addison-Wesley, 1989.)

– Ya en el año 85…
E.L. Lawler, J.K. Lenstra,
A.H.G. Rinnooy Kan, y D.B. Shmoys:
The Traveling Salesman Problem.
John Wiley & Sons, New York, 1985.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 57


El problema del viajante de comercio
• El coste del caso peor de la solución que vamos a ver seguirá
estando en O(n22n).

• Sin embargo, el uso de buenas funciones de acotación mejora la


eficiencia en muchos casos con respecto a la solución de
programación dinámica.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 58


El problema del viajante de comercio
• Formalización:
– Sean G=(V,A) un grafo orientado,
V={1,2,…,n},
Lij la longitud de (i,j)∈A,
Lij=∞ si no existe el arco (i,j).
– El circuito buscado empieza en el vértice 1.
– Espacio de soluciones:
E = { 1,π,1 | π es una permutación de (2,3,…,n) }
|E| = (n-1)!

– Reducción del espacio de soluciones:


E = { 1,π,1 | π = i1,i2,…,in-1, es una permutación de
(2,3,…,n) tal que (ij,ij+1)∈A, 0≤j≤n-1,
i0=in=1 }

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 59


El problema del viajante de comercio
• Representación del espacio de estados:
– Caso de un grafo completo con |V| = 4.
1

i1=2 i1=3 i1=4

2 3 4

i2=3 i2=4 i2=2 i2=4 i2=2 i2=3

5 6 7 8 9 10

i3=4 i3=3 i3=4 i3=2 i3=3 i3=2

11 12 13 14 15 16

Cada hoja es una solución y representa el viaje


definido por el camino desde la raíz hasta la hoja.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 60


El problema del viajante de comercio
• Definición de la función de coste, c:

– Debe ser tal que el nodo solución x con valor mínimo de c(x) corresponda
a un recorrido de longitud mínima.

– Por ejemplo,

 longitud del hamiltoniano definido por el camino


 desde la raíz hasta x , si x es una hoja
c(x) = 
 coste de una hoja de coste mínimo del subárbol
 con raíz x , si x no es una hoja

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 61


El problema del viajante de comercio
• Definición de la función de estimación ˆc
– Debe ser tal que: cˆ (x) ≤ c(x)
– Una muy fácil:
cˆ (x) = distancia total del recorrido definido
por el camino desde la raíz hasta x
1

i1=2

i2=3 i2=4
cˆ (6) = L1, 2 + L2, 4
5 6

Si x es una hoja, es obvio que:

cˆ (x) = c(x)

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 62


El problema del viajante de comercio
• Puede mejorarse usando la matriz de distancias reducida:
– Una fila (columna) de la matriz de distancias se dice reducida si sus
elementos son no negativos y contiene al menos un 0.
– Una matriz de distancias se dice  ∞ 20 30 10 11
reducida si cada fila y 15 ∞ 16 4 2 
columna es reducida.  
3 5 ∞ 2 4
 
19 6 18 ∞ 3
 
16 4 7 16 ∞ 
Ejemplo de matriz no reducida.

– Para cada k, 1≤k≤n, todo circuito hamiltoniano incluye exactamente


⇓ un arco de la forma (k,-) y exactamente un arco de la forma (-,k).
– Si se resta una constante t de cada elemento de una fila (columna) de
la matriz de distancias, la longitud de todo hamiltoniano se reduce
exactamente en t y un hamiltoniano de distancia mínima lo sigue
siendo.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 63
El problema del viajante de comercio
– Si se elige t como el mínimo de los ∞ 20 30 10 11 ∞ 10 20 0 1
elementos de la fila (columna) i-ésima 15 ∞ 16 4 2 15 ∞ 16 4 2
y se resta t de todos los elementos de 3 5 ∞ 2 4 3 5 ∞ 2 4
esa fila (columna), la fila resultante    
19 6 18 ∞ 3 19 6 18 ∞ 3
es reducida.    
16 4 7 16 ∞  16 4 7 16 ∞
Reducción de la fila 1, t = 10.
– Repitiendo el proceso para filas y columnas, siempre se puede conseguir
que la matriz de distancias  ∞ 20 30 10 11  ∞ 10 17 0 1 
sea reducida. 15 ∞ 16 4 2  12 ∞ 11 2 0 
Reducción 3 5 ∞ 2 4  0 3 ∞ 0 2
de la matriz,
   
L = 25. 19 6 18 ∞ 3 15 3 12 ∞ 0
   
16 4 7 16 ∞  11 0 0 12 ∞
La cantidad total L restada de filas y columnas es una cota inferior de la
longitud de un hamiltoniano de longitud mínima, luego sirve como
estimación cˆ (x) para el nodo x raíz.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 64
El problema del viajante de comercio
– Cálculo de cˆ (x) para los nodos distintos de la raíz y de las hojas:
• Sea A la matriz de distancias reducida para el nodo y.
• Sea x un hijo de y que corresponda a incluir el arco (i,j) en el recorrido y que
no sea hoja.
• La matriz B reducida para x, y por tanto cˆ (x), se calcula de la siguiente forma:

1. Cambiar todos los elementos de la fila i y de la columna j de A por ∞.


– Esto evita el incluir más arcos que salgan de i o lleguen a j.
2. Cambiar el elemento (j,1) de A por ∞.
– Esto evita considerar el arco (j,1).
3. B es la matriz que se obtiene al reducir todas las filas y columnas de la matriz
resultante (excepto aquéllas formadas sólo por “∞”).

• Si r es el valor total restado en el paso (3):


cˆ (x) = cˆ (y) + A(i, j) + r

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 65


El problema del viajante de comercio
• Definición de la función de poda U:
– Por simplificar la exposición, podemos adoptar la función de poda trivial:

• Inicialmente, U = ∞.

• Se modifica U sólo cuando se llega a un nodo x que es una hoja; entonces:

U = min {U, c(x) }

• Ejercicio: Pensar mejores funciones de poda.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 66


El problema del viajante de comercio
∞ 20 30 10 11 ∞ 10 17 0 1
• Ejemplo:
15 ∞ 16 4 2 12 ∞ 11 2 0
Grafo original.  3 5 ∞ 2 4 Matriz reducida, 
0 3 ∞ 0 2
  L = 25.  
19 6 18 ∞ 3 15 3 12 ∞ 0
   
16 4 7 16 ∞  11 0 0 12 ∞
∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞
∞ cˆ = 25 1 U=∞
∞ 11 2 0  10 ∞ 9 0 ∞
0 ∞ ∞ 0 2 i1 = 2 i1 = 5 0 3 ∞ 0 ∞
  i1 = 3  
15 ∞ 12 ∞ 0 i1 = 4
  12 0 9 ∞ ∞
2 3 4 5  
11 ∞ 0 12 ∞
∞ 0 0 12 ∞
cˆ = 25+10 = 35 cˆ = 25+17+11 = 53 cˆ = 25 cˆ = 25+1+5 = 31
∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞
1 ∞ ∞ 2 0 12 ∞ 11 ∞ 0 
 0 2 0
∞ 3 ∞ 3 ∞ ∞ 2
   
4 3 ∞ ∞ 0 ∞ 3 12 ∞ 0
   
0 0 ∞ 12 ∞ 11 0 0 ∞ ∞
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 67
El problema del viajante de comercio
cˆ = 25 1 U=∞

i1 = 2 i1 = 5
i1 = 3 i1 = 4
cˆ = 35 2 cˆ = 53 3 cˆ = 25 4 cˆ = 31 5

i2 = 2 i2 = 5
i2 = 3
cˆ = 28 6 7 8 cˆ = 36
cˆ = 50
i3 = 3 El siguiente nodo en curso sería
i3 = 5
el 5, pero cˆ (5) = 31 > U
cˆ = 32 9 10 cˆ = 28 luego el algoritmo
termina y el hamiltoniano mínimo
i4 = 3 es 1,4,2,5,3,1.

cˆ = 28 11 Es hoja (solución),
se actualiza U = 28.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 68


El problema del viajante de comercio
• Otras versiones, basadas en otra representación del espacio de
estados:

– Un hamiltoniano es un conjunto de n arcos.

– Además, para cada vértice i, 1≤i≤n, debe haber en ese conjunto


exactamente un arco de la forma (i,j) y uno de la forma (k,i).

– Espacio de estados = árbol binario:

• Un hijo izquierdo representa la inclusión de un determinado arco en el


hamiltoniano mientras que su hermano derecho representa la exclusión de ese
arco.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 69


El problema del viajante de comercio
– Hay distintos árboles, dependiendo de qué arco se elige para
incluir/excluir en cada paso.
1

3 2 1
incluir excluir
1 (1,3) (1,3)
incluir excluir
(1,2) (1,2) 2 3
incluir excluir incluir excluir
2 3 (1,2) (1,2) (1,2) (1,2)
incluir excluir incluir excluir 4 5 6 7
(1,3) (1,3) (1,3) (1,3)
4 5 6 7

– ¿Cómo elegir el arco por el que empezar?


Depende de los datos del problema.
– Árbol de estados dinámico: el método de construcción depende de los
datos del problema.
Algoritmia básica - Javier Campos (Universidad de Zaragoza) 70
El problema del viajante de comercio
– Si se elige, para empezar, el arco (i,j):
• el subárbol izquierdo representa todos los recorridos que incluyen el arco (i,j),
y
• el subárbol derecho los recorridos que no lo incluyen;
• si hay un recorrido óptimo incluido en el subárbol izquierdo, entonces sólo
faltan por seleccionar n-1 arcos para encontrarlo,
• mientras que si todos están en el derecho, hay que seleccionar todavía n arcos.

⇒ Hay que intentar seleccionar un arco que tenga


la máxima probabilidad de estar en el recorrido óptimo.

Hay varias heurísticas posibles, por ejemplo:


• Elegir un arco que produzca un subárbol derecho cuya raíz x tenga cˆ (x)
máxima.
• Elegir un arco tal que la diferencia entre la función cˆ para el hijo izquierdo
y el derecho sea máxima.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 71


El problema del viajante de comercio
– Aplicando la primera de las heurísticas al
cˆ = 25
mismo grafo: 1
∞ 20 30 10 11  incluir (3,1) excluir (3,1)
15 ∞ 16 4 2
3 cˆ = 25 2 3 cˆ = 36
5 ∞ 2 4
  incluir (5,3) excluir (5,3)
19 6 18 ∞ 3
  cˆ = 28 4 5 cˆ = 36
16 4 7 16 ∞ 
incluir (1,4) excluir (1,4)
Se llega al nodo 6. cˆ = 28 6 7 cˆ = 37
Se han elegido ya tres arcos:
(3,1), (5,3), (1,4).
Para los dos restantes, sólo queda ya una opción: (4,2) y (2,5).
Así, se obtiene el recorrido: 5,3,1,4,2,5.
Con distancia total: 28 (así, U = 28)
El siguiente nodo en curso es el 3, con cˆ (3) = 36 > U y el algoritmo acaba.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 72


El problema del viajante de comercio
• Comentarios:

– En el último ejemplo, el método de ramificación y poda se usa sólo para


subárboles grandes;
una vez que se llega a subárboles pequeños (4 ó 6 nodos) es más eficiente
construirlos enteros y calcular el valor exacto de la función de coste.

– No hay forma de calcular analíticamente cuál de las soluciones del


problema del viajante de comercio es más eficiente.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 73


Consideraciones finales sobre eficiencia:
– Es casi imposible estimar el rendimiento de la técnica para un problema y
funciones de estimación y poda dados.
– ¿Es posible disminuir en algún caso el número de nodos generados
mediante la expansión de nodos x con cˆ (x) > U ?
Nunca (porque el valor de U no será modificado si se expande tal nodo x,
y es el valor de U el que determina qué nodos se expanden en el futuro).
– Si se tienen dos funciones de poda U1 y U2 diferentes y U1<U2 entonces
siempre es mejor usar U1 (i.e., nunca dará lugar a más nodos).
– ¿Si se usa una función de estimación mejor, decrece el número de nodos a
expandir? (cˆ2 es mejor que cˆ1 si cˆ1 (x) ≤ cˆ2 (x) ≤ c(x) para todo x)
No necesariamente.
Si se usa una función de estimación mejor con la estrategia de
ramificación de mínimo coste, el nº de nodos generados puede crecer.

Algoritmia básica - Javier Campos (Universidad de Zaragoza) 74


Algoritmia Básica

Linear Programming and Reductions

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 1 / 71


Outline

1 Introduction

2 Flows in networks

3 Duality

4 Zero-sum games

5 The simplex algorithm

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 2 / 71


Introduction

Outline

1 Introduction

2 Flows in networks

3 Duality

4 Zero-sum games

5 The simplex algorithm

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 3 / 71


Introduction

Introduction
Linear Programming
Assign real values to a set of given variables so as to:
Satisfy a set of linear equations and/or linear inequalities.
Maximize or minimize a given linear objective function.

Example: A boutique chocolatier has two products: muffins and


chocolates.
It makes x1 muffins and x2 chocolates with a profit of 1 and 6 a
piece respectively.
Daily demand of muffins and chocolates is at most 200 and 300.
The current workforce can produce at most 400 products (either
muffins or chocolates).

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 4 / 71


Introduction

Introduction
Linear Programming
Assign real values to a set of given variables so as to:
Satisfy a set of linear equations and/or linear inequalities.
Maximize or minimize a given linear objective function.

Example: A boutique chocolatier has two products: muffins and


chocolates.
It makes x1 muffins and x2 chocolates with a profit of 1 and 6 a
piece respectively.
Daily demand of muffins and chocolates is at most 200 and 300.
The current workforce can produce at most 400 products (either
muffins or chocolates).
———————————————————————–
What are the optimal levels of production?
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 4 / 71
Introduction

Example: Chocolates

Product Var. Profit Max. demand


Muffins x1 1 200
Chocolates x2 6 300

Moreover, x1 + x2 must not be higher than 400.

———————————————————————–

We can represent the situation by a linear program, as follows:


Objetive function max x1 + 6x2
Constraints x1 ≤ 200
x2 ≤ 300
x1 + x2 ≤ 400
x1 , x2 ≥ 0

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 5 / 71


Introduction

Example: Chocolates
Objetive function max x1 + 6x2
Constraints x1 ≤ 200
x2 ≤ 300
x1 + x2 ≤ 400
x1 , x2 ≥ 0
———————————————————————–

Each equation defines a line


and each inequality defines
a half-space.
The set of feasible solutions
(x1 , x2 ) is the intersection of
five half-spaces.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 6 / 71


Introduction

Example: Chocolates

Goal
Find the point of this polygon at which the objective function is
maximized.

The points with a profit of c lie


on the line x1 + 6x2 = c.
As c increases, this “profit line”
moves parallel to itself.

Move the line as far up as possible!

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 7 / 71


Introduction

Example: Chocolates

Remark
Given that the constraints define a convex set and the objective
function is linear, the optimum solution is always achieved at a vertex.

Two exceptions:
The linear program is infeasible (it is impossible to satisfy all
constraints):
x ≤ 1, x ≥ 2
The linear program is unbounded:

max x1 + x2
x1 ≥ 2
x2 ≤ 3

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 8 / 71


Introduction

Example: Chocolates
Linear Programs (LP) can be solved by the simplex algorithm (Dantzig, 1947).

Main idea
The algorithm starts at a given
vertex (in our case (0, 0)).
It repeatedly looks for an
adjacent vertex of better
objective value.
It stops when no better
adjacent vertex exists. The last
visited vertex is globally
optimum.

It does hill-climbing on the vertices of the polygon.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 9 / 71


Introduction

Example: Chocolates
The chocolatier introduces a third product: Cakes. Updated table
Product Variable Profit Max. demand
Muffins x1 1 200
Chocolates x2 6 300
Cakes x3 13 –
The sum of all three variables can be at most 400.
Packaging constraints impose that x2 + 3x3 ≤ 600.
———————————————————————–
Updated linear program:
max x1 + 6x2 + 13x3
x1 ≤ 200
x2 ≤ 300
x1 + x2 + x3 ≤ 400
x2 + 3x3 ≤ 600
x1 , x2 , x3 ≥ 0
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 10 / 71
Introduction

Example: Chocolates

Updated linear program:

max x1 + 6x2 + 13x3


x1 ≤ 200
x2 ≤ 300
x1 + x2 + x3 ≤ 400
x2 + 3x3 ≤ 600
x1 , x2 , x3 ≥ 0

Each linear equation defines a 3D plane.


Each inequality defines a half-space on one side of the plane.
The feasible region is the intersection of the seven half-spaces.
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 11 / 71
Introduction

Example: Chocolates

A profit of c corresponds to the


plane x1 + 6x2 + 13x3 = c.
As c increases, this plane
moves parallel to itself.
The point of final contact is the
optimal vertex: (0, 300, 100)
with total profit 3100.

Possible trajectory of simplex:

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 12 / 71


Introduction

Example: Chocolates
Updated linear program:

max x1 + 6x2 + 13x3


x1 ≤ 200
x2 ≤ 300
x1 + x2 + x3 ≤ 400
x2 + 3x3 ≤ 600
x1 , x2 , x3 ≥ 0

Let’s add the second inequality to the third. Then, add to the result the
fourth inequality multiplied by 4. The result is the inequality:
x1 + 6x2 + 13x3 ≤ 3100
Hence, no feasible solution can have a profit greater than 3100.
———————————————————————–

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 13 / 71


Introduction

Example: Chocolates
Updated linear program:

max x1 + 6x2 + 13x3


x1 ≤ 200
x2 ≤ 300
x1 + x2 + x3 ≤ 400
x2 + 3x3 ≤ 600
x1 , x2 , x3 ≥ 0

Let’s add the second inequality to the third. Then, add to the result the
fourth inequality multiplied by 4. The result is the inequality:
x1 + 6x2 + 13x3 ≤ 3100
Hence, no feasible solution can have a profit greater than 3100.
———————————————————————–
What if we add a fourth line of chocolates, or hundreds more of them?
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 13 / 71
Introduction

Example: Production planning

We now own a company that manufactures carpets. The company has


30 employees. Each employee makes 20 carpets per month and gets a
monthly salary of 2000. The estimated demand for the next 12 months
is d1 , d2 , . . . , d12 . How can we handle the fluctuations in demand?

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 14 / 71


Introduction

Example: Production planning

We now own a company that manufactures carpets. The company has


30 employees. Each employee makes 20 carpets per month and gets a
monthly salary of 2000. The estimated demand for the next 12 months
is d1 , d2 , . . . , d12 . How can we handle the fluctuations in demand?

There are three ways:


1 Overtime, but this is expensive since overtime pay is 80 % more
than regular pay. Also, workers can put in at most 30 % overtime.
2 Hiring and firing, but these cost 320 and 400, respectively, per
worker.
3 Storing surplus production, but this costs 8 per carpet per month.
We currently have no stored carpets on hand, and we must end
the year without any carpets stored.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 14 / 71


Introduction

Example: Production planning

We now own a company that manufactures carpets. The company has


30 employees. Each employee makes 20 carpets per month and gets a
monthly salary of 2000. The estimated demand for the next 12 months
is d1 , d2 , . . . , d12 . How can we handle the fluctuations in demand?

There are three ways:


1 Overtime, but this is expensive since overtime pay is 80 % more
than regular pay. Also, workers can put in at most 30 % overtime.
2 Hiring and firing, but these cost 320 and 400, respectively, per
worker.
3 Storing surplus production, but this costs 8 per carpet per month.
We currently have no stored carpets on hand, and we must end
the year without any carpets stored.
This problem can be formulated and solved as a linear program.
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 14 / 71
Introduction

Example: Production planning


Variables
wi = number of workers during i th month; w0 = 30.
xi = number of carpets made during i th month.
oi = number of carpets made by overtime in month i.
hi , fi = number of workers hired and fired, respectively, at beginning of month i.
si = number of carpets stored at end of month i; s0 = 0.

Constraints
Variables must be nonnegative: wi , xi , oi , hi , fi , si ≥ 0, i = 1, . . . , 12
Number of carpets per month (regular production plus overtime):
xi = 20wi + oi , i = 1, . . . , 12
Number of workers at the start of each month:
wi = wi−1 + hi − fi , i = 1, . . . , 12
Number of carpets stored at the end of each month:
si = si−1 + xi − di , i = 1, . . . , 12
At most 30 % overtime is allowed: oi ≤ 6wi , i = 1, . . . , 12
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 15 / 71
Introduction

Example: Production planning

Variables

Constraints

Objective function: Minimize the total cost

12
X 12
X 12
X 12
X 12
X
min 2000 wi + 320 hi + 400 fi + 8 si + 180 oi
i=1 i=1 i=1 i=1 i=1

Done!

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 16 / 71


Introduction

Example: Production planning

Variables

Constraints

Objective function: Minimize the total cost

12
X 12
X 12
X 12
X 12
X
min 2000 wi + 320 hi + 400 fi + 8 si + 180 oi
i=1 i=1 i=1 i=1 i=1

Done!

———————————————————————–

Unfortunately the solution might be fractional.


Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 16 / 71
Introduction

Example: Optimum bandwidth allocation


We are now a network service provider.

Requirements and Features:


We have to establish three connections: A − B, B − C and A − C.
Each connection must have a bandwidth of at least 2 units.
Connections A − B, B − C and A − C pay 3, 2 and 4 euros per unit of bandwidth
respectively.
Each connection can be routed by the combination of a short and a long path.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 17 / 71


Introduction

Example: Optimum bandwidth allocation


We are now a network service provider.

Requirements and Features:


We have to establish three connections: A − B, B − C and A − C.
Each connection must have a bandwidth of at least 2 units.
Connections A − B, B − C and A − C pay 3, 2 and 4 euros per unit of bandwidth
respectively.
Each connection can be routed by the combination of a short and a long path.
How do we route the connections to maximize the revenue?
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 17 / 71
Introduction

Example: Optimum bandwidth allocation


0 0 0
max 3xAB + 3xAB + 2xBC +2xBC + 4xAC + 4xAC
0 0
xAB + xAB + xBC + xBC ≤ 10 [edge(b, B)]
0 0
xAB + xAB + xAC + xAC ≤ 12 [edge(a, A)]
0 0
xBC + xBC + xAC + xAC ≤8 [edge(c, C)]
0 0
xAB + xBC + xAC ≤6 [edge(a, b)]
0 0
xAB + xBC + xAC ≤ 13 [edge(b, c)]
0 0
xAB + xBC + xAC ≤ 11 [edge(a, c)]
0
xAB + xAB ≥2
0
xBC + xBC ≥2
0
xAC + xAC ≥2
0 0 0
xAB , xAB , xBC , xBC , xAC , xAC ≥0
0
xAB (xAB ) is the short(long)-path bandwidth allocated between A and B.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 18 / 71


Introduction

Example: Optimum bandwidth allocation


0 0 0
max 3xAB + 3xAB + 2xBC +2xBC + 4xAC + 4xAC
0 0
xAB + xAB + xBC + xBC ≤ 10 [edge(b, B)]
0 0
xAB + xAB + xAC + xAC ≤ 12 [edge(a, A)]
0 0
xBC + xBC + xAC + xAC ≤8 [edge(c, C)]
0 0
xAB + xBC + xAC ≤6 [edge(a, b)]
0 0
xAB + xBC + xAC ≤ 13 [edge(b, c)]
0 0
xAB + xBC + xAC ≤ 11 [edge(a, c)]
0
xAB + xAB ≥2
0
xBC + xBC ≥2
0
xAC + xAC ≥2
0 0 0
xAB , xAB , xBC , xBC , xAC , xAC ≥0
0
xAB (xAB ) is the short(long)-path bandwidth allocated between A and B.
———————————————————————–
0 0 0
Solution: xAB = 0, xAB = 7, xBC = 1.5, xBC = 1.5, xAC = 0.5, xAC = 4.5
Every edge, except a−c, is used at full capacity.
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 18 / 71
Introduction

Reductions
Reduction: Transformation of one problem into another problem.

Problem P is reducible to problem Q if an algorithm for solving problem Q


efficiently could also be used as a subroutine to solve problem P efficiently.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 19 / 71


Introduction

Reductions
Reduction: Transformation of one problem into another problem.

Problem P is reducible to problem Q if an algorithm for solving problem Q


efficiently could also be used as a subroutine to solve problem P efficiently.
———————————————————————–
Example: The longest path problem in a dag reduces to the shortest path
problem in a dag.
function LONGEST PATH(G)
negate all edge weights in G
return SHORTEST PATH(G)

———————————————————————–
Reductions enhance the power of algorithms...especially true for LPs.
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 19 / 71
Introduction

Variants of linear programming

A general linear program has many degrees of freedom.


1 It can be either a maximization or a minimization problem.
2 Its constraints can be equations and/or inequalities.
3 The variables are often restricted to be nonnegative, but they can
also be unrestricted in sign.

———————————————————————–

All theses variants can be reduced to one another.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 20 / 71


Introduction

Variants of linear programming


max to min (or vice versa). Multiply the objective function by −1.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 21 / 71


Introduction

Variants of linear programming


max to min (or vice versa). Multiply the objective function by −1.
Inequality constraint like ni=1 ai xi ≤ b to equality. Introduce a new slack variable
P
s and substitute the inequality by:
n
X
ai xi + s = b
i=1

s≥0

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 21 / 71


Introduction

Variants of linear programming


max to min (or vice versa). Multiply the objective function by −1.
Inequality constraint like ni=1 ai xi ≤ b to equality. Introduce a new slack variable
P
s and substitute the inequality by:
n
X
ai xi + s = b
i=1

Pn s≥0
Equality constraint like i=1 ai xi = b to inequality. Substitute the equality by:
n
X
ai xi ≥ b
i=1
n
X
ai xi ≤ b
i=1

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 21 / 71


Introduction

Variants of linear programming


max to min (or vice versa). Multiply the objective function by −1.
Inequality constraint like ni=1 ai xi ≤ b to equality. Introduce a new slack variable
P
s and substitute the inequality by:
n
X
ai xi + s = b
i=1

Pn s≥0
Equality constraint like i=1 ai xi = b to inequality. Substitute the equality by:
n
X
ai xi ≥ b
i=1
n
X
ai xi ≤ b
i=1
Variable unrestricted in sign like x to nonnegative: Introduce two nonnegative
variables, x + , x − ≥ 0, and replace x by x + − x − .

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 21 / 71


Introduction

Variants of linear programming


max to min (or vice versa). Multiply the objective function by −1.
Inequality constraint like ni=1 ai xi ≤ b to equality. Introduce a new slack variable
P
s and substitute the inequality by:
n
X
ai xi + s = b
i=1

Pn s≥0
Equality constraint like i=1 ai xi = b to inequality. Substitute the equality by:
n
X
ai xi ≥ b
i=1
n
X
ai xi ≤ b
i=1
Variable unrestricted in sign like x to nonnegative: Introduce two nonnegative
variables, x + , x − ≥ 0, and replace x by x + − x − .
———————————————————————–
Standard form: All variables are nonnegative, the constraints are all
equations, the objective function is to be minimized.
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 21 / 71
Introduction

Variants of linear programming


Standard form: All variables are nonnegative, the constraints are all
equations, the objective function is to be minimized.
Example:
max x1 + 6x2 min − x1 − 6x2
x1 ≤ 200 x1 + s1 = 200
x2 ≤ 300 x2 + s2 = 300

x1 + x2 ≤ 400 x1 + x2 + s3 = 400
x1 , x2 ≥ 0 x1 , x2 , s1 , s2 , s3 ≥ 0

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 22 / 71


Introduction

Variants of linear programming


Standard form: All variables are nonnegative, the constraints are all
equations, the objective function is to be minimized.
Example:
max x1 + 6x2 min − x1 − 6x2
x1 ≤ 200 x1 + s1 = 200
x2 ≤ 300 x2 + s2 = 300

x1 + x2 ≤ 400 x1 + x2 + s3 = 400
x1 , x2 ≥ 0 x1 , x2 , s1 , s2 , s3 ≥ 0
LPs are easily expressed by using matrices, e.g.:
max cT x
Ax ≤ b
x≥0
   
  1 0 200  
1 x1
where c = , A = 0 1, b = 300, x =
6 x2
1 1 400
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 22 / 71
Flows in networks

Outline

1 Introduction

2 Flows in networks

3 Duality

4 Zero-sum games

5 The simplex algorithm

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 23 / 71


Flows in networks

Example: Shipping oil


Network of pipelines along which oil can be sent:
Goal
Sent as much oil as possible from s (source) to t (sink).

Constraints
Each pipeline has a maximum capacity.
Storing is not possible.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 24 / 71


Flows in networks

Example: Shipping oil


The network is a directed graph G = (V , E) with two special nodes
s, t ∈ V , and capacities on the edges.
Let fe be the flow of edge e.
———————————————————————–
The problem can be formalized as:
Constraints
Capacities are not exceeded: 0 ≤ fe ≤ ce for all e ∈ E.
P P
Storing is not possible: fwu = fuz ∀ node u except s and t.
(w,u)∈E (u,z)∈E

Objective function
X
max fsu
(s,u)∈E

The maximum-flow problem reduces to a linear program


Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 25 / 71
Flows in networks

Example: Shipping oil


Behavior of simplex in the shipping oil problem:
1 Start with zero flow.
2 Repeat: choose an appropriate path from s to t, and increase flow
along the edges of this path as much as possible.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 26 / 71


Flows in networks

Example: Shipping oil


Behavior of simplex in the shipping oil problem:
1 Start with zero flow.
2 Repeat: choose an appropriate path from s to t, and increase flow
along the edges of this path as much as possible.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 26 / 71


Flows in networks

Example: Shipping oil


What if we had initially chosen a different path, i.e., s, a, b, t?
This gives only one unit of flow and blocks all other paths!

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 27 / 71


Flows in networks

Example: Shipping oil


What if we had initially chosen a different path, i.e., s, a, b, t?
This gives only one unit of flow and blocks all other paths!

Simplex solves this problem by allowing paths to cancel existing flow.


In fact, in each iteration simplex looks for an s − t path whose edges
(u, v ) can be of two types:
1 (u, v ) is in the original network, and is not yet at full capacity
((u, v ) can handle up to cuv − fuv additional flow).
2 The reverse edge (v , u) is in the original network, and there is
some flow along it (up to fvu flow units can be canceled).
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 27 / 71
Flows in networks

Example: Shipping oil

Simplex looks for an s − t path whose edges (u, v ) can be of two


types:
1 (u, v ) is in the original network, and is not yet at full capacity
((u, v ) can handle up to cuv − fuv additional flow).
2 The reverse edge (v , u) is in the original network, and there is
some flow along it (up to fvu flow units can be canceled).
———————————————————————–
This flow-increasing opportunities can be captured in a residual
network Gf = (V , E f ) that has two types of edges (u, v ):
(
cuv − fuv if (u, v ) ∈ E and fuv < cuv
fvu if (v , u) ∈ E and fvu > 0
Simplex chooses an s − t path in the residual network.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 28 / 71


Flows in networks

Example: Shipping oil

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 29 / 71


Flows in networks

Example: Shipping oil

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 30 / 71


Flows in networks

Example: Shipping oil

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 31 / 71


Flows in networks

Optimality
Simplex provides a short proof ot the optimality of its solution.
———————————————————————–
Let us partition the nodes of the network into two groups:

No flow can exceed the total capacity of the edges from L to R...
... the solution must be optimal.
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 32 / 71
Flows in networks

Optimality
Max-flow min-cut theorem
The size of the maximum flow in a network equals the capacity of the
smallest (s, t)-cut.

This cut is found by simplex as a by-product.


———————————————————————–
Let f be the flow computed by simplex. Node t is no longer reachable
from s in the residual network Gf .
Let L be the nodes reachable from s in Gf and R = V − L.

Any edge from L to R is at full


capacity (fe = ce ).
Any edge from R to L has zero
flow (fe0 = 0).

(L, R) is a cut in the graph and size(f ) = capacity (L, R).


Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 33 / 71
Flows in networks

Efficiency

Each iteration is efficient: A depth-first (or breadth-first) search can


be used to find an s − t path (O(|E|) time).

———————————————————————–

How many iterations are there?


Suppose all edges have integer capacities ≤ C.
The flow is always increased in an integer amount.
Hence, the maximum flow, and therefore the number of iterations, is at
most C|E|.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 34 / 71


Flows in networks

Efficiency

Each iteration is efficient: A depth-first (or breadth-first) search can


be used to find an s − t path (O(|E|) time).

———————————————————————–

How many iterations are there?


Suppose all edges have integer capacities ≤ C.
The flow is always increased in an integer amount.
Hence, the maximum flow, and therefore the number of iterations, is at
most C|E|.

Simplex performs better!!

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 34 / 71


Flows in networks

Bipartite matching

Perfect matching:

Is it possible to choose couples so that everyone is happy?

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 35 / 71


Flows in networks

Bipartite matching

Perfect matching:

Is it possible to choose couples so that everyone is happy?


———————————————————————–
This problem can be reduced to a maximum-flow problem.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 35 / 71


Flows in networks

Bipartite matching
Perfect matching: Reduction to a maximum-flow problem.
1 Create a new source node, s, connect it to all boys.
2 Connect all girks to a new sink node, t.
3 Associate a capacity of 1 to each edge.

There is a perfect matching iff this network has a flow whose size
equals the number of couples.
———————————————————————–
What if the flow of one edge is 0.52?

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 36 / 71


Flows in networks

Bipartite matching
Perfect matching: Reduction to a maximum-flow problem.
1 Create a new source node, s, connect it to all boys.
2 Connect all girks to a new sink node, t.
3 Associate a capacity of 1 to each edge.

There is a perfect matching iff this network has a flow whose size
equals the number of couples.
———————————————————————–
What if the flow of one edge is 0.52? If all capacities are integers,
then the optimal flow found by our algorithm is integral.
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 36 / 71
Duality

Outline

1 Introduction

2 Flows in networks

3 Duality

4 Zero-sum games

5 The simplex algorithm

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 37 / 71


Duality

Duality
Similarly to the maximum-flow – minimum cut problems...
Every maximization problem has a dual minimization problem.

Example: max x1 + 6x2


x1 ≤ 200 (1)
x2 ≤ 300 (2)
x1 + x2 ≤ 400 (3)
x1 , x2 ≥ 0 (4)
Solution: (x1 , x2 ) = (100, 300), objective value 1900.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 38 / 71


Duality

Duality
Similarly to the maximum-flow – minimum cut problems...
Every maximization problem has a dual minimization problem.

Example: max x1 + 6x2


x1 ≤ 200 (1)
x2 ≤ 300 (2)
x1 + x2 ≤ 400 (3)
x1 , x2 ≥ 0 (4)
Solution: (x1 , x2 ) = (100, 300), objective value 1900. Let’s check it!
Take (1) and add it to six times (2): x1 + 6x2 ≤ 2000. It is impossible to
achieve a profit of more than 2000.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 38 / 71


Duality

Duality
Similarly to the maximum-flow – minimum cut problems...
Every maximization problem has a dual minimization problem.

Example: max x1 + 6x2


x1 ≤ 200 (1)
x2 ≤ 300 (2)
x1 + x2 ≤ 400 (3)
x1 , x2 ≥ 0 (4)
Solution: (x1 , x2 ) = (100, 300), objective value 1900. Let’s check it!
Take (1) and add it to six times (2): x1 + 6x2 ≤ 2000. It is impossible to
achieve a profit of more than 2000.
Multiply (1), (2) and (3) by 0, 5 and 1 respectively and add the results:

x1 + 6x2 ≤ 1900
This is a certificate of optimality!
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 38 / 71
Duality

Duality
Where do these multipliers come from?
Mutiplier Inequality
y1 x1 ≤ 200
y2 x2 ≤ 300
y3 x1 + x2 ≤ 400
These yi ’s must be nonnegative (otherwise ≤ becomes ≥). After multiplying
and summing:
(y1 + y3 )x1 + (y2 + y3 )x2 ≤ 200y1 + 300y2 + 400y3
We want the left-hand side to look like our objective function x1 + 6x2 . That is,
we’d like (y1 + y3 ) to be at least 1 and (y2 + y3 ) to be at least 6.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 39 / 71


Duality

Duality
Where do these multipliers come from?
Mutiplier Inequality
y1 x1 ≤ 200
y2 x2 ≤ 300
y3 x1 + x2 ≤ 400
These yi ’s must be nonnegative (otherwise ≤ becomes ≥). After multiplying
and summing:
(y1 + y3 )x1 + (y2 + y3 )x2 ≤ 200y1 + 300y2 + 400y3
We want the left-hand side to look like our objective function x1 + 6x2 . That is,
we’d like (y1 + y3 ) to be at least 1 and (y2 + y3 ) to be at least 6.
———————————————————————–
Upper bound for the objective value:  
 y1 , y2 , y3 ≥ 0
 
x1 + 6x2 ≤ 200y1 + 300y2 + 400y3 if y1 + y3 ≥ 1
 
y2 + y3 ≥ 6
 

To get a bound as tight as possible we have to minimize:


200y1 + 300y2 + 400y3 ... a new LP!
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 39 / 71
Duality

Duality
A new LP!

min 200y1 + 300y2 + 400y3


y1 + y3 ≥ 1
y2 + y3 ≥ 6
y1 , y2 , y3 ≥ 0

Any feasible value of this dual LP is an upper bound on the original primal LP.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 40 / 71


Duality

Duality
A new LP!

min 200y1 + 300y2 + 400y3


y1 + y3 ≥ 1
y2 + y3 ≥ 6
y1 , y2 , y3 ≥ 0

Any feasible value of this dual LP is an upper bound on the original primal LP.

If we find a pair of primal and dual feasible values that are equal, then they must both
be optimal.
Primal: (x1 , x2 ) = (100, 300); Dual: (y1 , y2 , y3 ) = (0, 5, 1)
They both have value 1900. Optimality is certified.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 40 / 71


Duality

Duality
Primal LP: Dual LP:

max cT x min yT b
Ax ≤ b yT A ≥ cT
x≥0 y≥0

By construction, any feasible solution of the dual is an upper bound on


any feasible solution of the primal. But moreover, their optima coincide!
Duality theorem
If a linear program has a bounded optimum, then so does its dual, and
the two optimum values coincide.

In many cases, it is possible to assign interpretations to the dual


variables.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 41 / 71


Duality

Duality
Most general case of LP:
n variables
I: set of inequalities
E: set of equalities
N: subset of nonnegative variables
Primal LP: Dual LP:

max c1 x1 + . . . +cn xn min b1 y1 + . . . +bm yn


ai1 x1 + . . . + ain xn ≤ bi for i ∈ I a1j y1 + . . . + amj ym ≥ cj for j ∈ N
ai1 x1 + . . . + ain xn = bi for i ∈ E a1j y1 + . . . + amj ym = cj for j 6∈ N
xj ≥ 0 for j ∈ N yi ≥ 0 for i ∈ I

Duality theorem
If a linear program has a bounded optimum, then so does its dual, and
the two optimum values coincide.
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 42 / 71
Duality

Visualizing duality
The shortest-path problem between s and t can be solved by pulling s away
from t.

It is a minimization problem and... we are pulling nodes away?

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 43 / 71


Duality

Visualizing duality
The shortest-path problem between s and t can be solved by pulling s away
from t.

It is a minimization problem and... we are pulling nodes away?


By pulling s away from t we solve the dual of the shortest-path problem!
In words, the dual problem is to stretch s and t as far apart as possible,
subject to the constraint that the endpoints of any edge {u, v } are separated
by a distance of at most wuv .
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 43 / 71
Zero-sum games

Outline

1 Introduction

2 Flows in networks

3 Duality

4 Zero-sum games

5 The simplex algorithm

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 44 / 71


Zero-sum games

Zero-sum games

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 45 / 71


Zero-sum games

Zero-sum games
Rock-Paper-Scissorss game. Payoff matrix (Row’s gain and Column’s loss):
Column
r p s
G= r 0 −1 1

Row
p 1 0 −1
s −1 1 0

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 46 / 71


Zero-sum games

Zero-sum games
Rock-Paper-Scissorss game. Payoff matrix (Row’s gain and Column’s loss):
Column
r p s
G= r 0 −1 1

Row
p 1 0 −1
s −1 1 0
Let’s look for a good strategy for Row.
Row plays r with probability x1 , p with probability x2 and s with
probability x3 (x = (x1 , x2 , x3 )).
Column’s strategy is y = (y1 , y2 , y3 ).
On a given round, the probability that Row plays the ith move and
Column de jth move is xi yj .

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 46 / 71


Zero-sum games

Zero-sum games
Rock-Paper-Scissorss game. Payoff matrix (Row’s gain and Column’s loss):
Column
r p s
G= r 0 −1 1

Row
p 1 0 −1
s −1 1 0
Let’s look for a good strategy for Row.
Row plays r with probability x1 , p with probability x2 and s with
probability x3 (x = (x1 , x2 , x3 )).
Column’s strategy is y = (y1 , y2 , y3 ).
On a given round, the probability that Row plays the ith move and
Column de jth move is xi yj .
The expected (average) payoff is:
X X
Gij · Prob[Row plays i, Column plays j] = Gij xi yj
i,j i,j

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 46 / 71


Zero-sum games

Zero-sum games
The expected (average) payoff is:
X X
Gij · Prob[Row plays i, Column plays j] = Gij xi yj
i,j i,j

For example, if Row plays a random strategy x = (1/2, 1/2, 0) and Column
plays r , i.e., y = (1, 0, 0), the average payoff is:

1 1 1
· 0 + · 1 + 0 · −1 =
2 2 2
Row wants to maximize this, while Column wants to minimize it.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 47 / 71


Zero-sum games

Zero-sum games
The expected (average) payoff is:
X X
Gij · Prob[Row plays i, Column plays j] = Gij xi yj
i,j i,j

For example, if Row plays a random strategy x = (1/2, 1/2, 0) and Column
plays r , i.e., y = (1, 0, 0), the average payoff is:

1 1 1
· 0 + · 1 + 0 · −1 =
2 2 2
Row wants to maximize this, while Column wants to minimize it.
———————————————————————–
If Row plays a completely random strategy x = (1/3, 1/3, 1/3) and Column
plays any strategy y = (y1 , y2 , y3 ):
!
X X 1 X X1 X
Gij xi yj = Gij · yj = yj Gij = yj · 0 = 0
3 3
i,j i,j j i j

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 47 / 71


Zero-sum games

Zero-sum games

Let’s think about this in a slightly different way, by considering two


scenarios:
1 First Row announces her strategy, and then Column picks his.
2 First Column announces his strategy, and then Row chooses hers.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 48 / 71


Zero-sum games

Zero-sum games

Let’s think about this in a slightly different way, by considering two


scenarios:
1 First Row announces her strategy, and then Column picks his.
2 First Column announces his strategy, and then Row chooses hers.

———————————————————————–

If both play optimally, then it doesn’t hurt a player to announce his or


her strategy in advance!

This property is a consequence of linear programming duality.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 48 / 71


Zero-sum games

Zero-sum games
Nonsymmetric game:
m t
G= e 3 −1
s −2 1
Suppose Row announces that she will play the mixed strategy x = (1/2, 1/2).
What should Column do?

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 49 / 71


Zero-sum games

Zero-sum games
Nonsymmetric game:
m t
G= e 3 −1
s −2 1
Suppose Row announces that she will play the mixed strategy x = (1/2, 1/2).
What should Column do?
———————————————————————–
The best response of Column is the pure strategy y = (0, 1).
In fact, once Row’s strategy is fixed, there is always a pure strategy that is
optimal: either move m with payoff 3x1 − 2x2 , or t with payoff −x1 + x2 .

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 49 / 71


Zero-sum games

Zero-sum games
Nonsymmetric game:
m t
G= e 3 −1
s −2 1
Suppose Row announces that she will play the mixed strategy x = (1/2, 1/2).
What should Column do?
———————————————————————–
The best response of Column is the pure strategy y = (0, 1).
In fact, once Row’s strategy is fixed, there is always a pure strategy that is
optimal: either move m with payoff 3x1 − 2x2 , or t with payoff −x1 + x2 .
———————————————————————–
Row is forced to announce x before Column plays. Row knows that Column’s
best response will achieve an expected payoff of min{3x1 − 2x2 , −x1 + x2 }.
Row should choose a x that maximizes her payoff against this best response:
Pick (x1 , x2 ) that maximizes min{3x1 − 2x2 , −x1 + x2 }.
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 49 / 71
Zero-sum games

Zero-sum games
Pick (x1 , x2 ) that maximizes min{3x1 − 2x2 , −x1 + x2 }.
———————————————————————–
The following are equivalent:
max z
z = min{3x1 − 2x2 , −x1 + x2 } z ≤ 3x1 − 2x2
z ≤ − x1 + x2

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 50 / 71


Zero-sum games

Zero-sum games
Pick (x1 , x2 ) that maximizes min{3x1 − 2x2 , −x1 + x2 }.
———————————————————————–
The following are equivalent:
max z
z = min{3x1 − 2x2 , −x1 + x2 } z ≤ 3x1 − 2x2
z ≤ − x1 + x2
———————————————————————–
Row must choose x1 and x2 to maximize this z:
max z
−3x1 + 2x2 + z ≤ 0
x1 − x2 + z ≤ 0
x1 + x2 = 1
x1 , x2 ≥ 0
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 50 / 71
Zero-sum games

Zero-sum games
Symmetrically, if Column has to announce his strategy first, his best bet is to
choose the mixed strategy y that minimizes his loss under Row’s best
response, in other words:
Pick (y1 , y2 ) that minimizes max{3y1 − y2 , −2y1 + y2 }.
———————————————————————–
The following are equivalent:
min w
w = max{3y1 − y2 , −2y1 + y2 } w ≥3y1 − y2
w ≥ − 2y1 + y2

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 51 / 71


Zero-sum games

Zero-sum games
Symmetrically, if Column has to announce his strategy first, his best bet is to
choose the mixed strategy y that minimizes his loss under Row’s best
response, in other words:
Pick (y1 , y2 ) that minimizes max{3y1 − y2 , −2y1 + y2 }.
———————————————————————–
The following are equivalent:
min w
w = max{3y1 − y2 , −2y1 + y2 } w ≥3y1 − y2
w ≥ − 2y1 + y2
———————————————————————–
Column must choose y1 and y2 to minimize this w:
min w
−3y1 + y2 + w ≥ 0
2y1 − y2 + w ≥ 0
y1 + y2 = 1
y1 , y2 ≥ 0
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 51 / 71
Zero-sum games

Zero-sum games

Row must choose x1 and x2 to Column must choose y1 and y2 to


maximize this z: minimize this w:
max z min w
−3x1 + 2x2 + z ≤ 0 −3y1 + y2 + w ≥ 0
x1 − x2 + z ≤ 0 2y1 − y2 + w ≥ 0
x1 + x2 = 1 y1 + y2 = 1
x1 , x2 ≥ 0 y1 , y2 ≥ 0
———————————————————————–
These two LPs are dual to each other. Hence, they have the same optimum!

In our game the optimum is 1/7. It is realized when Row plays with optimal
strategy (3/7, 4/7) and Column with optimal strategy (2/7, 5/7).

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 52 / 71


Zero-sum games

Zero-sum games

This example can be generalized to many games to show the


existence of strategies that are optimal for both players and achieve
the same optimum value.

min-max theorem
X X
max min Gij xi yj = min max Gij xi yj
x y y x
i,j i,j

Value (row announces strategy) = Value (Column announces strategy)

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 53 / 71


The simplex algorithm

Outline

1 Introduction

2 Flows in networks

3 Duality

4 Zero-sum games

5 The simplex algorithm

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 54 / 71


The simplex algorithm

The simplex algorithm

High level strategy


1 let v be any vertex of the feasible region

2 while there is a neighbor v 0 of v with better


objective value: set v = v 0

This strategy has to work in the n-dimensional space.


A linear equation defines a hyperplane in the space Rn
A linear inequality defines a half-space in Rn
The feasible region is the intersction of the half-spaces, a convex
polytope.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 55 / 71


The simplex algorithm

The simplex algorithm


Vertex: Unique point at which some subset of hyperplanes meet.

max x1 + 6x2 +13x3


x1 ≤200 (1)
x2 ≤300 (2)
x1 + x2 + x3 ≤400 (3)
x2 + 3x3 ≤600 (4)
x1 ≥0 (5)
x2 ≥0 (6)
x3 ≥0 (7)
More formally: Pick a subset of the inequalities. If there is a unique point that
satisfies them with equality, and this point is feasible, then it is a vertex.

Each vertex is specified by a set of n inequalities.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 56 / 71


The simplex algorithm

The simplex algorithm


Vertex: Unique point at which some subset of hyperplanes meet.

Each vertex is specified by a set of n inequalities.

Attention: The same vertex might be


generated by different subsets of
inequalities, e.g., vertex B is generated
by {(2), (3), (4)} and by {(2), (4), (5)}.
We’ll consider these degenerate
vertices later.

Two vertices are neighbors if they have n − 1 defining inequalities in common.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 57 / 71


The simplex algorithm

The simplex algorithm

On each iteration, simplex has two tasks:


Task 1: Check whether the current vertex is optimal (if so, halt).
Task 2: Determine where to move next.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 58 / 71


The simplex algorithm

The simplex algorithm

On each iteration, simplex has two tasks:


Task 1: Check whether the current vertex is optimal (if so, halt).
Task 2: Determine where to move next.
———————————————————————–
These tasks are easy if the vertex is at the origin.

max cT x
Ax ≤ b
x≥0

Assume that the origin is feasible, then it is a vertex (it is the unique
point at which the n inequalities {x1 ≥ 0, . . . , xn ≥ 0} are tight).

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 58 / 71


The simplex algorithm

The simplex algorithm

On each iteration, simplex has two tasks:


Task 1: Check whether the current vertex is optimal (if so, halt).
Task 2: Determine where to move next.
———————————————————————–
These tasks are easy if the vertex is at the origin.

max cT x
Ax ≤ b
x≥0

Assume that the origin is feasible, then it is a vertex (it is the unique
point at which the n inequalities {x1 ≥ 0, . . . , xn ≥ 0} are tight).
Task 1: The origin is optimal iff all ci ≤ 0.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 58 / 71


The simplex algorithm

The simplex algorithm


These tasks are easy if the vertex is at the origin.
Task 2: We can move by increasing some xi for which ci > 0. How
much can we increase it? Until we hit some other constraint.
Example:
max 2x1 + 5x2
2x1 − x2 ≤4 (1)
x1 + 2x2 ≤9 (2)
−x1 + x2 ≤3 (3)
x1 ≥0 (4)
x2 ≥0 (5)

Simplex can be started at the origin, constraints {(4), (5)}. To move, we can
realease (5) and increase x2 gradually until it hits a constraint. It hits (3) with
x2 = 3 which becomes tight. The new vertex is given by {(4), (3)}.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 59 / 71


The simplex algorithm

The simplex algorithm

We will transform the current vertex u into the origin:


The usual coordinate system (x1 , . . . , xn ) will be changed to the
coordinate system (y1 , . . . , yn ) of the “local view” from u.
If one of the inequalities defining u is ai · x ≤ bi , the distance from
x to that hyperplane is:

yi = bi − ai · x

We can rewrite the LP in this new coordinate frame.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 60 / 71


The simplex algorithm

The simplex algorithm

The revised “local” LP has the following properties:

1 It includes the inequalities y ≥ 0, which are simply the


transformed versions of the inequalities defining u.
2 u itself is the origin in y-space.
3 The cost function becomes max cu + c̃ T y, where cu is the value of
the objective function at u and c̃ T is a transformed cost vector.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 61 / 71


The simplex algorithm

The simplex algorithm

The revised “local” LP has the following properties:

1 It includes the inequalities y ≥ 0, which are simply the


transformed versions of the inequalities defining u.
2 u itself is the origin in y-space.
3 The cost function becomes max cu + c̃ T y, where cu is the value of
the objective function at u and c̃ T is a transformed cost vector.

We are back to the situation we know how to handle!

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 61 / 71


The simplex algorithm

The simplex algorithm

Current vertex: {(4), (5)} (origin)


Initial LP: Objective value: 0

max 2x1 + 5x2 Move: increase x2


2x1 − x2 ≤4 (1) (5) is released, (3) becomes tight.
x1 + 2x2 ≤9 (2) Stop at x2 = 3.
−x1 + x2 ≤3 (3) New vertex {(4), (3)} has local
x1 ≥0 (4) coordinates (y1 , y2 ):
x2 ≥0 (5) y1 = x1
y2 = 3 + x1 − x2

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 62 / 71


The simplex algorithm

The simplex algorithm

Current vertex: {(4), (3)}


Rewritten LP: Objective value: 15

max 15 + 7y1 − 5y2 Move: increase y1


y1 + y2 ≤7 (1) (4) is released, (2) becomes tight.
3y1 − 2y2 ≤3 (2) Stop at y1 = 1.
y2 ≥0 (3)
New vertex {(2), (3)} has local
y1 ≥0 (4) coordinates (z1 , z2 ):
−y1 + y2 ≤3 (5) z1 = 3 − 3y1 + 2y2
z2 = y2

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 63 / 71


The simplex algorithm

The simplex algorithm

Current vertex: {(2), (3)}


Objective value: 22
Rewritten LP:
7 1 Optimal: all ci < 0.
max 22 − z1 − z2 Solve (2), (3) (in original LP) to get
3 3
1 5 optimal solution: (x1 , x2 ) = (1, 4).
− z1 + z2 ≤6 (1)
3 3
z1 ≥0 (2)
z2 ≥0 (3)
1 2
z1 − z2 ≤1 (4)
3 3
1 1
z1 + z2 ≤4 (5)
3 3

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 64 / 71


The simplex algorithm

The simplex algorithm. The starting vertex


What if the origin is not a feasible vertex?

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 65 / 71


The simplex algorithm

The simplex algorithm. The starting vertex


What if the origin is not a feasible vertex?
Consider the LP in standard form:
max cT x
Ax = b
x≥0
Make all bi nonnegative (if bi < 0 then multiply by −1).

Create a new LP as follows:


Create m new artificial variables z1 , . . . , zm ≥ 0 where m is the number
of equations.
Add zi to the left-hand side of the ith equation.
Let the objective function be: min z1 + z2 + . . . + zm

A potential starting vertex for this LP is: zi = bi for all i and all other variables
zero. Thus, it can be solved by simplex to obtain the optimum solution.
Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 65 / 71
The simplex algorithm

The simplex algorithm. The starting vertex

A potential starting vertex for this LP is: zi = bi for all i and all other
variables zero. Thus, it can be solved by simplex to obtain the optimum
solution.

———————————————————————–

Two cases can happen:


1 z1 + . . . + zm = 0. From the optimum vertex of the new LP we get a
starting feasible vertex of the original LP (just by ignoring the zi ’s).
2 z1 + . . . + zm > 0. The original linear program is infeasible (it
needs some nonzero zi ’s to become feasible).

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 66 / 71


The simplex algorithm

The simplex algorithm. Degeneracy

Vertex B is degenerate. It is the intersection of more than n = 3 faces of the


polyhedron ({(2), (3), (4), (5)}).

If we take any set: {(2), (3), (4)},


{(2), (3), (5)}, {(2), (4), (5)}, {(3), (4), (5)},
and solve the corresponding equations, we
get the same solution (0, 300, 100).

Problem: Simplex may return a suboptimal


degenerate vertex (all neighbors have the
same objective function).

Possible solution: Perturbation. Change


each b1 by a tiny random amount bi ± i to
differentiate the solutions of the linear
systems.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 67 / 71


The simplex algorithm

The simplex algorithm. Unboundedness

Unbounded LP: The objective function can be made arbitrarily large


(or small, if it’s a minimization problem).

Detection: In exploring the neighborhood of a vertex, simplex will


notice that taking out an inequality and adding another one leads to an
undetermined system of equations that has an infinity of solutions.
Simplex will halt and complain.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 68 / 71


The simplex algorithm

The running time of simplex


Consider the generic LP: A vertex has at most n · m neighbors
(choose which inequality to drop and
max cT x which new one to add).
Ax ≤ 0 Finding the cost of a vertex is a dot
x≥0 product.
Rewriting the LP in terms of current
local coordinates is O((m + n)n) (the
with n variables and m inequality local view only changes slightly
constraints. between iterations).
———————————————————————–
At the local view the objective function is: max cu + c̃y.
A promising direction to move is given by any c̃i > 0 (if there is none, then the
current vertex is optimal and simplex halts).
It is easy to determine how much yi can be increased before some other
inequality is violated (if yi can be increased indefinitely, then the LP is
unbounded).
The running time per iteration is O(mn)

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 69 / 71


The simplex algorithm

The running time of simplex

The running time per iteration is O(mn)

How many iterations could there be?

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 70 / 71


The simplex algorithm

The running time of simplex

The running time per iteration is O(mn)

How many iterations


 could
 there be?
m+n
No more than , which is an upper bound on the number of
n
vertices.
This is exponential in n....

Although simplex performs well in practice, it is an exponential time


algorithm.

Fortunately, polynomial time algorithms to solve LPs exist.

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 70 / 71


The simplex algorithm

Bibliography

Bibliogaphy:

Algorithms
S. Dasgupta, C.H. Papadimitriou, and U.V. Vazirani

Jorge Júlvez (Universidad de Zaragoza) Linear Programming and Reductions 71 / 71

You might also like