Você está na página 1de 115

EXMENES RESUELTOS PROGRAMACIN III

INFORMTICA SISTEMAS Y GESTIN


DELEGACIN DE ALUMNOS CENTRO ASOCIADO DE BALEARES

EXMENES PROGRAMACIN III

Escuela Universitaria de Informatica de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Programacion III - Convocatoria de Febrero


Examen primera semana - Curso 1995-96
Problema 1 (5 puntos). El tiempo de ejecucion de un algoritmo viene dado por T (n) = 2n2 . Encontrar una forma e ciente de calcular T (n), suponiendo que el coste de multiplicar dos enteros es proporcional a su tama~o en representacion n binaria. Problema 2 (5 puntos). Un recubrimiento de vertices de un grafo no dirigido G = hV Ai es un conjunto de vertices tales que cada arista del grafo incide en, al menos, un vertice de V. Dise~ar un algoritmo que, dado un grafo no dirigido, n calcule un recubrimiento de vertices de tama~o m nimo para un grafo dado. n

La resolucion de cada problema debe incluir: Eleccion razonada del esquema algor tmico. Descripcion del esquema usado e identi cacion con el problema. Estructuras de datos. Algoritmo completo a partir del re namiento del esquema general. Estudio del coste. Segun el esquema elegido hay que especi car, ademas:
Voraz: demostracion de optimalidad. Divide y venceras: preorden bien fundado. Vuelta atras: descripcion del arbol de busqueda asociado.

Escuela Universitaria de Informatica de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Programacion III - Convocatoria de Febrero


Examen segunda semana - Curso 1995-96
Problema 1 (5 puntos). Las 28 chas de domino son de la forma (i j ) con = 1 : : : 6. Una cha de domino puede colocarse a continuacion de la anterior si coinciden los valores de los extremos que se tocan. Por ejemplo, a continuacion de la cha (1 2) puede colocarse la (2 4). Dise~ar un algoritmo que produzca n todas las cadenas permisibles que contengan todas las chas del domino.
i j

cfn fn

Sugerencia: Utilizad la siguiente relacion:


0 10 0 1 0 B 0 0 1 CB @ A@
a b c

Problema 2 (5 puntos). Dada la sucesion de nida como fn = afn;3 + bfn;2 + n ;1 se pide dise~ar un algoritmo que calcule en tiempo logar tmico el termino
;3 fn;2 fn;1
fn

1 0 C=B A @

;2 fn;1
fn fn

1 C A

La resolucion de cada problema debe incluir: Eleccion razonada del esquema algor tmico. Descripcion del esquema usado e identi cacion con el problema. Estructuras de datos. Algoritmo completo a partir del re namiento del esquema general. Estudio del coste. Segun el esquema elegido hay que especi car, ademas:
Voraz: demostracion de optimalidad. Divide y venceras: preorden bien fundado. Vuelta atras: descripcion del arbol de busqueda asociado.

Escuela Universitaria de Informatica de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Programacion III - Convocatoria de Septiembre 96


Examen Original
Problema 1 (5 puntos). Un cartografo acaba de terminar el plano de su pais, que incluye informacion sobre las carreteras que unen las principales ciudades y sus longitudes. Ahora quiere a~adir una tabla en la que se recoja la distancia n entre cada par de ciudades del mapa (entendiendo por distancia la longitud del camino mas corto entre las dos). Escribir un algoritmo que le permita realizar esa tabla. Problema 2 (5 puntos). Se consideran las funciones m(x) = 3x y d(x) = x 2 (donde ` ' representa la division entera). Dise~ar un algoritmo que, dados dos n numeros a y b, encuentre una forma de llegar de a a b mediante aplicaciones sucesivas de m y d. Por ejemplo, se puede pasar de 7 a 2 mediante

2 = d(d(m(d(7))))

La resolucion de cada problema debe incluir, por este orden: 1. Eleccion razonada del esquema algor tmico. 2. Descripcion del esquema usado e identi cacion con el problema. 3. Estructuras de datos. 4. Algoritmo completo a partir del re namiento del esquema general. 5. Estudio del coste. Segun el esquema elegido hay que especi car, ademas:
Voraz: demostracion de optimalidad. Divide y venceras: preorden bien fundado. Vuelta atras: descripcion del arbol de busqueda asociado.

Escuela Universitaria de Informatica de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Soluciones a los examenes de Septiembre 1996


Equipo docente de la asignatura

Programacion III

Problema 1
Un cartografo acaba de terminar el plano de su pais, que incluye informacion sobre las carreteras que unen las principales ciudades y sus longitudes. Ahora quiere a~adir una tabla en la que se recoja la distancia entre cada par de ciudades del n mapa (entendiendo por distancia la longitud del camino mas corto entre las dos). Escribir un algoritmo que le permita realizar esa tabla.

Eleccion razonada del esquema algor tmico.


Para hallar la distancia m nima desde un vertice de un grafo a cada uno de los demas vertices contamos con el algoritmo voraz de Dijkstra. Basta, pues, con aplicarlo para cada una de las ciudades, siendo estas los vertices, las carreteras las aristas del grafo, y sus longitudes los pesos de las aristas.
Cuidado: no hay que confundir este problema (llamado \de caminos m nimos) con el problema de dar un arbol de expansion m nimo, que resuelven algoritmos como el de Prim o Kruskal. En este caso, un arbol de expansion m nimo ser a un subconjunto de carreteras que conectara todas las ciudades y cuya longitud total fuera m nima pero esa condicion no nos asegura que la distancia entre cada par de ciudades sea la m nima posible. Pensad contrajemplos en caso de duda.

Descripcion del esquema usado e identi cacion con el problema.


Nos ahorramos la explicacion, que podeis encontrar en el Brassard/Bratley, pag. 89.

Estructuras de datos.
El conjunto de ciudades y carreteras viene representado por un grafo no orientado con pesos. Podemos implementarlo como una matriz de adyacencia, como una lista de listas de adyacencia, etc. Ademas necesitaremos otra matriz que acumule las distancias m nimas entre ciudades y que sirva como resultado.

Algoritmo completo a partir del re namiento del esquema general.


La unica variacion respecto al algoritmo de Dijkstra es que necesitamos saber la distancia m nima entre cada par de ciudades, no solo entre una ciudad y todas las demas. Por ello, es necesario aplicar Dijkstra n veces, siendo n el numero de ciudades (en rigor, no es necesario aplicarlo sobre la ultima ciudad, pues los caminos m nimos a esa ciudad ya han sido obtenidos en aplicaciones anteriores.
vector 1. . . N,1. . . N] para cada vertice v hacer m dijkstra(g,v,m) m

fun mapa (g:grafo) dev vector 1. . . N,1. . . N] de entero

fpara dev m fun

donde el algoritmo de dijkstra se implementa mediante una funcion dijkstra(g,v,m) que devuelve la matriz m con la informacion a~adida correspondiente a las distancias entre el n grafo v y todos los demas grafos de g.

Estudio del coste.


El coste del algoritmo depende de la implementacion para grafos que se escoja. Si se implementa como una matriz de adyacencia, sabemos que el coste del algoritmo de Dijkstra es cuadratico (O(n2 )). Como hemos de aplicarlo n veces (o n ; 1, que tambien es de orden n), el coste del algoritmo completo es O(n3 ). 2

Problema 2
Se consideran las funciones m(x) = 3x y d(x) = x 2 (donde ` ' representa la division entera). Dise~ar un algoritmo que, dados dos numeros a y b, encuentre n una forma de llegar de a a b mediante aplicaciones sucesivas de m(x) y d(x). Por ejemplo, se puede pasar de 7 a 2 mediante 2 = d(d(m(d(7))))

Como este problema esta en relacion muy estrecha con la practica del curso 96-97, no ofrecemos todav a la solucion.

Problema 3
En una clase hay f las y c columnas de pupitres. Delante de la primera la se encuentra la pizarra. a) Dise~ar un algoritmo que reparta los f c alumnos de forma que, al mirar hacia n la pizarra, ninguno se vea estorbado por otro alumno mas alto que el. b) A mitad de curso se coloca una pizarra adicional en una de las paredes adyacentes con la primera pizarra. Dise~ar un algoritmo que coloque a los alumnos de forma n que puedan mirar tambien a esa segunda pizarra sin estorbarse. Este algoritmo debe sacar partido de la colocacion anterior.

Eleccion razonada del esquema algor tmico.


Para que nadie tenga un alumno mas alto que el al mirar a la pizarra, es necesario que, dentro de cada columna, los alumnos esten ordenados segun su altura de mayor a menor. 3

Para resolver el apartado a) de forma e ciente basta con dividir los f c alumnos en c subconjuntos de f elementos escogidos al azar, y a continuacion debe ordenarse cada uno de esos subconjuntos. Cada uno de ellos sera una columna en la clase. Como algoritmo de ordenacion puede escogerse cualquiera de los estudiados nosotros utilizaremos el algoritmo divide y venceras de fusion, por ser mas e ciente asintoticamente en el caso peor (es O(n log n)). Al colocar una segunda pizarra adyacente a la primera, los alumnos de cada la deben estar, a su vez, ordenados entre s . Para que esten ordenadas las columnas y las las, es necesario ordenar a todos los alumnos de menor a mayor, y colocarlos en la clase de forma que el mas bajito ocupe el pupitre que esta en la interseccion de las dos pizarras, y el mas alto en el vertice opuesto de la clase. Por lo tanto, para obtener la disposicion nal de los alumnos en el apartado b) debe hacerse una ordenacion de f c elementos. Pero si aprovechamos la disposicion anterior no es necesario, esta vez, aplicar ningun algoritmo de ordenacion: basta con realizar una fusion de los c subconjuntos ya ordenados (equivaldr a al ultimo paso de un algoritmo de ordenacion por fusion en el que el factor de division fuera c). As , la ordenacion nal puede obtenerse en tiempo lineal.

Descripcion del esquema usado e identi cacion con el problema.


El esquema divide y venceras es una tecnica recursiva que consiste en dividir un problema en varios subproblemas del mismo tipo. Las soluciones a estos subproblemas se combinan a continuacion para dar la solucion al problema. Cuando los subproblemas son mas peque~os n que un umbral pre jado, se resuelven mediante un algoritmo espec co. Si su tama~o es n mayor, se vuelven a descomponer. El esquema es el siguiente:

fun divide y venceras (problema) si su cientemente-simple (problema) entonces dev solucion-simple (problema) si no hacer

fp

fsi un

: : : pk g descomposicion(problema) para cada si hacer si divide y venceras(pi) fpara dev combinacion(s1 : : : sk )


1

Tama~o umbral y solucion simple: El preorden bien fundado para los problemas se deriva n directamente del orden total entre el tama~o de los subconjuntos problema. Podemos tomar n como tama~o umbral n=1, caso en el que la ordenacion es trivial y consiste simplemente en n devolver el elemento.

Descomposicion: Dividiremos el conjunto problema en dos subbconjuntos formados por los n 2 primeros elementos por un lado y el resto por otro. Combinacion: Es necesario fundir los dos subconjuntos ordenados, mediante un bucle que toma cada vez el menor elemento de entre los primeros de uno y otro subconjunto todav a sin seleccionar.

Estructuras de datos.
La unica estructura de datos que necesitamos es una matriz de enteros de tama~o c f que n almacene las alturas de los alumnos. Tambien podemos utilizar un vector de tama~o c f , n sabiendo que cada f elementos representan una columna.

Algoritmo completo a partir del re namiento del esquema general.


Llamaremos a a la funcion que obtiene la ordenacion requerida en el apartado a), y b a la que soluciona el apartado b), es decir, obtiene una ordenacion total a partir de la que se tiene en a). La funcion a es la siguiente:

fun a (clase: vector 1. . . f,1... . . c] de enteros) dev vector 1. . . f,1... . . c] de enteros para i=1 hasta c hacer fpara dev clase un
clase 1 : : : f i] ordenacion(clase 1 : : : f i])

La funcion de ordenacion equivale a la funcion general divide y venceras, que modi caremos ligeramente para incluir como argumento vectores que sean siempre del mismo tama~o: n

proc ordenacion (v: vector 1. . . n] i,j: entero ) dev vector 1. . . n] si i = j entonces dev v si no hacer
k (i + j 2) ordenacion (v,i,k) ordenacion (v,k+1,j) fusion (v,i,j,2)

fsi fproc

La funcion de fusion tiene cuatro parametros: el vector, el principio y nal del tramo que contiene a los dos subvectores que hay que fusionar, y el factor de division empleado. Para el apartado a) podr amos ahorrarnos este ultimo argumento (es 2), pero esa generalizacion nos permitira usar la misma funcion en el apartado b).

f Inicializa el vector solucion g v' vector 1. . . n] f Inicializa punteros al comienzo de los vectores por fusionar g para k = 1 hasta factor hacer i inicio + factor (k ; 1) fpara I f i ::: i g f Selecciona el menor elemento de entre los principios de vector para incluirlo en la solucion, y a continuacion lo borra para que no vuelva a ser considerado g
k
1

proc fusion (v: vector 1. . . n] inicio, nal,factor: entero ) dev vector 1. . . n]

factor

ix

elemento que maximiza v ix] v' h] v ix] si ix < inicio + factor x ; 1 hacer ix ix + 1 v

para h=inicio hasta nal hacer

si no hacer fsi fpara


v'

I Infi g
x

fproc

La funcion b debe conseguir una ordenacion completa del conjunto de alumnos, pero debe tener en cuenta que ya existe una ordenacion parcial entre ellos: los alumnos de cada columna estan ordenados entre s . Si representamos el conjunto de los alumnos como un vector de c f elementos, en el que los f primeros elementos corresponden a la primera columna, los f siguientes a la segunda, etc, el problema queda solucionado llamando a la funcion de fusion de nida anteriormente, pero utilizando un factor de division c en lugar de 2:

proc b (v: vector 1. . . c*f], entero: c) dev vector 1. . . c*f]


fusion (v,1,c*f,c)

fproc

Estudio del coste.


apartado a

La ordenacion por fusion tiene un coste que cumple: ya que el algoritmo de fusion tiene un coste O(n) (consta de dos bucles consecutivos). De esa igualdad se obtiene un coste O(n log n. Como se realizan c ordenaciones de f elementos cada una, el coste total es O(cf log f ). Mediante una ordenacion total habr amos resuelto n tambien el problema, pero con un coste O(cf log cf ) (ya que el tama~o del problema ser a c f ).
apartado b

T (n) = 2T (n=2) + cte n

Se resuelve mediante una llamada al algoritmo de fusion, que tiene un coste lineal como el tama~o del problema es c f , el coste es O(c f ). El coste es mucho menor que en el caso n en que no aprovecharamos la ordenacion parcial que se obtiene en el apartado a.

Problema 4
Se planea conectar entre s todos los pueblos de una cierta region mediante carreteras que sustituyan los antiguos caminos vecinales. Se dispone de un estudio que enumera todas las posibles carreteras que podr an construirse y cual ser a el coste de construir cada una de ellas. Encontrar un algoritmo que permita seleccionar, de entre todas las carreteras posibles, un subconjunto que conecte todos los pueblos de la region con un coste global m nimo.

Eleccion razonada del esquema algor tmico.


Si interpretamos los datos como un grafo en el que los pueblos son los vertices y las carreteras son aristas cuyos pesos son el coste de construccion, el problema no es otro que el de hallar un arbol de expansion m nimo para ese grafo. En efecto, un arbol de expansion m nimo es un conjunto de aristas que conectan todos los vertices del grafo en el que la suma de los pesos es m nima (por tanto, el coste de construir el subconjunto de carreteras es m nimo). 7

Para resolverlo podemos usar cualquiera de los dos algoritmos voraces estudiados que resuelven este problema: el de Kruskal o el de Prim.
<Cuidado! No debe confundirse este problema con el de encontrar los caminos m nimos entre un vertice y el resto. Ver problema 1

Descripcion del esquema usado e identi cacion con el problema.


Nos ahorramos la descripcion del resto del problema. Podeis encontrarla en la pagina 83 del Brassard/Bratley.

Escuela Universitaria de Informatica de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Programacion III - Convocatoria de Septiembre 96


Examen de reserva
Problema 1 (5 puntos). En una clase hay f las y c columnas de pupitres. Delante de la primera la se encuentra la pizarra. a) Dise~ar un algoritmo que reparta los f c alumnos de forma que, al mirar n hacia la pizarra, ninguno se vea estorbado por otro alumno mas alto que el. b) A mitad de curso se coloca una pizarra adicional en una de las paredes adyacentes con la primera pizarra. Dise~ar un algoritmo que coloque a los alumnos n de forma que puedan mirar tambien a esa segunda pizarra sin estorbarse. Este algoritmo debe sacar partido de la colocacion anterior. Problema 2 (5 puntos). Se planea conectar entre s todos los pueblos de una cierta region mediante carreteras que sustituyan los antiguos caminos vecinales. Se dispone de un estudio que enumera todas las posibles carreteras que podr an construirse y cual ser a el coste de construir cada una de ellas. Encontrar un algoritmo que permita seleccionar, de entre todas las carreteras posibles, un subconjunto que conecte todos los pueblos de la region con un coste global m nimo.

La resolucion de cada problema debe incluir, por este orden: 1. Eleccion razonada del esquema algor tmico. 2. Descripcion del esquema usado e identi cacion con el problema. 3. Estructuras de datos. 4. Algoritmo completo a partir del re namiento del esquema general. 5. Estudio del coste. Segun el esquema elegido hay que especi car, ademas:
Voraz:

demostracion de optimalidad. preorden bien fundado. descripcion del arbol de busqueda asociado.

Divide y venceras: Vuelta atras:

Escuela Universitaria de Informatica de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Programacion III - Convocatoria de Febrero de 1997


Examen primera semana
denados cada una, se pretende mezclarlas a pares hasta lograr una unica cinta ordenada. La secuencia en la que se realiza la mezcla determinara la e ciencia del proceso. Dise~ar un algoritmo que busque la solucion optima minimizando el n numero de movimientos.

Problema 1 (5 puntos). Dado un conjunto de n cintas con n registros ori

Por ejemplo: 3 cintas: A con 30 registros, B con 20 y C con 10 1. Mezclamos A con B (50 movimientos) y el resultado con C (60 movimientos), con lo que realizamos en total 110 movimientos 2. Mezclamos C con B (30 Movimientos) y el resultado con A (60). Total = 90 movimientos >Hay alguna forma mas e ciente de ordenar el contenido de las cintas? Problema 2 (5 puntos). El juego del 31 utiliza las cartas de la baraja espa~ola: n 1,2,3,4,5,6,7,10(sota),11(caballo) y 12(rey) con los 4 palos: oros, copas, espadas y bastos. Dise~ar un algoritmo que calcule todas las posibles formas de obtener n 31 utilizando a lo sumo 4 cartas y 2 palos distintos en cada combinacion.
La resolucion de cada problema debe incluir, por este orden: 1. Eleccion razonada del esquema algor tmico. 2. Descripcion del esquema usado e identi cacion con el problema. 3. Estructuras de datos. 4. Algoritmo completo a partir del re namiento del esquema general. 5. Estudio del coste. Segun el esquema elegido hay que especi car, ademas:
Voraz: demostracion de optimalidad. Divide y venceras: preorden bien fundado. Vuelta atras: descripcion del arbol de busqueda asociado.

Escuela Universitaria de Informatica de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Programacion III - Convocatoria de Febrero de 1997


Examen segunda semana
Queremos grabar canciones de duraciones P . duracion =1
n T <
n i

t1 : : : tn

en una cinta de audio de

ti

numero de canciones en el espacio disponible. Problema 2(5 puntos). Dise~ar un algoritmo que seleccione las canciones de n forma que se minimice el espacio vac o que queda en la cinta.

Problema 1(5 puntos). Dise~ar un algoritmo que permita almacenar el maximo n

La resolucion de cada problema debe incluir, por este orden: 1. Eleccion razonada del esquema algor tmico. 2. Descripcion del esquema usado e identi cacion con el problema. 3. Estructuras de datos. 4. Algoritmo completo a partir del re namiento del esquema general. 5. Estudio del coste. Segun el esquema elegido hay que especi car, ademas:
Voraz: demostracion de optimalidad. Divide y venceras: preorden bien fundado. Vuelta atras: descripcion del arbol de busqueda asociado.

Escuela Universitaria de Informatica de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Programacion III - Convocatoria de Septiembre de 1997


Original Problema 1 (5 puntos). Una empresa de mensajer a dispone de tres motoristas en distintos puntos de la ciudad, y tiene que atender a tres clientes en otros tres puntos. Se puede estimar el tiempo que tardar a cada motorista en atender a cada uno de los clientes (en la tabla, en minutos):
cliente1 cliente2 cliente3 Moto 1 Moto 2 30 40 60 20 40 90 Moto 3 70 10 20

Dise~ar un algoritmo que distribuya un cliente a cada motorista de forma que se minimice el n coste total (en tiempo) de atender a los tres clientes.

Problema 2 (5 puntos). Sea un juego de tablero para dos personas, en el que se turnan para

mover las piezas del tablero segun unas reglas determinadas. Daremos por conocidos: Una estructura de datos jugada que nos da dos tipos de informacion: en un registro tablero, por un lado, la situacion de las chas en el tablero. Y en un registro turno, por otro lado, quien debe mover a continuacion (o, en caso de ser una posicion nal, quien es el ganador), con la siguiente convencion: 1 signi ca que le toca mover al jugador que comenzo. 2, al segundo jugador. 3, que la partida acabo con triunfo del primer jugador, y 4, que la partida acabo con triunfo del segundo jugador. Una funcion
funcion movimientos (j: jugada) devolver l:lista de jugada

que da todas las jugadas posibles a partir de una dada. Supondremos que en el juego no se pueden dar ciclos (volver a una situacion previa en el juego), que no se puede prolongar inde nidamente y que la partida no puede acabar en tablas. Dise~ar n un algoritmo que averigue si existe una estrategia optima para el jugador que mueve primero, de forma que se asegure la victoria siguiendo esa estrategia. >Se puede aplicar el algoritmo, en teor a, al juego del ajedrez? >Y en la practica?
La resolucion de cada problema debe incluir, por este orden: 1. Eleccion razonada del esquema algor tmico. 2. Descripcion del esquema usado e identi cacion con el problema. 3. Estructuras de datos. 4. Algoritmo completo a partir del re namiento del esquema general. 5. Estudio del coste. Segun el esquema elegido hay que especi car, ademas: Voraz: demostracion de optimalidad. Divide y venceras: preorden bien fundado. Exploracion en grafos: descripcion del arbol de busqueda asociado.

Escuela Universitaria de Informatica de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Programacion III - Convocatoria de Febrero de 1998


Primera Semana Problema 1 (5 puntos). Se considera un juego solitario en el que el tablero se compone de varios huecos dispuestos en forma de cruz y un conjunto de bolas que, inicialmente, cubren todos ellos excepto el hueco central (ver gura izquierda). Siempre que haya dos bolas y un hueco vac o consecutivos, se puede saltar con la primera bola al hueco vac o, retirando la bola intermedia (ver un posible primer movimiento en g. derecha). Solo se consideran movimientos horizontales o verticales, nunca en diagonal. El objetivo del juego es eliminar progresivamente todas las bolas del tablero hasta que solo quede una. Dise~ar un algoritmo que encuentre una solucion al juego. n

Problema 2 (5 puntos). En la compleja red de metro de Japon, la cantidad que se paga por un billete es proporcional a la distancia que se recorre. Por tanto, es necesario instalar en cada estacion un panel informativo que informe del precio del billete a cualquier otra estacion de la red. Describir un algoritmo que deduzca la informacion de todos esos paneles, basando el calculo en la suposicion de que el viajero se trasladara de una estacion a otra por el camino mas corto.

La resolucion de cada problema debe incluir, por este orden: 1. Eleccion razonada del esquema algor tmico. 2. Breve descripcion del esquema usado e identi cacion con el problema. 3. Estructuras de datos requeridas. 4. Algoritmo completo a partir del re namiento del esquema general. 5. Estudio del coste. Segun el esquema elegido hay que especi car, ademas: Voraz: demostracion de optimalidad. Divide y venceras: preorden bien fundado entre los ejemplares del problema. Exploracion en grafos: descripcion del grafo de busqueda asociado.

Escuela Universitaria de Informatica de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Programacion III - Convocatoria de Febrero de 1998


Segunda Semana
Problema 1 (5 Puntos) Sobre un eje de coordenadas positivo se tienen representados edi cios en forma de rectangulos. Cada rectangulo descansa sobre el eje horizontal y se representa por sus abscisas inicial y nal y por su altura. La linea de horizonte es el contorno que forman los edi cios. Se pide programar un algoritmo e ciente que encuentre la linea de horizonte que forma un conjunto de edi cios. Ej. Una ciudad = f(0 4 7) (2 14 4) (7 12 5) (8 17 2) (19 21 10)g tendr a una linea de horizonte = f(0 4 7) (4 7 4) (7 12 5) (12 14 4) (14 17 2) (17 19 0) (19 21 10)g:
C H

Problema 2 (5 Puntos) Se tiene un mecano de 8 piezas. Las piezas se acoplan entre s mediante tornillos, formando distintos juguetes dependiendo de como se combinen. Un juguete completo es aquel formado por las 8 piezas. El gasto de tornillos de cada acoplamiento es el indicado en la siguiente tabla: (Un ; indica que las piezas no encajan)
p1 p2 p3 p4 p5 p6 p7 p8

7 12 4 -

p1

p2

7 2 6 1 1 -

12 2 4 10 3

p3

p4

6 4 3 2 -

4 - 1 - 1 - 10 - 3 2 - 20 10 20 - 5 10 5 - - -

p5

p6

p7

p8

3 -

Se pide construir un algoritmo que calcule la combinacion de piezas que forman un juguete completo minimizando el gasto de tornillos.

La resolucion de cada problema debe incluir, por este orden: 1. Eleccion razonada del esquema algor tmico. 2. Breve descripcion del esquema usado e identi cacion con el problema. 3. Estructuras de datos requeridas. 4. Algoritmo completo a partir del re namiento del esquema general. 5. Estudio del coste. Segun el esquema elegido hay que especi car, ademas: Voraz: demostracion de optimalidad. Divide y venceras: preorden bien fundado entre los ejemplares del problema. Exploracion en grafos: descripcion del grafo de busqueda asociado.

Escuela Universitaria de Informatica de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Programacion III - Convocatoria de Septiembre de 1998


Original
a los ejes del plano, hallar el rectangulo interseccion de todos los rectangulos mediante un algoritmo e ciente.

Problema 1 (5 puntos). Dado un conjunto de n rectangulos cuyos lados son paralelos

Problema 2 (5 puntos). Una cadena euleriana en un grafo no orientado es una cadena

que une cada arista del grafo exactamente una vez. Escribir un algoritmo que decida si un grafo dado tiene una cadena euleriana y, si es as , que devuelva esa cadena.

La resolucion de cada problema debe incluir, por este orden: 1. Eleccion razonada del esquema algor tmico. 2. Breve descripcion del esquema usado e identi cacion con el problema. 3. Estructuras de datos requeridas. 4. Algoritmo completo a partir del re namiento del esquema general. 5. Estudio del coste. Segun el esquema elegido hay que especi car, ademas:
Voraz: demostracion de optimalidad. Divide y venceras: preorden bien fundado entre los ejemplares del problema. Exploracion en grafos: descripcion del grafo de busqueda asociado.

ESCUELA UNI\7ERSITARIA DE INFORMTICA DE LA UNED INGENIERA TECNICA DE SISTEMAS E INGENIERA TECNICA DE GESTIN

Programacin III - Convocatoria de Febrero de 1999


Segunda Semana Problema 1 (5 puntos). Disear un algoritmo que tome un mapa poltico y coloree el mapa con el mnimo nmero de colores posible de manera que dos pases fronterizos no tengan el mismo color.

Problema 2 (5 puntos). Una liga de n equipos ei juega a un juego donde solo se pierde o se gana, pero no se empata. Disear un algoritmo que realice una pseudo-ordenacin (e1,e2 . - - ,en) a partir de la tabla de resultados de lo equipos de manera que e1 haya ganado a e2, e2 a e3, etc. El coste debe ser a lo sumo O(nlogn)

La resolucin de cada problema debe incluir, por este orden: 1. 2. 3. 4. 5. Eleccin razonada del esquema algortmico. Descripcin del esquema usado e identificacin con el problema. Estructuras de datos. Algoritmo complejo a partir del refinamiento del esquema general. Estudio del coste.

Segn el esquema elegido hay que especificar, adems: e Voraz: demostracin de optimalidad. e Divide y vencers: preorden bien fundado. e Exploracin en grafos: descripcin del rbol de bsqueda asociado.

[Exmen copiado del original] Programacin III- Convocatoria de febrero de 2000 Primera Semana

Problema (5 puntos) Se considera un juego de tablero genrico con las siguientes caractersticas: Juegan dos oponentes entre s. Cada jugador mueve alternativamente. El juego acaba con la victoria de uno de los dos jugadores, o en tablas. Se supone conocido: - Una estructura de datos situacin que nos da la situacin actual del juego: qu jugador tiene el turno, disposicin de las fichas en el tablero, etc. - Una funcin funcion movimientos(j: situacion) devolver l:lista de situacin que nos da todas las jugadas posibles a partir de una dada. Aceptaremos que, si nos devuelve una lista vaca, es porque el juego ha terminado. Se pide disear un algoritmo que encuentre cul es el nmero de movimientos de la (o las) partidas ms cortas.

Cuestiones 1. Comparar la eficiencia de los algoritmos de ordenacin quicksort (ordenacin rpida) y mergesort (ordenacin por fusin) (2 puntos) 2. Comenta las condiciones de poda que has utilizado en la realizacin de la prctica del Nim. (1 punto). 3. Que variante del problema de la mochila admite una solucin voraz y por qu? Qu variante no admite solucin voraz? Poner un ejemplo del segundo caso en el que la solucin voraz no nos lleve a la solucin ptima. (2 Puntos).

La resolucin del problema debe incluir, por este orden: 1. Eleccin razonada del esquema algortmico. 2. Descripcin del esquema usado e identificacin con el problema. 3. Estructuras de datos. 4. Algoritmo complejo a partir del refinamiento del esquema general. 5. Estudio del coste. Segn el esquema elegido hay que especificar, adems: Voraz: demostracin de optimalidad. Divide y vencers: preorden bien fundado. Exploracin en grafos: descripcin del rbol de bsqueda asociado.

EXAMEN Programacin III. Febrero 2000 (Primera Semana) Cuestin 1. Comparar la eficiencia de los algoritmos de ordenacin Quicsort (ordenacin rpida) y mergesort (ordenacin por fusin). (Respuesta: Fundamentos de Algoritmia, pag. 260) El algoritmo Quicksort emplea un tiempo promedio de n log n, en el peor caso de n2. El algoritmo por fusin mergesort utiliza un tiempo de n log n (siempre observando la precaucin de equilibrar los subcasos a tratar). Pese a esto, en la prctica Quicksort es ms rpido en un tiempo c constante. Adems el algoritmo mergesort requiere de un espacio extra para tratar los distintos casos sin perder eficiencia (hacer la ordenacin in situ lleva asociado un incremento de la constante oculta bastante alto). Cuestin 2. Comenta las condiciones de poda que has utilizado en la realizacin de la prctica del Nim. Cuestin 3.Qu variante del problema de la mochila admite solucin voraz, y porqu?Qu variante no admite solucin voraz? Poner un ejemplo del segundo caso en el que la solucin voraz no nos lleve a la solucin ptima. (Respuesta: Fundamentos de algoritmia, pag 227, contraejemplo en pag. 300) La variante del problema de la mochila que admite solucin voraz es la variante continua, donde podemos fragmentar los objetos. Esta variante admite solucin voraz porque encontramos una funcin de seleccin que nos permite escoger del candidato a cada paso de forma que obtengamos una solucin ptima. Dicha funcin consiste en escoger los objetos por orden decreciente (de mayor a menor) segn su relacin valor/peso, lo que nos lleva a una solucin ptima. La variante que no admite solucin optima es la que no nos permite fragmentar los objetos, veamos esto con un ejemplo. Dada la siguiente relacin de objetos valor-peso para una mochila de capacidad 10 (W=10 , peso mximo de la mochila) . abc wi 6 5 5 vi 8 5 5 Segn el algoritmo voraz de la variante continua tomaramos los objetos segn su orden decreciente en funcin de la relacin valor/peso. De este modo tendramos: a (vi/wi = 1,333) , b (vi/wi= 1) y c( vi/wi=1) . La sucesin a, b y c. Sin embargo como en esta ocasin no podemos fragmentar los objetos al introducir en la mochila el objeto a de peso 6 ya no podemos introducir ninguno ms, el valor conseguido ser entonces de 6; mientras que si introducimos primero el objeto b, queda an espacio para el objeto c, con lo que en esta ocasin hemos utilizado el peso total mximo de la mochila y el valor conseguido es de 10. Siendo esta la solucin ptima. Vemos con este ejemplo como el criterio seguido en la variante continua del problema no puede aplicarse en el caso en el que los objetos no puedan fragmentarse.

PROGRAMACION III Convocatoria de Febrero del 2.000


Segunda semana

Cuestiones:

1. Poner algn ejemplo en el que un enfoque de Divide y Vencers nos lleve a un


coste exponencial de forma innecesaria. (1 Punto).

1. Puedes explicar brevemente que papel desempea un montculo en el


algoritmo de Ramificacin y Poda? Cul es el criterio general para realizar la poda en este algoritmo? (2 Puntos).

1. En una exploracin de un rbol de juego con dos oponentes a nivel de


profundidad 4 (contando la raiz como nivel 1) y siguiendo la estrategia del MINIMAX nos encontramos con la siguiente puntuacin: [[[-7,5] [-3] [-10,-20,0]] [[-5,-10] [-15,20]] [[1] [6,-8,14] [-30,0] [-8,-9]]] donde los corchetes indican agrupacin de nodos por nodo padre comn. Se pide propagar las puntuaciones y elegir la rama ms adecuada a partir de la raiz sabiendo que el nodo raiz corresponde al jugador A, a mayor valor, mejor jugada para A, y que se alternan para mover. En que se diferencia esta estrategia de juego de la utilizada para resolver la prctica? (2 Puntos).

Problema (5 Puntos). La Base Aerea de Gando (Gran Canaria) posee una flota
variada de n cazas de combate ci (con i {1..n}). Cada caza tiene que salir del bunker y superar un tiempo de rodadura ki ms un tiempo de despegue ti para estar en el aire y operativo. Durante este proceso la nave es vulnerable. Suponiendo que se produce un ataque sorpresa, construir un algoritmo que averige el rden de despegue de las aeronaves de manera que se minimice el tiempo medio durante el cual son vulnerables.

Supongamos ahora que cada aeronave ci posee un ndice acumulativo bi de importancia estratgica siempre que despegue antes de la ranura temporal hi (con i {1..n}). Si queremos maximizar la importancia estrategica una vez que hayan despegado todas Qu tipo de problema es ste? Con que esquema se resuelve?. Explica en un prrafo breve el funcionamiento del algoritmo.

La resolucin del problema debe incluir siempre, y por este orden: 1. Eleccin razonada del esquema algortmico. 2. Descripcin del esquema usado e identificacin con el problema. 3. Estructuras de datos 4. Algoritmo completo a partir del refinamiento del esquema general. 5. Estudio del coste. Segn el esquema elegido hay que especificar, adems Voraz: demostracin de optimalidad. Divide y vencers: preorden bien fundado. Exploracin en grafos: descripcin del rbol de bsqueda asociado

EXAMEN Programacin III. Febrero 2000 (Segunda semana) Cuestin 1.Poner algn ejemplo en el que un enfoque divide y vencers nos lleve a un coste exponencial de forma innecesaria. (Respuesta: Fundamentos de Algoritmia, pag.83) Un ejemplo claro de esto es utilizar la definicin recursiva de la funcin de Fibonacci sin ms, de este modo el siguiente algoritmo conlleva un coste exponencial, existiendo formas de obtener la solucin en un coste inferior utilizando un enfoque distinto al de divide y vencers. Fun Fib(n) si (n<2) entonces devolver n sino Devolver Fib(n-1) + Fib(n-2) Fsi Ffun Cuestin 2.Puedes explicar brevemente qu papel desempea un montculo en el algoritmo de ramificacin y poda? Cul es el criterio general para realizar la poda en este algoritmo? (Respuesta Fundamentos de Algoritmia, pag. 354, y 348) El montculo es la forma ideal de mantener la lista de nodos que han sido generados pero no explorados en su totalidad en los diferentes niveles del rbol, tomando como valor el de la funcin de cota. De este modo tendremos ordenados los nodos segn la cota, de manera que el elemento en la cima ser el ms factible de ser explorado a continuacin. El criterio consiste en calcular una cota del posible valor de aquellas soluciones que el grafo pudiera tomar ms adelante, si la cota muestra que cualquiera de estas soluciones ser necesariamente peor que la mejor solucin hallada hasta el momento entonces no seguimos explorando esa parte del grafo. Cuestin 3.En una exploracin de un rbol de juego con dos oponentes a nivel de profundidad 4 (Contando la raiz como nivel 1) y siguiendo la estrategia MINIMAX nos encontramos con la siguiente puntuacin: [[[-7,5][-3][-10,-20,0]] [[-5,-10][-15,20]] [[1] [6,-8,14] [-30,0] [-8,-9]]] Donde los corchetes indican agrupacin de nodos por nodo padre comn. Se pide propagar las puntuaciones y elegir la rama ms adecuada a partir de la raiz sabiendo que el nodo raiz corresponde al jugador A, a mayor valor, mejor jugada para A, y que se alternan en mover. En que se diferencia esta estrategia de juego de la utilizada para resolver la prctica? (Alg. Minimax en Fundamentos de Algoritmia pag. 354) El nodo raiz corresponde al jugador A, el nodo 2 a B, el nodo 3 a A y consecuentemente el nodo 4 a B, segn lo cual los valores correspondern por tanto a una jugada de B. Como anteriormente juega A, y los mejores valores para A son los mayores, coger por tanto los mayores valores de las jugadas posibles. Cuando juege B es lgico que este tomar aquellas jugadas que sean peores para A, luego coger los valores ms pequeos. Dibujemos el rbol (de forma invertida) para verlo ms claro y realizar la propagacin... Juega B min [-7,5] [-3] [-10,-20,0] [-5,-10] [-15,20] [1] [6,-8,14] [-30,0] [-8,-9] A max [ 5 -3 0] [ -5 20 ] [ 1 14 0 -8] B min [ -3 -5 -8] A max [ -3 ]

Escuela Universitaria de Informatica de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Programacion III - Septiembre 2.000 - Original


Cuestion 1. (1 punto). A la hora de hacer una exploracion ciega en un
grafo, >que criterios nos pueden decidir por una busqueda en profundidad o en anchura?
f ib f ib n f ib n f ib n n

f ib

Cuestion 2 (2 puntos). La sucesion de Fibonacci se de ne como (0) = (1) = 1 ( ) = ( ; 1)+ ( ; 2)si 2. Que ocurre si aplicamos
una estrategia divide y venceras para calcular ( ) usando directamente la de nicion? >Que otras opciones existen? (2 puntos).
f ib n

seleccion y la ordenacion por mont culo? >Como se re eja en la e ciencia de los dos algoritmos? (2 puntos).
T :::n n

Cuestion 3 (2 puntos). >Cual es la relacion entre la ordenacion por

Problema (5 puntos). Sea 1 ] un vector de elementos. La unica comparacion que se permite entre esos elementos es el test de igualdad. Llamemos elemento mayoritario de , si existe, a aquel que aparece estrictamente mas de 2 veces en . Dise~ar un algoritmo que encuentre el n elemento mayoritario de un vector (si existe) en un tiempo que sea, a lo sumo, O( log ). Sugerencia: el elemento mayoritario de un vector debe serlo tambien, al menos, de una de sus dos mitades.
T n= T n n

La resolucion del problema debe incluir, por este orden: 1. Eleccion razonada del esquema algor tmico. 2. Descripcion del esquema usado e identi cacion con el problema. 3. Estructuras de datos. 4. Algoritmo completo a partir del re namiento del esquema general. 5. Estudio del coste. Segun el esquema elegido hay que especi car, ademas: Voraz: demostracion de optimalidad. Divide y venceras: preorden bien fundado. Exploracion en grafos: descripcion del arbol de busqueda asociado.

EXAMEN Programacin III. Septiembre 2000 (Original) Cuestin 1.A la hora de hacer una exploracin ciega en un grafoqu criterios nos pueden decidir por una bsqueda en profundidad o en anchura? (Respuesta: Fundamentos de Algoritmia, pag 340) A la hora de escoger un criterio u otro fundamentaremos nuestra decisin segn el problema en cuestin y el tamao del grafo generado. Si el problema consiste en encontrar el camino ms corto desde un punto del grafo hasta otro, la exploracin en anchura es la ms adecuada. Del mismo modo, si el grafo a tratar es de un tamao muy grande, de forma que no resulte manejable, o infinito, utilizaremos la exploracin en anchura para realizar una exploracin parcial de dicho grafo. En otro caso nos decidiremos por la exploracin en profundidad. Cuestin 2.La sucesin de fibonacci se define como Fib(1)=1; fib(n)=fib(n-1)+fib(n-1) si n >= 2 Qu ocurre si aplicamos una estrategia divide y vencers para calcular fib(n) usando directamente la definicin?Qu otras opciones existen?. (Respuesta. Fundamentos de Algoritmia pag. 83) Si utilizamos directamente la definicin obtendremos un algoritmo con un coste exponencial. Dicho algoritmo sera el siguiente: Fun Fib(n) si (n<2) entonces devolver n sino Devolver Fib(n-1) + Fib(n-2) Fsi Ffun Y el principal problema es que calculara varias veces los mismos valores, para evitar esto existe otra opcin dada por el siguiente algoritmo iterativo: Fun Fib2(n) i 1; j 0 para k 1 hasta n hacer j i j i fin_para Devolver j Ffun

j+i

Que requiere de un tiempo de orden n. Cuestin 3.Cul es la relacin entre la ordenacin por seleccin y la ordenacin por montculo?Cmo se refleja en la eficiencia de los dos algoritmos?

EXAMEN Programacin III. Septiembre 2000 (Reserva) Cuestin 1. En el algoritmo quicksort, qu implicaciones tiene para la eficiencia el escoger como pivote la mediana exacta del vector?. (Respuesta en: Fundamentos de Algoritmia, pag. 266) El algoritmo Quicksort tiene un tiempo promedio de O(n log n ). En la prctica es ms rpido que la ordenacin por montculo (heapsort) y la ordenacin por fusin (mergesort) en un tiempo constante. Al ser un algoritmo recursivo sera ideal poder dividir el caso en sub-casos de tamaos similares de manera que cada elemento sea de profundidad log n, es decir, poder equilibrar los subcasos. Sin embargo, aunque seleccionemos la mediana del vector en el peor caso (todos los elementos a ordenar son iguales) el orden ser cuadrtico. Para obtener alguna ventaja utilizando como pivote la mediana tendremos que hacer algunas modificaciones al algoritmo original. Utilizaremos una nueva funcin pivote que divida en tres secciones el vector , de modo que dado un pivote p una parte conste de elementos menores que l, otra de elementos iguales y finalmente otra parte con los ms grandes que p. Tras hacer esto se haran las llamadas recursivas correspondientes al algoritmo, una para con el sub-vector de elementos menores que p, y otra para el de los mayores que p. Esta modificacin consigue que, utilizando la mediana como pivote el orden del algoritmo sea O(n log n) incluso en el peor caso. Pero el coste que implica esta modificacin hace que el tiempo constante crezca haciendo mejor el algoritmo de ordenacin por montculo que el Quicksort en todos los casos, lo que hace que la modificacin no sea factible. Cuestin 2. Los algoritmos de Prim y Kruskal calculan, de distintas formas, el rbol de expansin mnimo de un grafo. Cul de los dos es ms eficiente para un grafo con alta densidad de aristas?. Razonar la repuesta. (Respuesta en: Fundamentos de Algoritmia, pag. 223) El algoritmo de Kruskal tiene un tiempo (a log n), siendo a el nmero de aristas. Si la densidad es alta el nmero de aristas a tiene a ser n(n-1)/2, con lo que el tiempo pasara a (n2 log n), y el algoritmo de Prim podra implementarse de forma que fuera mejor. En el caso de un grafo disperso (pocas aristas) el nmero de aristas tendera a n, siendo en este caso el tiempo (n log n), siendo mejor que algunas implementaciones del algoritmo de Prim. Pero si implementamos el algoritmo de Prim utilizando montculos el tiempo requerido ser de (a log n) (al igual que el algoritmo de Kruskal). Cuestin 3. Explicar cmo funciona el algoritmo que dota a un vector de la propiedad de montculo en tiempo lineal (no es necesario demostrar que ese es el coste). (Respuesta en: Fundamentos de Algoritmia, pag. 190) El algoritmo que convierte un vector en un montculo en tiempo lineal es: Proc CrearMontculo (V[1...N]) Para i [n/2] bajando hasta 1 hacer hundir(V,i) Fin_proc Y hundir es: Proc Hundir(V[1...N],i) k i Repetir j k Si 2j <= n y V[2j] > V[k] entonces k 2j fsi Si 2j < n y V[2j+1] > V[k] entonces k 2j + 1 fsi Intercambiar V[j] y V[k] hasta j=k Fin_proc

La idea es considerar el vector como un montculo, empezamos convirtiendo inicialmente en montculos los sub-rboles del nivel ms bajo, para progresivamente seguir modificando en niveles superiores sucesivos. Veamos su funcionamiento con un ejemplo V=[4,3,7,7,10,1] con n=5 Si consideramos este vector cmo un montculo tendremos... Ejecutaramos el algoritmo CrearMontculo Para i 3 hasta 1 hundir(V,i) I=3, hundir (V,3) k=6, j =6 no habra ningn cambio dado que V[6] < V[3] V=[4,3,7,7,10,1] k=j fin del bucle I=2 hundir (V,2) k=2, j=2 Como V[4]>V[2] k = 4 Pero V[5]>V[2], k=5 intercambia V[5],V[2] V=[4,10,7,7,3,1] k=5 y j=5, termina el bucle. I=1 hundir (V,1) k=1, j=1 Resulta que V[2]>V[1] k=2 Y NO (V[3] > V[2]) Intercambia V[2],V[1] V=[10,4,7,7,3,1] k=2, j=2 Como V[4]>V[2] k = 4 Pero NO(V[3]>V[4]) asi que k=4 Intercambia V[4],V[2] V=[10,7,7,4,3,1] k=3, j=3 NO(V[6]>V[4]) con lo que no hay cambio y termina el bucle. Hemos obtenido finalmente el montculo. Si dibujamos los vectores como montculos, observamos que el proceso es el descrito anteriormente, vamos al nivel ms bajo y obtenemos los montculos correspondientes. Y as sucesivamente hasta llegar a la raz.

EXAMEN Programacin III. Febrero 2001 (Primera Semana) Cuestin 1.Dado el siguiente montculo[10,6,3,5,2,3,2] se pide insertar el valor 6 describiendo toda la secuencia de cambios en el mismo. El algoritmo de insercin es el siguiente: Proc aadir-nodo (T[1...n],v) T[n+1] v Flotar(T[1...n+1],n+1) Fproc Proc Flotar(T[1...n],i) k i Repetir j k Si j> 1 y T[j/2] < T[k] entonces k Intercambiar T[j] y T[k] Hasta j=k Fproc

j/2

De este modo, dado el montculo [10,6,3,5,2,3,2], aadimos 6 al final [10,6,3,5,2,3,2,6] y procedemos a comparar y subir T[n+1] para cada sub-rbol hasta no tener que hacer ningn cambio. Veamos como ira cambiando: Se llamara a flotar (T[1...8],8). Se compara T[8] con su padre, que viene dado por T[8/2]=4, como es mayor se intercambiara resultando [10,6,3,6,2,3,2,5]. El valor de k queda actualizado a 4. Se vuelven a comparar T[4] y T[2], como son iguales no se hace nada y j queda igual que k, luego termina el bucle. Cuestin 2.Suponemos que para el juego del ajedrez hemos programado una funcin esttica perfecta de evaluacin eval(u) para cada situacin de juego u. Se supone conocida otra funcin, compleciones (u) que devuelve la lista de las jugadas legales a partir de la posicin del tablero u. Explica, incluyendo pseudocdigo si es preciso, como programar un algoritmo que juegue al ajedrez.Qu pasa si (como ocurre en la realidad) la funcin eval(u) no existe?Qu papel desempea entonces la estrategia MINIMAX? (Respuesta: Fundamentos de Algoritmia, pag.355) Gracias a la informacin perfecta suministrada por la funcin eval(u) podremos saber en cada momento cul es la mejor jugada posible. De este modo si jugaran por ejemplo las blancas dado un estado u, tomaramos como mejor movimiento el que maximice el valor de eval(u) (suponiendo que eval(u) nos devuelve el valor ms grande cuanto mejor sea la jugada para las blancas), sin importarnos qu decisin puedan tomar las negras tras nuestro movimiento, ya que eval(u) nos asegura que nuestro movimiento es el ms acertado. Sin embargo no existe una funcin eval(u) perfecta en el caso del ajedrez, deberemos entonces buscar una funcin eval aproximada con una relacin coste/precisin lo mejor posible. En este caso, eval(u) no nos confirma que el mejor movimiento considerado por ella sea en realidad el ms adecuado. Y es aqu donde entra la estrategia MINIMAX, considerando que si para las blancas ser la mejor jugada la marcada como mayor valor de eval(u), las negras ejecutarn aquella que minimice dicho valor. De este

modo si queremos anticipar un nmero determinado de jugadas, tomaremos al anterior criterio, minimizar el valor de eval(u) paras las negras y maximizarlo paras las blancas. Cuestin 3. Un vector T contiene n elementos. Se quieren encontrar los m mayores elementos del vector y se supone que n >>m. Describe una forma eficiente de hacer esto sin ordenar el vector y calcula qu coste tiene. Podemos utilizar un enfoque similar a como hacemos en la ordenacin por fusin, pero en este caso iremos generando un sub-vector con aquellos elementos mayores que m. Dividimos por tanto el vector original de forma equilibrada y progresivamente, hasta llegar a un tamao base adecuado (lo suficientemente pequeo) para aplicar en el la bsqueda de todo elemento menor que m, cada vez que encontremos un elemento menor que m lo almacenaremos en un vector resultado, que posteriormente se fusionar con los encontrados en las distintas llamadas. Igualmente podemos utilizar otro algoritmo de Ordenacin pero sin ordenar el vector, si no almacenar en otro vector los ndices en el orden correspondiente, por ejemplo.

EXAMEN Programacin III. Febrero 2001 (Segunda Semana) Cuestin 1.Mostrar mediante un ejemplo que el algoritmo de Dijkstra no siempre encuentra el camino mnimo si existe una distancia negativa. (Respuesta: Fundamentos de Algoritmia pag. 224) El algoritmo de Dijkstra nos devuelve los caminos mnimos desde el origen, y su pseudo cdigo es: Funcin Dijkstra (L[1...n,1..n]): matriz [2...n] Matriz D[2...n] {Inicializacin} C {2,3,....n} Para i 2 hasta n hacer D[i] L[1,i] Finpara {Bucle voraz} Repetir n-2 veces v algn elemento de C que minimiza D[v] C C \ {v} Para cada w C hacer D[w] min (D[w], D[v] + L[v,w]) Finpara FinRepite Probaremos este algoritmo para el siguiente grafo: 21

1 4 5 -9 Observando el grafo apreciamos los caminos ms cortos desde 1 a cualquier nodo son: 1-2 con coste 2, 1-3 con coste 4, 1-3-5 con coste 9, 1-3-5-6 con coste 0 y 1-3-5-6-4 con coste 1, veremos si el algoritmo de Dijkstra nos devuelve esta solucin. Tenemos para cada paso y tras la inicializacin... Paso V C D[2] D[3] 4 4 4 4 4 D[4] 3 3 3 3 D[5] 9 9 D[6] 0

Inicializa 1 2 3 4 2 4 3 5

{2,3,4,5,6} 2 {3,4,5,6} {3,5,6} {5,6} {6} 2 2 2 2

Observamos como la solucin devuelta no es la correcta ya que los costes no son los mnimos, con lo que los caminos seran 1-2 (coste 2), 1-2-4 (coste 3) aqu est el fallo-, 1-3 (coste 4), 1-3-5 (coste 9) y 1-3-5-6 (coste 0).

Cuestin 2.Poner un ejemplo de un vector de 10 elementos que suponga un ejemplo de caso peor para el algoritmo de ordenacin Quicksort. Ordenar el vector mediante este algoritmo detallando cada uno de los pasos. (Respuesta Fundamentos de Algoritmia, pag 261) Tomaremos un vector con 10 elementos ya ordenados como peor caso. {1,2,3,4,5,6,7,8,9,10} El algoritmo Quicksort es... Proc pivote(T[i...j],var L ) p T[i] k i ; L j+1 repetir k k+1 hasta que T[k] > p o k >= j fin_repite repetir L L 1 hasta que T[L]<=p fin_repite mientras k < L hacer Intercambiar T[k] y T[L] repetir k k +1 hasta que T[k] > p fin_repite repetir L L+1 hasta que T[L] <= p fin_repite fmientras intercambiar T[i] y T[L] Fin_proc Proc quicksort(T[i...j]) Si i-j es suficientemente pequeo entonces insertar (T[i...j] ) Sino Pivote (T[i...j],L) Quicksort (T[iL-1]) Quicksort(T[L+1j]) Fsi Fin_proc T[1..10]={1,2,3,4,5,6,7,8,9,10} Pivote(T[1..10], L) Luego i=1 y j=10 p=1, k=1, L=11 1. primer bucle, se mueve k hasta 2, ya que T[2]>p 2. segundo bucle, L llega hasta 1, ya que es el nico elemento tq T[L]<=p Llegamos al 3er bucle k=2 y L=1 (k>L), no existe por tanto intercambio alguno, excepto la ltima instruccin Intercambiar T[i] por T[L], como L apunta a 1, e i es uno T[L] queda igual. A continuacin se llamara a: Quicksort(T[1...0]), Llamada a un caso de tamao cero. Quicksort(T[2....10]). Llamamos al resto del vector. Ignoramos la primera llamada al ser de un tamao 0, la segunda llamada tendra el mismo efecto que la primera vez, en este caso en el procedimiento pivote L descendera hasta llegar al T[2], y k quedara en el tercer elemento; no se provoca cambio alguno, y vuelve a hacerse una tercera llamada a Quicksort, una de ellas para un caso de tamao 0: Quicksort(T[2..1]), y otra para el resto del vector, Quicksort(T[3...10]). Como vemos el proceso se repite hasta llegar al ltimo elemento, producindose tantas llamadas como elementos posee el vector. Cuestin 3. Dado un montculo T[1...n] programar completamente en pseudocdigo una funcin recursiva flotar(T,i) para flotar el elemento de la posicin i del vector T. Explica como usar esta funcin para insertar un elemento en el montculo. (Respuesta. Fundamentos de Algoritmia, pag. 188) Tomar el algoritmo iterativo de la pag 188 y transformar en recursivo.

Escuela Tecnica Superior de Ingenieros Informaticos de la UNED Ingenier a Tecnica de Sistemas e Ingenier a Tecnica de Gestion

Programacion III - Convocatoria de Septiembre de 2001


Original Cuestion 1 (2 punto). Halla el grafo de expansion m nimo del grafo de la gura mediante Cuestion 2 (1 punto). Explica porque una estructura de mont culo suele ser adecuada
el algoritmo de Kruskal. Detalla cada paso. para representar el conjunto de candidatos en un algoritmo voraz. Cuestion 3 (1 punto). Explica en que consiste un problema de plani cacion con plazo jo. Pon un ejemplo con n = 4 y resuelvelo aplicando el algoritmo voraz correspondiente. de n las y m columnas con n m casillas y suponemos que el tablero descansa sobre uno de sus lados de tama~o m al que denominaremos base, y donde cada casilla puede contener n s mbolos de k tipos diferentes. Al comienzo del juego el usuario comienza con un tablero lleno de s mbolos. En cada movimiento el jugador elige un s mbolo del tablero y este es eliminado del mismo junto con (si las hay) las agrupaciones adyacentes (en horizontal o vertical) de su mismo s mbolo siempre que mantengan la continuidad. Una vez eliminada la agrupacion, los huecos dejados por esta se rellenan deslizando hacia la base los s mbolos de su columna que queden por encima del hueco dejado por los s mbolos eliminados. El objetivo del juego es el de dejar el tablero vac o. Para ilustrar el enunciado supongamos un tablero de 4 las y 5 columnas con 4 s mbolos o,+,*,x y donde - representa una casilla vac a. Una secuencia de juego ser a la siguiente:
oox+x o++x+ o**ox oo*xx --x+x --+x+ -+*ox -**xx ---+x ---x+ --xox -++xx -------+--xxx -++o+ -----------+-++o+ -----------+---o+ --------------++-----------------

Problema 2 (5 puntos). Se plantea el siguiente juego: Tenemos un rectangulo (tablero)

Se pide programar un algoritmo que resuelva el juego. Explicar ademas (si las hay) las diferencias que habr a que introducir a este algoritmo si se exigiera resolver el juego en el menor numero de movimientos.
La resolucion de cada problema debe incluir, por este orden: Eleccion razonada del esquema algor tmico. Breve descripcion del esquema usado e identi cacion con el problema. Estructuras de datos requeridas. Algoritmo completo a partir del re namiento del esquema general. Estudio del coste. Segun el esquema elegido hay que especi car, ademas: Voraz: demostracion de optimalidad. Divide y venceras: preorden bien fundado entre los ejemplares del problema. Exploracion en grafos: descripcion del grafo de busqueda asociado.

EXAMEN Programacin III. Septiembre 2001 (Original). Cuestin 1.Comenta de qu formas se puede mejorar la eficiencia del algoritmo de Dijkstra mediante el uso de estrucutras de datos apropiadas. (Respuesta. Fundamentos de Algoritmia. Pag 227) Utilizando una matriz de adyacencia y matrices para representar los datos el algoritmo se situan en O(n2) (con un tiempo O(n) para inicializar la matriz de adyacencia y un tiempo (n2 ) en los bucles que conforman el algoritmo voraz). Si resulta que el nmero de aristas a es mayor que el nmero de nodos al cuadrado, n2 , resulta apropiado utilizar en vez de una matriz de adyacencia, una lista de adyacencia, evitando examinar entradas innecesarias -dnde no existe arista- , ahorrando as tiempo en el bucle ms interno del algoritmo. Por otro lado podemos utilizar un montculo invertido para representar el camino mnimo que se ir generando (que llamaremos D), esto hace que buscar un nodo que minimice el costo requiera slo eliminar la raiz del montculo lo que conlleva un gasto de O(log n) , siendo la inicializacin del montculo (n). Igualmente las operaciones empleadas en el bucle ms interno del algoritmo reducirn su coste (al ser D un montculo), situndose en O(log n). Si se produce la eliminacin de la raiz del montculo n-2 veces (el bucle se ejecuta n-2 veces) y hay que flotar un mximo de a nodos (siendo a el nmero de aristas) obtenemos un tiempo total de ((a+n) log n). Si el grafo es conexo, es decir, a >= n-1 el tiempo corresponde a (a log n). Si el grafo es denso ser preferible la implementacin con matrices, si el grafo es disperso es mejor la implementacin con montculos. Cuestin 2. Explica porqu una estructura de montculo suele ser adecuada para representar el conjunto de candidatos de un algoritmo voraz. En un algoritmo voraz iremos eligiendo el candidato ms apropiado a cada paso para la hallar la solucin segn el valor de una funcin de seleccin. Para agilizar esa eleccin podemos tener dichos candidatos almacenados en un montculo, de forma que el valor considerado para su mantinimiento sea el valor de dicha funcin de seleccin. De este modo la eleccin de candidato consistir en ir escogiendo la cima de dicho montculo y actulizar este cuando as proceda, operaciones stas que resultan ms efecientes en los montculos que en otros tipos de estructura de datos. Cuestin 3. Explica en que consiste un problema de planificacin con plazo fijo. Pon un ejemplo con n=4 y resulvelo aplicando el algoritmo correspondiente. (Respuesta: Fundamentos de Algoritmia pag. 233) Un problema de planificacin con plazo fijo consiste en: Dado un conjunto de n tareas, cada una de las cuales requiere un tiempo unitario, en cualquier instante T=1,2,... podemos ejecutar nicamente una tarea. Cada tarea nos producir un beneficio mayor que cero, slo en el caso en el que su ejecucin sea en un instante anterior a di. Habr que buscar la secuencia de tareas ms apropiada de manera que el beneficio obtenido sea mayor. ( Bastara con aplicar el algoritmo que aparece en la pag. 240, ilustrado con un ejemplo para seis tareas, como se ve la solucin bastara con eleminar las tareas 5 y 6 y el resultado sera igual con lo que ya tenemos un ejemplo con n=4 i1234 beneficio 20 15 10 7 tiempo 3 1 1 3 Observar que tenemos las tareas ya ordenadas segn su beneficio de mayor a menor, si no fuera as para utilizar el algoritmo convendra proceder a esta ordenacin )

EXAMEN Programacin III. Septiembre 2001 (Reserva). Cuestin 1.Compara la eficiencia de los algoritmos de ordencin quicksort y mergesort. (Ver cuestin 1. Examen de Febrero del 2000 Primera Semana. ) Cuestin 2. Programa un algoritmo recursivo para implementar la operacin de hundir un elemento i en un montculo representado por el vector T[1...n] (Se supone que salvo por T[i], el vector T posee la propiedad del montculo). (Respuesta Fundamentos de Algoritmia, pag 188) Tomar el algoritmo iterativo descrito en el libro y transformarlo aun algoritmo recursivo. Cuestin 3. En los algoritmos de vuelta atrs explica la diferencia entre una condicin de poda y una condicin de retroceso. El algoritmo de vuelta atrs bsico consiste en una bsqueda exhaustiva en el rbol, si el recorrido del rbol no tiene xito porque la solucin parcial hasta ese momento no puede ser completada se produce un retroceso, igualmente si ya existiera una solucin mejor a la que est siendo actualmente calculado volveramos atrs. Si queremos limitar ms an nuestro espacio de bqueda podemos utilizar condiciones de poda, dado un determinado problema intentamos encontrar informacin que nos permita decidir deterner la bsqueda (volvindo consecuentemente atrs) si hay claros indicios de que el estado actual no nos conducir a una solucin.

Escuela Universitaria de Informatica de la UNED Ingenier Tecnica de Sistemas e Ingenier Tecnica de Gestion a a

Programacin III - Febrero 2.002 - Segunda Semana o


Cuestin 1 (1 puntos). Escribe la secuencia completa de pasos para oro denar por fusin el vector [3,2,7,5,9,3,4,8]. o Cuestin 2 (1 punto). Un algoritmo de coste O(n2 ) tarda 15 segundos o en realizar un determinado procesamiento sobre un ordenador a 450 MHz. Cunto tiempo se tarda en realizar el mismo procesamiento con el mismo a algoritmo sobre una mquina 3 veces ms lenta? a a Cuestin 3 (3 puntos). Programar en pseudocdigo todos los proceo o dimientos necesarios para fusionar dos conjuntos implementados con mont culos. Suponer que los conjuntos no pueden tener elementos repetidos. Problema (5 puntos). Se dispone de un tablero de 8 casillas similar al que muestra la gura. En la situacin inicial, las casillas estn ocupadas por o a cuatro O y cuatro X distribuidas de forma aleatoria. En cada paso la unica operacin posible es intercambiar dos chas adyacentes. Programar de la o forma ms eciente posible el algoritmo que devuelva la secuencia de pasos a ms corta para ordenar el tablero de forma que todas las chas tengan al a menos otra igual adyacente. X O X X O O O X

La resolucin del problema debe incluir, por este orden: o 1. Eleccin razonada del esquema algor o tmico. 2. Descripcin del esquema usado e identicacin con el problema. o o 3. Estructuras de datos. 4. Algoritmo completo a partir del renamiento del esquema general. 5. Estudio del coste. Segn el esquema elegido hay que especicar, adems: u a Voraz: demostracin de optimalidad. o Divide y vencers: preorden bien fundado. a Exploracin en grafos: descripcin del rbol de bsqueda asociado. o o a u

Suponiendo la llamada inicial flotar_rec( T[1..n+1], n+1) Fun flotar_rec(T[1..n, i]) Si T[i]>T[i DIV 2] ent Intercambiar T[i] y T[i DIV 2] Flotar_rec(T, i DIV 2); Fsi Ffun

Nota: en este ejercicio solo pondremos los pasos donde hay intercambio. (si no seran 189 pasos)

El pivote va a ser el elemento primero, ahora buscamos hacia la derecha el primer elemento mayor y hacia la izquierda el menor o igual que el pivote e intercambiamos, seguimos haciendo esto y cuando se crucen los punteros cambiaremos el que va decreciendo por el pivote. 2 2 1 2 2 2 8 2 2 1 1 2 9 9 9 4 4 4 2 8 8 3 3 3 6 6 6 5 5 5 4 4 4 3 3 3 7 7 7 4 4 4

Ahora hacemos dos llamadas recursivas, una por cada lado del pivote. Solo detallamos las llamadas que producen cambios. En este caso vamos con la del lado derecho.

1 1

2 2

2 2

2 2

4 4

4 4

8 7

3 3

6 6

5 5

4 4

3 3

7 8

9 9

Pgina 1 de 3
Apuntes realizados por Jos Mara Arrando Baeza, centro asociado de Terrasa.

1 1

2 2

2 2

2 2

4 4

4 4

3 3

3 3

6 6

5 5

4 4

7 7

8 8

9 9

Si nos centramos sobre todo en las repeticiones vemos que el primer para es: 1 asignacin y 7 llamadas recursivas. b=2(el problema se llama recursivamente con ejemplares de tamao n/2 (n/b). A=7, se llama 7 veces. El segundo para ser desde 1 hasta 4n^3. Por lo que el grado k del polinomio ser 3 (k=3). La ecuacin de recurrencia quedara: T(n)= cte si n<=1 3 n 7 * ( ) + 4 n si n>1 2 Ahora falta el coste, que si no pasa nada estar esta noche.

Pgina 2 de 3
Apuntes realizados por Jos Mara Arrando Baeza, centro asociado de Terrasa.

Este ni idea, todava no he conocido a nadie que lo sepa resolver, una pista es que funciona de forma parecida a los de exponenciacin.

Pgina 3 de 3
Apuntes realizados por Jos Mara Arrando Baeza, centro asociado de Terrasa.

Programacin III
Cdigos de asignatura: Sistemas: 402048; Gestin: 41204UNIVERSIDAD NACIONAL DE EDUCACIN A DISTANCIA

Primera Semana Enero de 2003 Duracin: 2 horas Material permitido: NINGUNO


DNI: _______________________

Prueba Presencial

Apellidos: ___________________________________________________________________________________ Nombre: _____________________________________

Centro Asociado en el que entreg la prctica: _______________________

Cuestin 1 (1 puntos). Para qu se pueden utilizar montculos en el algoritmo de Kruskal? Qu mejoras introduce en trminos de complejidad? Solucin: Brassard, pgina 220. Cuestin 2 (2 punto). Dado el grafo de la figura, aplicar el algoritmo de Dijkstra para hallar los caminos ms cortos desde el nodo 1 hasta cada uno de los otros nodos, indicando en cada paso: nodos seleccionados, nodos no seleccionados, vector de distancias y vector de nodos precedentes.
20 7
3 2 1

15 7
4

5 5

7
5

Solucin:
Paso Inicializacin 1 2 3 Nodos seleccionados 1 1, 4 1, 4, 5 1, 4, 5, 3 Nodos no seleccionados 2, 3, 4, 5 2, 3, 5 2, 3 2 Distancias desde 1 2 3 4 5 20 5 7 20 12 5 7 20 12 5 7 19 12 5 7 Nodo precedente 2 3 4 5 1 1 1 1 1 4 1 1 1 4 1 1 3 4 1 1

Cuestin 3 (2 puntos). Se desea implementar una funcin para desencriptar un mensaje numrico. La funcin desencriptar recibe tres enteros: el mensaje cifrado c, la clave privada s y la clave pblica z; y devuelve el mensaje original a. El mensaje original se recompone con la frmula: a := cs mod z Sabiendo que no se dispone del operador de potencia, implementar la funcin utilizando el esquema divide y vencers.
La resolucin del problema debe incluir, por este orden: 1. Eleccin razonada del esquema algortmico 2. Descripcin del esquema usado e identificacin con el problema 3. Estructuras de datos 4. Algoritmo completo a partir del refinamiento del esquema general 5. Estudio del coste Segn el esquema elegido hay que especificar, adems: Voraz: demostracin de optimalidad Divide y Vencers: preorden bien fundado Exploracin en grafos: descripcin del rbol de bsqueda asociado

Solucin: a) desencriptar (c, s, z: entero) { devolver expoDV(c,s) mod z } expoDV en Brassard, pgina 276. b) implementarlo como expomod, Brassard, pgina 279. Problema (5 puntos). Teseo se adentra en el laberinto en busca de un minotauro que no sabe dnde est. Se trata de implementar una funcin ariadna que le ayude a encontrar el minotauro y a salir despus del laberinto. El laberinto debe representarse como una matriz de entrada a la funcin cuyas casillas contienen uno de los siguientes tres valores: 0 para camino libre, 1 para pared (no se puede ocupar) y 2 para minotauro. Teseo sale de la casilla (1,1) y debe encontrar la casilla ocupada por el minotauro. En cada punto, Teseo puede tomar la direccin Norte, Sur, Este u Oeste siempre que no haya una pared. La funcin ariadna debe devolver la secuencia de casillas que componen el camino de regreso desde la casilla ocupada por el minotauro hasta la casilla (1,1). Solucin: 5.1 Eleccin razonada del esquema algortmico Como no se indica nada al respecto de la distancia entre casillas adyacentes, y ya que se sugiere utilizar nicamente una matriz, es lcito suponer que la distancia entre casillas adyacentes es siempre la misma (1, sin prdidad de generalidad). Por otra parte, no se exige hallar el camino ms corto entre la entrada y el minotauro, sino que el enunciado sugiere, en todo caso, que el algoritmo tarde lo menos posible en dar una de las posibles soluciones (y ayudar a salir a Teseo cuanto antes). Tras estas consideraciones previas ya es posible elegir el esquema algortmico ms adecuado. El tablero puede verse como un grafo en el que los nodos son las casillas y en el que como mximo surgen cuatro aristas (N, S, E, O). Todas las aristas tienen el mismo valor asociado (por ejemplo, 1). En primer lugar, el algoritmo de Dijkstra queda descartado. No se pide el camino ms corto y si se hiciera, las particularidades del problema hacen que el camino ms corto coincida con el camino de menos nodos y, por tanto, una exploracin en anchura tendr un coste menor: siempre que no se visiten nodos ya explorados, como mucho se recorrer todo el tablero una vez (coste lineal con respecto al nmero de nodos versus coste cuadrtico para Dijkstra). En segundo lugar, es previsible esperar que el minotauro no est cerca de la entrada (estar en un nivel profundo del rbol de bsqueda) por lo que los posibles caminos solucin sern largos. Como no es necesario encontrar el camino ms corto, sino encontrar un camino lo antes posible,

una bsqueda en profundidad resulta ms adecuada que una bsqueda en anchura. En el peor de los casos en ambas habr que recorrer todo el tablero una vez, pero ya que buscamos un nodo profundo, se puede esperar que en media una bsqueda en profundidad requiera explorar menos nodos que una bsqueda en anchura. Si se supone que el laberinto es infinito entonces una bsqueda en profundidad no sera adecuada porque no garantiza que se pueda encontrar una solucin. En este enunciado se puede presuponer que el laberinto es finito. En tercer lugar, es posible que una casilla no tenga salida por lo que es necesario habilitar un mecanismo de retroceso. Por ltimo, es necesario que no se exploren por segunda vez casillas ya exploradas anteriormente. Por estos motivos, se ha elegido el esquema de vuelta atrs. 5.2. Descripcin del esquema usado

Vamos a utilizar el esquema de vuelta atrs modificado para que la bsqueda se detenga en la primera solucin y para que devuelva la secuencia de ensayos que han llevado a la solucin en orden inverso (es decir, la secuencia de casillas desde el minotauro hasta la salida). fun vuelta-atrs (ensayo) dev (es_solucin, solucin) si vlido (ensayo) entonces solucin crear_lista(); solucin aadir (solucin, ensayo); devolver (verdadero, solucin); si no hijos crear_lista(); hijos compleciones (ensayo) es_solucion falso; mientras es_solucin vacia (hijos) hijo primero (hijos) si cumple_poda (hijo) entonces (es_solucin, solucin) vuelta-atrs(hijo) fsi fmientras si es_solucin entonces solucin aadir (solucin, ensayo); fsi devolver (es_solucin, solucin); fsi ffun

5.3 Estructuras de datos Para almacenar las casillas bastar un registro de dos enteros x e y. Vamos a utilizar una lista de casillas para almacenar la solucin y otra para las compleciones. Para llevar control de los nodos visitados bastar una matriz de igual tamao que el laberinto pero de valores booleanos. Ser necesario implementar las funciones de lista: crear_lista vacia aadir primero 5.4 Algoritmo completo Suponemos laberinto inicializado con la configuracin del laberinto y visitados inicializado con todas las posiciones a falso. tipoCasilla = registro x,y: entero; fregistro tipoLista fun vuelta-atrs ( laberinto: vector [1..LARGO, 1..ANCHO] de entero; casilla: tipoCasilla visitados: vector [1..LARGO, 1..ANCHO] de booleano; ) dev (es_solucin: booleano; solucin: tipoLista) visitados [casilla.x, casilla.y] verdadero; si laberinto[casilla.x, casilla.y] == 2 entonces solucin crear_lista(); solucin aadir (solucin, casilla); devolver (verdadero, solucin); si no hijos crear_lista(); hijos compleciones (laberinto, casilla) es_solucin falso; mientras es_solucin vacia (hijos) hijo primero (hijos) si visitados [hijo.x, hijo.y] entonces (es_solucin, solucin) vuelta-atrs (laberinto,hijo,visitados); fsi fmientras si es_solucin entonces solucin aadir (solucin, casilla); fsi devolver (es_solucin, casilla); fsi

ffun

En el caso de encontrar al minotauro se detiene la exploracin en profundidad y al deshacer las llamadas recursivas se van aadiendo a la solucin las casillas que se han recorrido. Como se aaden al final de la lista, la primera ser la del minotauro y la ltima la casilla (1,1), tal como peda el enunciado. La funcin compleciones comprobar que la casilla no es una pared y que no est fuera del laberinto fun compleciones ( laberinto: vector [1..LARGO, 1..ANCHO] de entero; casilla: tipoCasilla) dev tipoLista hijos crear_lista(); si casilla.x+1 <= LARGO entonces si laberinto[casilla.x+1,casilla.y] <> 1 entonces casilla_aux.x=casilla.x+1; casilla_aux.y=casilla.y; hijos aadir (solucin, casilla_aux); fsi fsi si casilla.x-1 >= 1 entonces si laberinto[casilla.x-1,casilla.y] <> 1 entonces casilla_aux.x=casilla.x-1; casilla_aux.y=casilla.y; hijos aadir (solucin, casilla_aux); fsi fsi si casilla.y+1 <= ANCHO entonces si laberinto[casilla.x,casilla.y+1] <> 1 entonces casilla_aux.x=casilla.x; casilla_aux.y=casilla.y+1; hijos aadir (solucin, casilla_aux); fsi fsi si casilla.y-1 >= 1 entonces si laberinto[casilla.x,casilla.y-1] <> 1 entonces casilla_aux.x=casilla.x; casilla_aux.y=casilla.y-1; hijos aadir (solucin, casilla_aux); fsi fsi ffun 5.5 Estudio del coste Todas las operaciones son constantes salvo la llamada recursiva a vuelta-atrs. En cada nivel, pueden realizarse hasta 4 llamadas. Sin embargo, las llamadas no se realizan si la casilla ya ha sido visitada. Esto quiere decir que, en el caso peor, slo se visitar una vez cada casilla. Como las operaciones para una casilla son de complejidad constante, la complejidad ser O(ANCHO*LARGO), lineal con respecto al nmero de casillas.

Programacin III Solucin Examen 2 Semana de Febrero Cuestin 1 (2 Puntos)


Explica cmo pueden ordenarse n valores enteros positivos en tiempo lineal, sabiendo que el rango de dichos valores es limitado. Explica las ventajas e inconvenientes de este mtodo

Respuesta.
Suponiendo que el rango de los valores a ordenar es limitado, es decir, sabemos que por ejemplo el rango de nmeros a ordenar va de 0 a 2000, podemos generar un vector de 2000 elementos de tipo entero que almacenar almacenar el nmero de ocurrencias de cada valor de la lista a ordenar en la posicin del vector correspondiente. 1- El vector esta inicializado a 0 (O(n)). 2- Recorremos la lista de valores a ordenar (O(n)). a. Por cada valor i extrado de la lista, incrementamos el valor de la posicin i del vector. 3- Recorremos el vector generado mostrando los valores generados en el paso anterior (2) y omitiendo aquellas posiciones del vector que contengan un 0. (Pgina 79 Brassard)

Cuestin 2 (1 Punto)
Puede un grafo tener dos rboles de recubrimiento mnimo diferentes? En caso afirmativo poner un ejemplo. En caso negativo justificar la respuesta.

Respuesta
Si. Siendo G=(N,A) un grafo conexo no dirigido en donde N es el conjunto de nodos y A es el conjunto de aristas. Suponiendo que cada arista posee una longitud no negativa. Encontrar un rbol de recubrimiento mnimo consiste en hallar un subconjunto T de las aristas de G tal que utilizando solamente las aristas de T, todos los nodos deben quedar conectados, y adems la suma de las longitudes de las aristas de T debe ser tan pequea como sea posible.
1 1 1 1 2 3 1 1 5 1 4 4 1 3 5 2 1 4 2 5 3

(Pgina 215 Brassard)

Cuestin 3 (2 Puntos)
Aplicar el algoritmo de planificacin con plazo fijo para las actividades ai maximizando el beneficio gi en el plazo di. Detallar todos los pasos con claridad. ai gi di 1 20 4 2 10 5 3 7 1 4 15 1 5 25 2 6 15 3 7 5 1 8 30 2

Respuesta
Inicialmente procederemos a ordenar la matriz de costes y plazos de mayor a menor en funcin de los costes. Una vez realizado este paso, procederemos a aplicar el algoritmo rpido (pginas 237-241 Brassard) de planificacin con plazo fijo. Resultado de la ordenacin: i ai gi di 1 8 30 2 2 5 25 2 3 1 20 4 4 4 15 1 5 6 15 3 6 2 10 5 7 3 7 1 8 7 5 1

Calculamos p=min(8,5)=5
0 0 1 1 2 2 3 3 4 4 5 5 1 0 2 0 3 0 4 0 5 0 j[]

i=1, d[1]=2. Seleccionamos K(2)


0 0 1 1,2 3 3 4 4 5 5 1 0 2 1 3 0 4 0 5 0 j[]

i=2, d[2]=2. Seleccionamos K(1)


0 0,1,2 3 3 4 4 5 5 1 2 2 1 3 0 4 0 5 0 j[]

i=3, d[3]=4. Seleccionamos K(4)


0 0,1,2 3 3,4 5 5 1 2 2 1 3 0 4 3 5 0 j[]

i=4, d[4]=1. Tarea rechazada i=5, d[5]=3. Seleccionamos K(3)


0 0,1,2,3,4 5 5 1 2 2 1 3 5 4 3 5 0 j[]

i=6, d[6]=5. Seleccionamos K(5)


0 1 2 2 1 3 5 4 3 5 6 j[]

0,1,2,3,4,5

Resto de tareas rechazadas. Fin del Algoritmo. Orden de ejecucin de las tareas: a5, a8, a6, a1, a2. (Pgina 237-241 Brassard)

Problema (5 Puntos)
Se pide disear completamente un algoritmo que calcule en tiempo logertmico el valor de fn de la sucesin definida como fn=afn-1+bfn-2 con f0=0 y f1=1. Sugerencia: Pudiera ser de utilidad razonar el problema utilizando la siguiente igualdad entre matrices:
a b f n1 f n 1 0 f = f n2 n1

Solucin
La solucin trivial se basa en resolver recursivamente el caso n resolviendo los n trminos anteriores, lo cual supondra un coste lineal que no es lo que nos piden en el enunciado del problema. Planteamiento a b Si llamamos F a la matriz 1 0 , vamos a intentar encontrar una frmula que nos permita expresar la solucin del problema en funcin de los casos base que se proporcionan en el enunciado que son f0=0 y f1=1.

fn f = F n1 f f n1 n2 f n1 f n2 f f f f = F f n = F 2 n2 = ..... = F n1 1 f f n2 n3 f n1 n3 0 .......................... f f2 = F 1 f f 1 0 Con esta simplificacin, es posible calcular el valor de fn con slo calcular Fn-1 y hacer una multiplicacin por el vector de casos base. La forma ms eficiente de calcular exponenciaciones es mediante la tcnica de divide y vencers, aplicada sobre:

F n = F ndiv 2 F n mod 2

n 2 F 2 si n es par = 2 n 1 2 F F si n es impar

Como puede observarse, reducimos el problema n a uno de n/2 que nos permite obtener una eficiencia de O(log n) frente a O(n) como ocurra si aplicbamos el algoritmo inicial.
Descripcin del Esquema Algortimico Para resolver el problema de elevar una matriz F a un determinado exponente utilizaremos la tcnica de divide y vencers aplicada a la frmula de potencia descrita en el apartado anterior.

El esquema algortmico de divide y vencers se basa en la idea de dividir un problema en varios subproblemas del mismo tipo cuya solucin ser combinada posteriormente para obtener la solucin al problema inicial.

Como en toda funcin que resuelva un problema recursivamente, existirn casos umbral para los cuales la solucin del problema pueda ser obtenida directamente mediante el uso de una sencilla funcin. En nuestro caso concreto: 1- Tamao umbral y solucin simple: En nuestro caso, para n=1 y n=0 existen soluciones triviales y, por tanto, nuestro tamao umbral lo podemos poner en n=1. 2- Descomposicin: Fn siempre lo vamos a descomponer en un nico subproblema Fn/2. En este caso, el algoritmo de divide y vencers realiza una reduccin en lugar de una descomposicin. 3- Combinacin: La funcin de combinacin en nuestro caso ser la que hemos desarrollado al final del apartado anterior.
Estructuras de Datos. En nuestro caso utilizaremos enteros y matrices de 2x2. Algoritmo Completo. Suponiendo que conocemos a, b, f0 y f1.
fun f(n:entero) dev entero F caso

a b 1 0
n=0: dev f0 n=1: dev f1 verdadero: hacer S exp_mat(F,n-1) s S

f1 f 0

dev s[1] fcaso ffun

fun exp_mat(M:vector[2,2]; n:entero) dev vector[2,2] si n <= 1 entonces dev solucion_simple(M,n) si no hacer p n div 2 r n mod 2 T exp_mat(M,p) dev combinacion(T,r,M) fsi ffun fun combinacin (T:vector[2,2]; r:entero; M:vector[2,2]) dev vector[2,2] dev TT*Mr ffun Donde M1=M y M0=

1 0 0 1

fun solucion_simple (M:vector[2,2], n:entero) dev vector[2,2] si n=1 dev M si no dev fsi ffun

1 0 0 1

Estudio del Coste Funcin de recurrencia:


c n k si 1 n < b T (n ) = k a T (n / b ) + c n si n b + + a, c R , k R {0}, n, b N , b > 1

Resolucin de la funcin de recurrencia: k=0, b=2; a=1


n k si a < b k T (n ) = n k log n si a = b k n log b a si a > b k

( )

De acuerdo a los valores extrados del caso particular de nuestra funcin, podemos concluir que la complejidad del problema solucionado ser de O(log n) como nos pedan en el enunciado. (Pginas 55-59 Esquemas Algortmicos: Enfoque Metodolgico y Problemas Resueltos. J. Gonzalo Arroyo y M. Rodrguez Artacho)

Programacin III
Cdigos de asignatura: Sistemas: 402048; Gestin: 41204UNIVERSIDAD NACIONAL DE EDUCACIN A DISTANCIA

Nacional Original Septiembre de 2003 Duracin: 2 horas Material permitido: NINGUNO


DNI: _______________________

Prueba Presencial

Apellidos: ___________________________________________________________________________________ Nombre: _____________________________________

Centro Asociado en el que entreg la prctica: _______________________

Cuestin 1 (2 puntos). Hallar el coste de los siguientes algoritmos, siendo h(n,r,k)O(n).

PROCEDIMIENTO uno(n,k:entero):entero; VAR i,r:entero; COMIENZO SI n<3 ENTONCES DEVOLVER(1); SINO COMIENZO r!uno(n DIV 3,k-1); r! r + uno(n DIV 3,k+1); DEVOLVER(r); FIN FIN

PROCEDIMIENTO dos(n,k:entero):entero; VAR i,r:entero; COMIENZO SI n<4 ENTONCES DEVOLVER(1); SINO COMIENZO r ! dos(n DIV 4,k-1); r ! r + dos(n DIV 4,k+1); PARA i! 1 HASTA n HACER COMIENZO r ! h(n,r,i) r ! r + h(n,r-1,i) FIN r ! r + dos(n DIV 4,k+2); DEVOLVER(r); FIN FIN

Cuestin 2 (2 puntos). Una matriz T contiene n elementos. Se desea encontrar los m elementos ms pequeos de T (con m<<n). Explicar cmo hacer esto de la manera ms eficiente. Cuestin 3 (1 puntos). Explicar de qu manera se puede implementar mediante un esquema voraz el conocido problema de la bsqueda del camino ms corto hacia la salida a un laberinto descrito por una matriz rectangular de casillas de tipos libre y ocupada, y otras dos de tipo entrada y salida. Compararlo en trminos de coste con otras soluciones. Problema (5 puntos). Una operadora de telecomunicaciones dispone de 10 nodos conectados todos entre s por una tupida red de conexiones punto a punto de fibra ptica. Cada conexin c(i,j) entre el nodo i y j ( Con i,j {1..10}) tiene un coste asignado que sigue la frmula c(i,j)= (i + j) MOD 8. La operadora quiere reducir gastos, para lo cual est planificando asegurar la conectividad de su red de nodos minimizando el coste. Disear un algoritmo que resuelva el problema (4 puntos) y aplicarlo a los datos del enunciado (1 punto).

La resolucin del problema debe incluir, por este orden: 1. Eleccin razonada del esquema algortmico 2. Descripcin del esquema usado e identificacin con el problema 3. Estructuras de datos 4. Algoritmo completo a partir del refinamiento del esquema general 5. Estudio del coste Segn el esquema elegido hay que especificar, adems: Voraz: demostracin de optimalidad Divide y Vencers: preorden bien fundado Exploracin en grafos: descripcin del rbol de bsqueda asociado

Solucin al examen de Septiembre 2003 Programacin III Cuestin 1


El procedimiento uno tiene una instruccin condicional de coste constante. Dentro de la condicin tiene o bien una instruccin constante o bien dos llamadas recursivas. Ambas invocan la funcin con un tamao n/3. En el segundo caso hay otra instruccin simple aadida. La expresin queda T (n) = 1 + T (n/3) + 1 + T (n/3) lo que equivale a que T (n) = 2T (n/3) + c con c constante. Aplicando la resolucin genrica de las expresiones del tipo T (n) = aT (n/b) + cnk con k = 0, a = 2 y b = 3 queda que 2 > 30 y por tanto la funcin T(n) 2 tiene un coste O(nlog3 ). De forma anloga, el segundo algoritmo dos est formado por una instruccin condicional cuyo cuerpo incluye secuencialmente (i) una llamada recursiva de tamao n/4, (ii) una instruccin simple, (iii) otra llama recursiva de tamao n/4, (iv) un bucle en el que se repite n veces un clculo consistente en llamar dos veces a una funcin h(n, r, i) de coste lineal, ms una instruccin simple, y por ltimo (v) una instruccin simple y otra llamada recursiva de tamao n/4. Sumando los 5 trminos nos sale T (n) = T (n/4) + 1 + T (n/4) + n (2n + 1) + 1 + T (n/4), lo que equivale a T (n) = 3T (n/4) + 4n2 y siendo 3 < 42 el coste es O(n2 ).

Cuestin 2
Un procedimiento parcial de ordenacin por seleccin nos da los m elementos ms pequeos con coste O(m.n). Una ordenacin eciente sin embargo lo hara en O(n.log n). Si m n, el coste vendra a ser cuadrtico, lo cual nos hara desechar el procedimiento de seleccin, sin embargo con m << n el orden O(n.m) se puede considerar lineal, y en este caso el algoritmo de seleccin puede ser ms eciente.

Cuestin 3
Cada casilla se asimila a un nodo. Casillas libres adyacentes tendran aristas dirigidas en ambas direcciones. El peso sera unitario para cada arista. Las casillas de tipo ocupada no tienen aristas origen ni destino. De esta forma, un algoritmo de Dijkstra puede hallar el camino ms corto de un nodo llegada a todos los dems, incluyendo el nodo salida. En trminos de coste, sin embargo es necesario tener en cuenta que si el laberinto es un cuadrado de lado n, el grafo tendr v = n2 nodos y alrededor de a = 4n2 aristas. En el anlisis de coste de la resolucin de Dijkstra si v (nmero de nodos del grafo) es lo sucientemente grande hace cierta la expresin a << v 2 y por tanto podemos aproximarnos al coste O((a + v).log v).

Problema
Se trata de un grafo no dirigido de 10 nodos n1 , n2 , . . . , n10 con una matriz simtrica de costes:

1 2 3 4 5 6 7 8 9 10

1 2 3 4 5 6 7 8 9 10
3 4 5 6 7 0 1 2 3
3 5 6 7 0 1 2 3 4
4 5 7 0 1 2 3 4 5
5 6 7 1 2 3 4 5 6
6 7 0 1 3 4 5 6 7
7 0 1 2 3 5 6 7 0
0 1 2 3 4 5 7 0 1
1 2 3 4 5 6 7 1 2
2 3 4 5 6 7 0 1 3
3 4 5 6 7 0 1 2 3 -

Se trata de conseguir minimizar el coste de los enlaces asegurando nicamente la conectividad de la red. El enunciado describe un problema de optimizacin en el que se nos pide que el grafo sea conexo ("asegurar la conectividad de la red") y contenga un rbol de expansin mnimo ("que el coste sea mnimo"), ya que la conectividad se asegura no dejando subgrafos no conexos.
Eleccin del esquema: Con las condiciones descritas podemos usar algoritmos que re-

suelvan el problema del rbol de expansin mnimo, dentro de la familia de los algoritmos voraces.
Descripcin del esquema: Se elige cualquiera de los algoritmos expuestos en el temario

Kruskal o Prim, por ejemplo ste ltimo.

funcin Prim(G:grafo):T:conjunto de aristas


T B1

mientras B = N hacer { min e = {u, v} tq. u B y v N \B


T T {e} B B {v}
}

dev T
Hemos tomado 1 como nodo arbitrario. El conjunto B va a ir conteniendo los nodos del subgrafo ya conexo y el conjunto T ir teniendo en cada iteracin aquellas aristas del rbol de expansin mnimo que contiene los nodos de B . El conjunto de candidatos es B , la condicin de nalizacin es que B = N y la funcin de optimizacin es elegir aquella arista del subgrafo

B que conecte con algn nodo de N \B con menor coste.


Estructuras de datos: El grafo se representar mediante una matriz de costes. La estruc-

tura de datos tendr un mtodo que implementa el clculo de la distancia entre dos nodos. En el caso de esta implementacin la distancia entre dos nodos i y j es el valor de la matriz de distancias, y su coste O(1).
Algoritmo completo a partir del esquema general:

T B1 para i 2 hasta n hacer masP roximo[i] 1 distanciaM in[i] G.distancia[i, 1] repetir n 1 veces{ min para j 2 hasta n hacer { \* Selecciona la mejor arista entre B y N \B *\ si (distanciaM in[j] 0) (distanciaM in[j] < min) ent { distanciaM in[k] G.distancia(j, k) masP roximo[j] k } } T T {masP roximo[k], k} \* Aade la arista *\ distanciaM in[k] 1 para j 2 hasta n hacer { si G.distancia(j, k) < distanciaM in[j] ent { distanciaM in[k] G.distancia(j, k) masP roximo[j] k } } } dev T

funcin Prim(G:grafo):T:conjunto de aristas

Coste: El coste del algoritmo de Prim es O(n2 ), que puede mejorarse utilizando una repre-

sentacin de montculos para el vector distanciaM in[]

Optimalidad: El algoritmo de Prim encuentra la solucin ptima. Se puede demostrar por

induccin sobre T que aadir la arista ms corta {e} que sale de T (Lema 6.3.1 del texto base) forma en T {e} un rbol de recubrimiento mnimo que contendr al nal n 1 aristas y todos los nodos del grafo G.
Aplicacin al problema: Tenemos los siguientes conjuntos inicialmente B = {1} y la

arista mnima entre un nodo de B y otro de N \B es u = (1, 7) con valor 0.

Los valores de B y la u elegida en cada momento evolucionan como sigue:

B = {1, 7} u = (7, 9) Coste: 0 B = {1, 7, 9} u = (7, 2) Coste: 1 B = {1, 2, 7, 9} u = (2, 6) Coste: 0 B = {1, 2, 6, 7, 9} u = (6, 10) Coste: 0 B = {1, 2, 6, 7, 9, 10} u = (6, 3) Coste: 1 B = {1, 2, 3, 6, 7, 9, 10} u = (3, 5) Coste: 0 B = {1, 2, 3, 5, 6, 7, 9, 10} u = (6, 3) Coste: 0 B = {1, 2, 3, 5, 6, 7, 8, 9, 10} u = (9, 8) Coste: 1 B = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} u = (9, 8) Coste: 1
Coste del rbol de expansin mnimo: 4

Programacin III
Cdigos de asignatura: Sistemas: 402048; Gestin: 41204-

Extraordinario Diciembre de 2003

UNIVERSIDAD NACIONAL DE EDUCACIN A DISTANCIA

Prueba Presencial

Duracin: 2 horas Material permitido: NINGUNO


DNI: _______________________

Apellidos: ___________________________________________________________________________________

Nombre: ______________________________ Centro donde entreg la prctica: ____________________ Especialidad: ____________

Cuestin 1 (2 puntos). Qu significa que el tiempo de ejecucin de un algoritmo est en el orden exacto de f(n)?. Demostrar que T(n)=52n+n2 est en el orden exacto de 2n.

Cuestin 2 (2 punto). Qu diferencias hay entre un montculo y un rbol binario de bsqueda?

Cuestin 3 (2 puntos). Cules son los casos mejor y peor para el algoritmo de ordenacin rpida (Quicksort)? Cul es el orden de complejidad en cada uno de ellos? Razona tu respuesta.

Problema (4 puntos). Hoy es un da duro para el taller Sleepy. Llegan las vacaciones y a las 8:00 de la maana n clientes han pedido una revisin de su coche. Como siempre, todos necesitan que les devuelvan el coche en el menor tiempo posible. Cada coche necesita un tiempo de revisin ri y al mecnico le da lo mismo por cul empezar: sabe que en revisar todos los coches tardar lo mismo independientemente del orden que elija. Pero al jefe de taller no le da lo mismo, la satisfaccin de sus clientes es lo que importa: es mejor tener satisfechos al mayor nmero de ellos. Al fin y al cabo, la planificacin la hace l y, evidentemente, un cliente estar ms satisfecho cuanto menos tarden en devolverle el coche. Implementar un programa que decida el orden en el que revisar uno a uno los coches para maximizar la satisfaccin de los clientes de Sleepy.

La resolucin del problema debe incluir, por este orden: 1. Eleccin razonada del esquema algortmico 2. Descripcin del esquema usado e identificacin con el problema 3. Estructuras de datos 4. Algoritmo completo a partir del refinamiento del esquema general 5. Estudio del coste

Enero de 2004

Programacin III
Cdigo de asignatura (marcar con crculo): Sistemas: __ 402048 (plan viejo) __ 532044 (plan nuevo) Gestin: __ 41204- (plan viejo) __ 542046 (plan nuevo)

Prueba Presencial Segunda Semana Febrero de 2004

UNIVERSIDAD NACIONAL DE EDUCACIN A DISTANCIA

Duracin: 2 horas Material permitido: NINGUNO


DNI: _______________________

Apellidos: ___________________________________________________________________________________

Nombre: ______________________________ Centro donde entreg la prctica: ____________________ e-mail: ___________________

Cuestin 1 (1 puntos). En qu orden est el tiempo de ejecucin del siguiente algoritmo? Justifica tu respuesta. Procedimiento h(n,i,j) si n>0 entonces h(n-1,i,6-i-j); escribir i -> j; h(n-1,6-i-j,j); fsi; T(n)=2T(n-1)+1, luego nmero de llamadas: a=2 reduccin por sustraccin: b=1 cnk=1, k=0 Aplicando la recurrencia para el caso cuando a>1: T(n)(an div b); T(n)(2n) Cuestin 2 (2 punto). Aplica el algoritmo de Kruskal al siguiente grafo indicando claramente en cada paso qu arista se selecciona, la evolucin de las componentes conexas y la evolucin de la solucin.
2 4 5 2 4 5

1 6 3 3 4 6

Se ordenan las aristas de menor a mayor coste: {(2,3),(4,5),(2,4),(3,5),(3,6),(2,5),(1,2),(1,3),(5,6)} Arista Evolucin de las componentes Evolucin de la solucin seleccionada conexas {1} {2} {3} {4} {5} {6} (2,3) {1} {2,3} {4} {5} {6} {(2,3)} (4,5) {1} {2,3} {4,5} {6} {(2,3), (4,5)} (2,4) {1} {2,3,4,5} {6} {(2,3), (4,5), (2,4)} (3,5) Se rechaza porque los extremos de la arista ya estn en la misma comp. conexa
La resolucin del problema debe incluir, por este orden: 1. Eleccin razonada del esquema algortmico 2. Descripcin del esquema usado e identificacin con el problema 3. Estructuras de datos 4. Algoritmo completo a partir del refinamiento del esquema general 5. Estudio del coste

(3,6) {1} {2,3,4,5,6} {(2,3), (4,5), (2,4), (3,6)} (2,5) Se rechaza porque los extremos de la arista ya estn en la misma comp. conexa (1,2) {1,2,3,4,5,6} {(2,3), (4,5), (2,4), (3,6), (1,2)} Proceso terminado porque slo queda una nica componente conexa Cuestin 3 (2 puntos). Cundo resulta ms apropiado utilizar una exploracin en anchura que en profundidad? - Cuando el grafo tiene ramas infinitas - Cuando se busca el camino de menor nmero de nodos o aristas - Cuando los nodos finales se encuentran cerca del nodo raz En que casos puede que la exploracin en anchura no encuentre solucin aunque sta exista? - Que exista una solucin quiere decir que existe un camino desde el nodo inicial al nodo final. No tiene sentido, entonces, hablar de que la solucin est en una componente conexa diferente. Por otro lado, el caso en que un nodo genere infinitos hijos es un caso excepcional que no debera darse. Por todo ello, y salvo esta ltima excepcin, la exploracin en anchura siempre encuentra la solucin, si sta existe. Y la exploracin en profundidad? Razona tu respuestas. - Si existen ramas infinitas sin nodos finales puede que la exploracin en profundidad quede atrapada en una de ellas y no encuentre solucin aunque sta exista. Problema (5 puntos). Dado un grafo dirigido, finito, con ciclos y con todas las aristas de coste unitario, implementar un algoritmo que devuelva el nmero de nodos que contiene el camino ms largo sin ciclos que se puede recorrer desde un determinado nodo. Eleccin del esquema. Hallar el camino ms largo desde un nodo en un grafo finito puede verse como un problema de determinar cul es la profundidad mxima del rbol. Para ello, ser necesario recorrer todos los caminos sin ciclos del grafo, almacenando la longitud del ms largo encontrado hasta el momento. El esquema de bsqueda exhaustiva en profundidad nos permite resolver este problema. Descripcin del esquema e identificacin con el problema. En la pgina 330 del libro de texto (Brassard, 1997) se presenta el esquema de recorrido en profundidad: procedimiento rp(nodo) {nodo no ha sido visitado anteriormente} visitado[nodo]:=cierto; para cada hijo en adyacentes[nodo] hacer si visitado[nodo]=falso entonces rp(hijo) fsi fpara

As planteado, un nodo no se explorara 2 veces aunque llegramos a l desde una rama distinta. Esto es incorrecto y se debe a que el vector de nodos visitados se plantea de forma global. Veamos un ejemplo:
1 5 2 6 3

La exploracin llega al nodo 1 y lo marca como visitado. Anlogamente sigue marcando como visitados los nodos 2, 3 y 4, hallando un camino de longitud 4. Cundo el control regresa al nodo 1 para explorar ramas alternativas, se explora el nodo 5, el 6, pero cuando llega al nodo 3, se detiene la exploracin porque 3 est marcado como visitado. El nuevo camino encontrado tiene 4 nodos en vez de 5 que sera lo correcto. Este problema lo podemos corregir si el vector de visitados tiene un mbito local en vez de global, y se pasa una copia de padres a hijos (paso de parmetro por valor).

Estructuras de datos Necesitaremos una estructura para grafo. La ms compacta y sencilla de usar es un vector en el que la componente i tiene un puntero a lista de nodos adyacentes al nodo i. Por tanto, tambin necesitaremos implementar una lista de nodos que puede ser, simplemente, una lista de enteros. Adems, necesitaremos un vector de nodos visitados por rama. Algoritmo completo procedimiento longitud(nodo,visitados) dev long {nodo no ha sido visitado anteriormente} visitados[nodo]:=cierto; long_max:=0; para cada hijo en adyacentes[nodo] hacer si visitados[nodo]=falso entonces long:=longitud(hijo,visitados); si long>long_max entonces long_max:=long fsi; fsi fpara devolver long_max+1; La llamada inicial se realiza con el nodo inicial, y los elementos del vector de visitados inicializados a falso. Estudio del coste Sea n el nmero de nodos del grafo. Si suponemos un grafo denso (en el que todos los nodos estn interconectados entre s), tenemos que la longitud del camino mximo ser n. Cada

llamada recursiva, entonces, supondr una reduccin en uno del problema. As mismo, el nmero de llamadas recursivas por nivel tambin ira disminuyendo en uno puesto que en cada nivel hay un nodo adyacente ms que ya ha sido visitado. Por ltimo, dentro del bucle se realizan al menos n comparaciones. Por tanto, podemos establecer la siguiente recurrencia: T(n)=(n-1)T(n-1)+n nmero de llamadas: a=n-1 reduccin por sustraccin: b=1 cnk=n, k=1 Aplicando la recurrencia para el caso cuando a>1: T(n)O(an div b); T(n)O(nn) Al mismo resultado se puede llegar razonando sobre la forma del rbol de exploracin.

Programacin III
Cdigo de asignatura (marcar con una X): Sistemas: __ 402048 (plan viejo) __ 532044 (plan nuevo) Gestin: __ 41204- (plan viejo) __ 542046 (plan nuevo)

Prueba Presencial Original Septiembre de 2004

UNIVERSIDAD NACIONAL DE EDUCACIN A DISTANCIA

Duracin: 2 horas Material permitido: NINGUNO


DNI: _______________________

Apellidos: ___________________________________________________________________________________

Nombre: ______________________________ Centro donde entreg la prctica: ____________________ e-mail: ___________________

Cuestin 1 (2 puntos). Qu significa que el tiempo de ejecucin de un algoritmo est en el orden exacto de f(n)? Demostrar que T(n)=n3+9n2log(n) est en el orden exacto de n3.
La definicin formal es (f(n)) = O(f(n)) (f(n)) , y considerando que si lim f (n)/g(n) + entonces f(n) (g(n)) n segn la relacin del apartado 3.3 (Ver p. 100 del texto base) y adems aplicamos el teorema de LHopital (p. 38) obtenemos que:

lim f (n)/g(n) = n

lim f (n)/g(n) con lo que: n lim 3n2 + 18nlog(n) + 9n / 3n2 = lim 6n + 18log(n) + 27 / 6n = n n

lim n3 + 9 n2 log(n) / n3 = n

lim 6n +18 / 6n = n

con lo que n3 + 9 n2 log(n) ( n3)

Tambin ser vlido hallar las constantes c y d segn la definicin de la notacin Theta (p.100)

Cuestin 2 (2 puntos). Implementar una versin recursiva de una funcin que tome un vector y le d estructura de montculo. A partir de una implementacin recursiva en MODULA-2 de Flotar (P. ej.):
PROCEDURE Flotar(i: INTEGER; VAR T: TipoMonticulo); VAR i_padre: INTEGER; BEGIN La resolucin del problema debe incluir, por este orden: 1. Eleccin razonada del esquema algortmico 2. Descripcin del esquema usado e identificacin con el problema 3. Estructuras de datos 4. Algoritmo completo a partir del refinamiento del esquema general 5. Estudio del coste

i_padre := i DIV 2 ;

IF (i > 1) AND T[i]<T[i_padre]) THEN Intercambia(T[i],T[i_padre]); Flotar(i_padre,T); END; END Flotar;

Se puede implementar la creacin de montculo como: procedimiento crear_monticulo(T[1..n],i) si i>n devuelve(T) sino flotar(i,T) crear_monticulo(T,i+1) fsi fprocedimiento La llamada inicial ser crear_monticulo(T,2) Otra versin pero en este caso sin usar funciones auxiliares es sustituir el cdigo de flotar por su versin iterativa e insertarlo en la funcin anterior. Cuestin 3 (1 punto). En qu se diferencian los algoritmos de Prim y de Kruskal? Discute tanto los algoritmos como su complejidad en los casos peores de cada uno.
En primer lugar difieren en la forma de crear el camino mnimo. En el caso de Prim la solucin es siempre un AEM y en el otro caso, lo son las componentes conexas pero sin referencia al grafo inicial, salvo al final del mismo. En segundo lugar en trminos de coste, el algoritmo de Kruskal requiere un tiempo que est en (a log n) con a el nmero de aristas, por lo que en el caso peor si el grafo es denso y a se acerca a n2, entonces es menos eficiente que el de Prim que es cuadrtico, ocurriendo lo contrario para grafos dispersos.

Problema (5 puntos). Sean dos vectores de caracteres. El primero se denomina texto y el segundo consulta, siendo ste de igual o menor longitud que el primero. Al vector consulta se le pueden aplicar, cuantas veces sea necesario, los siguientes tres tipos de operaciones, que aaden cada una un coste diferente a la edicin de la consulta: Intercambio de dos caracteres consecutivos: coste de edicin igual a 1 Sustitucin de un carcter por otro cualquiera: coste de edicin igual a 2 Insercin de un carcter cualquiera en una posicin cualquiera: coste de edicin igual a 3 Implementar una funcin que escriba la secuencia de operaciones con menor coste total que hay que realizar sobre el vector consulta para que coincida exactamente con el vector texto. La

funcin devolver el coste total de estas operaciones, es decir, la suma de los costes asociados a cada operacin realizada. 1. Eleccin razonada del esquema algortmico La solucin es resultado de una secuencia de pasos o decisiones pero no se puede establecer un criterio ptimo de seleccin de cada decisin por lo que no puede ser un esquema voraz. Por tanto hay que realizar una exploracin de las posibles soluciones y buscar la ptima. Debido a que hay un criterio de optimalidad, es decir, existe una funcin que decide si un nodo puede llevar a una solucin mejor que la encontrada hasta el momento, el esquema adecuado es Ramificacin y Poda. 2. Descripcin del esquema

Funcin RamificacinPoda (nodo_raz) dev nodo inicializarSolucin(Solucin,valor_sol_actual); Montculo:=montculoVaco(); cota:=acotar(nodo_raz); poner((cota,nodo_raz),Montculo); mientras no vaco(Montculo) hacer (cota,nodo):=quitarPrimero(Montculo); si es_mejor(cota, valor_sol_actual) entonces si vlido(nodo) entonces /*cota es el valor real de la mejor solucin hasta ahora*/ valor_sol_actual:=cota; Solucin:=nodo; fsi; si no para cada hijo en compleciones(nodo) hacer cota:=acotar(hijo); poner((cota,hijo),Montculo); fpara; fsi; sino devolver Solucin fsi; /*termina el bucle, montculo no tiene mejores*/ fmientras devolver Solucin; 3. Estructuras de datos Vector de texto Vector de consulta Montculo de mnimos en el que cada componente almacene una solucin parcial (nodo) con su cota correspondiente. nodo=tupla acciones: lista de Strings; ltimo_coincidente: cardinal; long: cardinal; coste: cardinal;

4. Algoritmo completo inicializarSolucin

La solucin inicial debe tener un coste asociado mayor o igual que la solucin final. De acuerdo con el problema, basta con realizar sustituciones de los caracteres de la consulta (coste=2*long_consulta) y realizar la insercin de los caracteres que faltan (coste=3*(long_texto-long_consulta)). Adems tenemos que construir la solucin inicial: la secuencia de sustituciones e inserciones. Funcin inicializarSolucin(long_consulta, texto, long_texto, Solucin, valor_sol_actual); valor_sol_actual:= 2*long_consulta+3*(long_texto-long_consulta); Solucin:=listaVacia(); para i desde 1 hasta long_consulta hacer aadir(Solucin, sustituir i por texto[i]); fpara; para i desde long_consulta+1 hasta long_texto hacer aadir(Solucin, insertar en i, texto[i]); fpara; vlido(nodo) Un nodo ser vlido (como solucin) si se han hecho coincidir los long_texto caracteres de texto. Para ello, vamos a ir haciendo coincidir la solucin desde el principio del vector hasta el final. por tanto, un nodo ser vlido (aunque no sea la mejor solucin todava) si: nodo.ltimo_coincidente==long_texto es_mejor(cota, valor_sol_actual) Como se trata de encontrar la solucin de menor coste, una cota ser mejor que el valor de la solucin actual si: cota<valor_sol_actual acotar(nodo) Se trata de realizar una estimacin que sea mejor o igual que la mejor solucin que se puede alcanzar desde ese nodo. De esta manera sabremos que si, an as, la estimacin es peor que la solucin actual, por esa rama no encontraremos nada mejor y se puede podar. La mejor estimacin ser sumar al coste ya acumulado, el menor coste que podra tener completar la solucin: que el resto de caracteres de consulta coincidieran (coste=0) y realizar tantas inserciones como caracteres nos falten (coste=2*(long_texto-nodo.long)). Es decir, acotar(nodo) es: nodo.coste+2*(long_texto-nodo.long) compleciones(nodo) Sabiendo que hasta nodo.ltimo_coincidente todos los caracteres coinciden, se trata de considerar las posibilidades para que el siguiente carcter de la consulta coincida con el texto: No hacer nada si ya coinciden de antemano. Intercambiarlo por el siguiente si ste coincide con el texto. Sustituirlo por el correspondiente del texto Insertar el correspondiente del texto y correr el resto del vector, siempre que la consulta no haya alcanzado el tamao del texto. Si se da el primer caso, no es necesario generar el resto de compleciones porque no se puede encontrar una solucin mejor con ninguna de las otras alternativas. An as, no pasara nada si se incluyen. Sin embargo, para el resto de alternativas, no hay garantas

de que una permita encontrar mejor solucin que otra, aunque el coste de la accin puntual sea menor. Por tanto, hay que incluir todas las alternativas. Funcin compleciones(nodo, texto, long_texto, consulta) dev lista_nodos lista:=crearLista(); si consulta[hijo.ltimo_coincidente]==texto[hijo.ltimo_coincidente] entonces hijo:=crearNodo(); hijo.ltimo_coincidente:=nodo.ltimo_coincidente+1; hijo.acciones=nodo.acciones; hijo.coste=nodo.coste; hijo.long=nodo.long; aadir(lista, hijo); si no /* intercambio */ si consulta[hijo.ltimo_coincidente+1]==texto[hijo.ltimo_coincidente] entonces intercambiar(consulta[hijo.ltimo_coincidente], consulta[hijo.ltimo_coincidente+1]); hijo:=crearNodo(); hijo.ltimo_coincidente:=nodo.ltimo_coincidente+1; hijo.acciones=nodo.acciones; aadir(hijo.acciones,intercambiar consulta[hijo.ltimo_coincidente] por consulta[hijo.ltimo_coincidente+1]); hijo.coste=nodo.coste+1; hijo.long=nodo.long; aadir(lista, hijo); fsi; /* sustitucin */ hijo:=crearNodo(); hijo.ltimo_coincidente:=nodo.ltimo_coincidente+1; hijo.acciones=nodo.acciones; insertar(hijo.acciones,sustituir hijo.ltimo_coincidente por texto[hijo.ltimo_coincidente]); hijo.coste=nodo.coste+2; hijo.long=nodo.long; aadir(lista, hijo); /* insercin */ si (nodo.long<long_texto) entonces hijo:=crearNodo(); hijo.ltimo_coincidente:=nodo.ltimo_coincidente+1; hijo.acciones=nodo.acciones; insertar(hijo.acciones,insertar en hijo.ltimo_coincidente, texto[hijo.ltimo_coincidente]); hijo.coste=nodo.coste+3; hijo.long=nodo.long+1; aadir(lista, hijo); fsi; fsi; devolver lista;

La funcin principal quedara entonces como sigue: Funcin ajustar(consulta, long_consulta, texto, long_texto) dev coste inicializarSolucin(long_consulta, texto, long_texto, Solucin, valor_sol_actual); Montculo:=montculoVaco(); nodo.acciones=listaVacia(); nodo.ltimo_coincidente=0; nodo.coste=0; nodo.long=long_consulta; cota:= nodo.coste+2*(long_texto-nodo.long); poner((cota,nodo),Montculo); mientras vaco(Montculo) hacer (cota,nodo):=quitarPrimero(Montculo); si cota<valor_sol_actual entonces si nodo.ltimo_coincidente==long_texto entonces valor_sol_actual:=cota; solucin:=nodo.acciones; si no para cada hijo en compleciones(nodo, texto, long_texto, consulta) hacer cota:= nodo.coste+2*(long_texto-nodo.long); poner((cota,hijo),Montculo); fpara; fsi; sino /* Ya no puede haber una solucin mejor */ escribir(solucin); devolver valor_sol_actual; fsi; fmientras escribir(solucion); devolver valor_sol_actual; 5. Estudio del coste En este caso nicamente podemos hallar una cota superior del coste del algoritmo por descripcin del espacio de bsqueda. En el caso peor se generan 3 hijos por nodo hasta llegar a una profundidad de long_texto. Por tanto, el espacio a recorrer siempre ser menor que 3long_texto.

Programacin III
Cdigos de asignatura: Sistemas: 402048; Gestin: 41204UNIVERSIDAD NACIONAL DE EDUCACIN A DISTANCIA

Primera Semana Febrero 2005 Duracin: 2 horas Material permitido: NINGUNO


DNI: _______________________

Prueba Presencial

Apellidos: ___________________________________________________________________________________ Nombre: _____________________________________

Centro Asociado en el que entreg la prctica: _______________________

Cuestin 1 (2 puntos).
Se dispone de un conjunto de ficheros f1, f2, ..., fn con tamaos I1, I2, ..., In y de un disquete con una capacidad total de almacenamiento de d<I1+I2+...+In. a) Suponiendo que se desea maximizar el nmero de ficheros almacenados y que se hace uso de un planteamiento voraz basado en la seleccin de ficheros de menor a mayor tamao, el algoritmo propuesto siempre obtendra la solucin ptima?. En caso afirmativo demostrar la optimalidad y en caso negativo ponga un contraejemplo; b) En caso de que quisiramos ocupar la mayor cantidad de espacio en el disquete independientemente del nmero de ficheros almacenados, una estrategia voraz basada en la seleccin de ficheros de mayor a menor tamao obtendra en todos los casos la solucin ptima?. En caso afirmativo demuestre la optimalidad, en caso negativo ponga un contraejemplo.

Solucin: Apartado A
El algoritmo voraz obtendra la solucin ptima, es decir, un disquete con el mayor nmero posible de ficheros. Demostracin: Suponiendo que los programas se encuentran inicialmente ordenados de menor a mayor tamao, vamos a demostrar la optimalidad de la solucin comparando una solucin ptima con una solucin obtenida por el algoritmo voraz. Si ambas soluciones no fueran iguales, iremos transformando la solucin ptima de partida, de forma que contine siendo ptima, pero asemejndola cada vez ms con la obtenida por el algoritmo voraz. Si consiguiramos igualar ambas soluciones en un nmero finito de pasos, entonces podremos afirmar que la solucin obtenida por el algoritmo es ptima. Notacin: Una solucin cualquiera viene representada por Z=(z1, z2, ..., zn) donde zi=0 implica que el fichero fi no ha sido seleccionado como parte de la solucin. De este modo,

z
i =1

indicar el nmero de ficheros seleccionados

como solucin al problema. Siendo X la solucin devuelta por la estrategia voraz e Y la solucin ptima al problema. Supongamos que la estrategia voraz propuesta selecciona los k primeros ficheros (con 1 k n), recordamos que los ficheros se encuentran inicialmente ordenados de menor a mayor tamao. El fichero k+1 es rechazado puesto que ya no es posible incluir un solo fichero ms. De este modo, la solucin X ser (x1, x2, ..., xk,..., xn), donde i { ..k }.x i = 1 y 1 i {k + 1..n}.x i = 0 . Comenzando a comparar X con Y de izquierda a derecha, supongamos que j 1 sea la primera posicin donde xj yj . En este caso, obligatoriamente j k ya que en caso contrario la solucin ptima incluira todos los ficheros escogidos por la estrategia voraz y alguno ms, lo que se contradice con el hecho de que los ficheros del k+1 al n se rechazan por la estrategia voraz porque no caben. Este modo, xj yj implica que yi=0, por lo que

y
i =1

= j 1 , que es menor que el nmero de ficheros seleccionados

por nuestra estrategia voraz como solucin al problema

x
i =1

= j . Como suponemos que Y es una solucin ptima,


i =1

yi

x
i =1

= k , esto significa que existe un l > k j tal que yl = 1, es decir, existe un fichero posterior para

compensar el que no se ha cogido antes. Por la ordenacin impuesta a los ficheros, sabemos que lj ll, es decir, que si fl cabe en el disco, podemos poner en su lugar fj sin sobrepasar la capacidad total. Realizando este cambio en la solucin ptima Y, obtenemos otra solucin Y en la cual yj= 1 = xj, yl=0 y para el resto yi = yi. Esta nueva solucin es ms parecida a X, y tiene el mismo nmero de ficheros que Y, por lo que sigue siendo ptima. Repitiendo este proceso, podemos ir igualando los ficheros en la solucin ptima a los de la solucin voraz X, hasta alcanzar la posicin k.

Apartado B
El algoritmo voraz no obtendra la solucin ptima en todos los casos. Contraejemplo: Supongamos la siguiente lista de ficheros con tamaos asociados: Fichero F1 Tamao 40 Supongamos que la capacidad mxima del disquete es 45. Aplicando la estrategia voraz propuesta, nicamente podramos almacenar el fichero F1, ocupando 40 de los 45 de capacidad que tiene el disquete. Sin embargo, si hubiramos seleccionado los ficheros F2 y F3 hubiera sido posible maximizar el espacio ocupado en el disco. F2 30 F3 15

Cuestin 2 (2 punto).
Exponga y explique el algoritmo ms eficiente que conozca para realizar una planificacin de tareas con plazo fijo maximizando el beneficio. Dada la tabla adjunta de tareas con sus beneficios (gi) y caducidades (di) asociados. Aplique paso a paso el algoritmo propuesto, suponiendo que se desea realizar una planificacin en un tiempo t=5. i gi di 1 30 5 2 10 3 3 2 2 4 11 2 5 10 1 6 9 2 7 2 7 8 56 5 9 33 4

Solucin: Apartado A
El algoritmo ms apropiado es el algoritmo secuencia2 explicado y desarrollado en pg 240-241 del texto base y que ha sido utilizado en la prctica (Bloque 1). El alumno debe haberlo expuesto y explicado.

Apartado B
1. Inicialmente ordenamos la tabla propuesta por orden decreciente de beneficios. 2. Creamos el nmero apropiado de estructuras de particin. p=min(9,max(di))=min(9,7)=7. Como en este caso concreto queremos nicamente planificar las 5 primeras tareas p puede reducirse a 5. 3. Vamos extrayendo cada una de las tareas por orden decreciente de beneficios e incluyndolas en su correspondiente estructura de particin. Esta operacin implica fusionar la estructura en la cual se ha incluido la tarea con la estructura de particin inmediatamente anterior. 4. El algoritmo termina cuando ya no queda ninguna estructura de particin libre para asignar tarea. i gi di 8 9 1 4 5 2 6 3 7 56 33 30 11 10 10 9 2 2 5 4 5 2 1 3 2 2 7 Tabla de costes y caducidades ordenada

El proceso puede esquematizarse del siguiente modo:

0 0

1 1

2 2

3 3

4 4

5 5

0 Res[]

0 0

1 1

2 2

3 3

4 4

Selecciono tarea 8 0 Res[] 5 1 2 3 4 8

0 0

1 1

2 2

3 3

Selecciono tarea 9 0 Res[] 4 5 1 2 3 9 4 8

0 0

1 1

2 2

Selecciono tarea 1 0 Res[] 3 4 5 1 2 1 3 9 4 8

0 0

1 1

Selecciono tarea 4 0 Res[] 2 3 4 5 1 4 2 1 3 9 4 8

Selecciono tarea 5 0 Res[] 1 2 3 4 5 5 1 4 2 1 3 9 4 8

Cuestin 3 (1 punto).
Explique las diferencias entre un recorrido en anchura y un recorrido en profundidad. Exponga un algoritmo iterativo para cada uno de los recorridos explicando las estructuras de datos asociadas, as como su coste.

Solucin:
En las pginas 338 y 339 del texto base puede encontrarse una explicacin tanto de las diferencias entre ambos tipos de recorrido, como un algoritmo iterativo para cada uno de ellos basado en el uso de PILAS y COLAS como estructuras de datos asociadas.

Problema (5 puntos).
Partiendo de un conjunto N={n1, n2, ..., nm} compuesto por m nmero positivos y de un conjunto O={+,-,*,/} con las operaciones aritmticas bsicas, se pide obtener una secuencia de operaciones factible para conseguir un nmero objetivo P. Como restricciones al problema, debe tenerse en cuenta que: a) los nmeros del conjunto N pueden utilizarse en la secuencia de operaciones 0 o 1 vez, b) los resultados parciales de las operaciones pueden utilizarse como candidatos en operaciones siguientes, c) las operaciones que den como resultado valores negativos o nmeros no enteros NO debern tenerse en cuenta como secuencia vlida para obtener una solucin. Disee un algoritmo que obtenga una solucin al problema propuesto, mostrando la secuencia de operaciones para obtener el nmero objetivo P. En caso de no existir solucin alguna, el algoritmo deber mostrar la secuencia de operaciones que d como resultado el valor ms prximo, por debajo, del nmero objetivo P. Por ejemplo, siendo P=960 y N={1,2,3,4,5,6}, la secuencia de operaciones que obtiene la solucin exacta es: ((((6*5)*4)*2)*(3+1))=960. Si P=970, el algoritmo no encontrara la solucin exacta con el conjunto de nmeros inicial y la secuencia ms prxima por debajo de P sera ((((6*5)*4)*2)*(3+1))=960.

Solucin: Eleccin Razonada del Esquema Algortmico.


Obviamente no se trata de un problema que pueda ser resuelto por divide y vencers, puesto que no es posible descomponer el problema en subproblemas iguales, pero de menor tamao, que con algn tipo de combinacin nos permita encontrar la solucin del problema. Tampoco se trata de un algoritmo voraz, puesto que no existe ninguna manera de atacar el problema de manera directa que nos lleve a la solucin sin necesidad de, en algn momento, deshacer alguna de las decisiones tomadas. Por tanto, se trata de un problema de exploracin de grafos donde deberemos construir el grafo implcito al conjunto de operaciones posibles con el fin de encontrar una solucin al problema. Descartamos una exploracin ciega en profundidad o en anchura puesto que, como en la mayor parte de los casos va a existir por lo menos una solucin y adems el enunciado del problema solicita una solucin al problema y no todas, es deseable que la exploracin se detenga en el momento en el que encuentre alguna de ellas. Slo en el caso de que no exista solucin al problema, a partir del conjunto N inicial, el recorrido deber ser completo. De acuerdo a este razonamiento, la estrategia ms apropiada parece la de aplicar un esquema del tipo backtracking o vuelta atrs. Como el alumno ya conoce, este tipo de algoritmos se basan en un recorrido en profundidad o en anchura que no construye el grafo implcito de manera exhaustiva, puesto que dispone de condiciones de corte que lo detienen en cuanto se encuentra una solucin. En nuestro caso, adems, basaremos el algoritmo en un recorrido en profundidad y no en anchura puesto que en la mayor parte de las ocasiones es necesario combinar prcticamente la totalidad de los elementos de N para obtener la solucin. La alternativa de aplicar un algoritmo de ramificacin y poda no es vlida en este caso pues este tipo de algoritmos se caracteriza por obtener la solucin ptima a un problema concreto. En este caso no es necesario optimizar absolutamente nada, pues la solucin es el nmero objetivo que nos solicitan y no van a existir, por tanto, soluciones mejores o peores. Slo en el caso de que no exista solucin, el problema nos pide la ms aproximada por debajo, lo cual implica una exploracin exhaustiva del grafo implcito y, por tanto, el conocimiento por parte del algoritmo de cual ha sido la operacin ms aproximada realizada hasta el momento.

Descripcin del Esquema Algortmico de Vuelta Atrs.


fun vuelta-atrs(e: ensayo) si valido(e) entonces dev e sino listaensayos complecciones(e) mientras vacia(listaensayos) resultado hacer hijo primero(listaensayos) listaensayos resto(listaensayos) si condicionesdepoda(hijo) entonces resultado vuelta-atrs(hijo) fsi fmientras dev resultado fsi ffun

Estructuras de Datos Necesarias


La estructura de datos principal para llevar a cabo nuestro algoritmo va a ser aquella encargada de almacenar la informacin relativa a cada uno de los ensayos generados:
Tipo Tensayo= candidatos: vector de int operaciones: vector de TpilaOperaciones solucion: boolean vacio: boolean Operaciones Asociadas --------------------getCandidatos():vector Devuelve el vector de candidatos para operar con l. getOperaciones():vector Devuelve el vector de operaciones(pilas) para operar con l. getCandidato(indexCand int):int Devuelve el candidato que se encuentra en la posicin indexCand. removeCandidato(indexCand int):void Elimina el candidato que se encuentra en la posicin indexCand. setCandidato(candidato int,indexCand int):void Inserta el candidato candidato en la posicin indexCand del vector de candidatos. getOperacion(indexOp int):TPilaOperaciones Devuelve la operacin(pila) que se encuentra en la posicin indexOp. removeOperacion(indexOp int):void Elimina la pila de operaciones que se encuentra en indexOp. setOperacion(operacion TpilaOperaciones, indexOp int):void Inserta la pila de operaciones operacin en la posicin indexOp del vector de operaciones. setSolucion(solucion boolean):void Marca el ensayo como solucin vlida. isSolucion():boolean Devuelve un boolean que indica si el ensayo es o no solucin. isVacio():bolean Devuelve un bolean que indica si el ensayo es o no vacio. setVacio(vacio boolean)void Marca el ensayo como vacio.

Tipo TpilaOperaciones= pila: pila de String Operaciones Asociadas --------------------pushNumber(value int):void Aade un nmero a la pila. La lgica de la operacin transforma el entero de entrada en una cadena de caracteres para poder insertarlo en la pila. pushOperator(oper char):void Aade un operador a la pila. La lgica de la operacin transforma el entero de entrada en una cadena de caracteres para poder insertarlo en la pila.

El principal problema del ejercicio se encuentra en determinar cmo vamos a ir construyendo el grafo implcito y cmo vamos a representar las operaciones que ya han sido llevadas a cabo. Para ello vamos a tener en cuenta lo siguiente: 1. Nuestro algoritmo siempre va a trabajar sobre un conjunto de candidatos que recoger inicialmente los valores asociados y, posteriormente, los valores obtenidos al ir realizando cada una de las operaciones. Esta es la funcin del elemento candidatos de Tensayo. 2. Para poder recordar qu operaciones se han llevado a cabo y mostrrselas al usuario al fin del algoritmo, es necesario desplegar un almacn de informacin paralelo a candidatos que, para cada uno de los candidatos recoja las operaciones que ste ha soportado hasta el momento. Con este fin se crea el elemento operaciones, que no es ms que un vector donde cada elemento representa una pila de operaciones y operandos que, en notacin postfija, representan el historial de operaciones de dicho elemento. 3. Finalmente, el elemento solucin marca el ensayo como solucin o no, dependiendo si alberga la solucin al problema. Veamos con un ejemplo el funcionamiento de esta estructura de datos. Supongamos que nuestro conjunto inicial es N={1, 2, 3, 4}. El ensayo correspondiente a esta situacin inicial vendra descrito por:
Tipo Tensayo= candidatos: vector de int operaciones: vector de TpilaOperaciones solucion: bolean ENSAYO -----candidatos:<1,2,3,4> 1 2 3 4

operaciones

<

>

solucion: false

Supongamos ahora que operamos el candidato 2 y el candidato 4 con el operador +. El nuevo formato del ensayo sera el siguiente:
ENSAYO -----candidatos:<1,6,3> 2 4 1 operaciones < solucion: false vacio: false + 3 >

Ntese que: 1. Desaparece el elemento que ocupa la posicin 3 del vector y su pila asociada. 2. El vector de candidatos ahora almacena el valor 6 all donde se ha realizado la operacin. 3. El vector de operaciones ha actualizado la pila de operaciones, reflejando la nueva situacin en notacin postfija (2,4,+)

Supongamos que ahora operamos el candidato 6 con el candidato 3 utilizando el operador -. El nuevo ensayo quedara:
ENSAYO -----candidatos:<1,3>

2 4 + 3 1 operaciones < solucion: false vacio: false >

Finalmente si operamos el candidato 1 con el candidato 3 utilizando el operador *. El ensayo obtenido sera:
ENSAYO -----candidatos:<3>

2 4 + 3 1 *

operaciones

<

>

solucion: false vacio: false

Como podemos observar, el valor final obtenido combinando todos los valores iniciales, y de acuerdo a las operaciones descritas, sera 3 y el historial completo de todas las operaciones realizadas podra mostrarse deshaciendo la pila en formato postfijo generada (2,4,+,3,-,1,*).

Algoritmo Completo.
fun vuelta-atrs(e: Tensayo):Tensayo si valido(e) entonces solucion e solucion.setSolucion(true); dev solucion sino listaensayos complecciones(e) mientras vacia(listaensayos) solucion.isSolucion() hacer hijo primero(listaensayos) listaensayos resto(listaensayos) si podar(hijo) entonces solucion vuelta-atrs(hijo) sino solucion mejor(e) fsi fmientras dev solucion fsi ffun

Ntese que solucin es un ensayo, que inicialmente es vaco, y que contendr la solucin en caso de existir o la serie de operaciones que ms se aproximen en caso de que esto no ocurra. Solucin se define externamente a la funcin vuelta-atrs y, por eso, puede manipularse desde cualquiera de las funciones sin ser necesario enviarla a stas como parmetro. Igualmente, la el valor objetivo P, tambin es utilizado globalmente por la funcin vuelta atrs. Las funciones asociadas al algoritmo son las siguientes:
valido(e Tensayo):boolean Funcin que devuelve true si el ensayo que recibe como parmetro es solucin al problema, es decir, si contiene algn candidato cuyo valor sea P. Devuelve false en caso contrario. complecciones(e Tensayo):lista Funcin que devuelve la lista de hijos correspondientes a un ensayo concreto. La poltica de generacin de hijos que seguiremos ser la siguiente: Para cada candidato, complecciones genera todas las combinaciones posibles de ste con cada uno de los dems, haciendo uso del conjunto de operaciones posibles. podar(e Tensayo):bolean Funcin que devuelve un boolean dependiendo si es posible continuar explorando por el ensayo e que recibe como parmetro o no. La nica condicin de poda que impondremos ser que alguno de los candidatos calculados hasta el momento sobrepase el valor de P. mejor(e Tensayo):Tensayo Funcin que compara el ensayo e, que recibe como parmetro, con la solucin calculada hasta el momento. Devuelve a la salida aquel ensayo que contenga el candidato ms prximo a la solucin solicitada. fun valido(e: Tensayo):boolean para c desde 0 hasta numCandidatos hacer candidato e.getCandidato(c) si candidato = P entonces dev true fsi fpara dev false ffun fun podar(e: Tensayo):boolean para c desde 0 hasta numCandidatos hacer candidato e.getCandidato(c) si candidato > P entonces dev true fsi fpara dev false ffun

fun mejor(e: Tensayo):Tensayo v1 valorMax(e) v2 valorMax(solucion) si v1<v2 entonces dev solucion sino dev e fsi ffun fun valorMax(e: Tensayo):int value e.getCandidato(0) para cada c desde 1 hasta numCandidatos hacer valAux e.getCandidato(c) si (valAux>value) (valAux<=P) entonces value=valAux fsi fpara dev value ffun

fun complecciones(e: Tensayo):vector para c1 desde 0 hasta numCandidatos hacer para c2 desde c1+1 hasta numCandidatos hacer hijo=obtieneHijo(e,+,c1,c2) si (hijo.isVacio()) entonces vHijos.addElement(hijo) fsi hijo=obtieneHijo(e,-,c1,c2) si (hijo.isVacio()) entonces vHijos.addElement(hijo) fsi hijo=obtieneHijo(e,*,c1,c2) si (hijo.isVacio()) entonces vHijos.addElement(hijo) fsi hijo=obtieneHijo(e,/,c1,c2) si (hijo.isVacio()) entonces vHijos.addElement(hijo) fsi fpara fpara dev vHijos ffun

fun obtieneHijo(e: Tensayo, char operator, int c1Index, int c2Index):Tensayo c1 e.getCandidato(c1Index) c2 e.getCandidato(c2Index) nuevoEnsayo e si (operator=+) entonces res c1+c2 sino si (operator=-) entonces res c1-c2 sino si (operator=*) entonces res c1*c2 sino si (operator=/) entonces si (c2!=0) (c1%c2=0) entonces res c1/c2 sino res -1 fsi fsi fsi fsi fsi si (res >=0) entonces nuevoEnsayo e pila1=e.getOperacion(c1) pila2=e.getOperacion(c2) pila=generaNuevaPila(pila1,pila2,operator) nuevoEnsayo.removeCandidato(c2) nuevoEnsayo.setCandidato(res,c1) nuevoEnsayo.removeOperacion(c2) nuevoEnsayo.setOperacion(pila,c1) dev nuevoEnsayo sino dev ensayoVacio fsi ffun

Ntese como la funcion generaNuevaPila recibe como parmetros las dos pilas ya existentes (pertenecientes a cada uno de los candidatos), as como el operador que va a ser utilizado para combinar ambos candidatos y genera como resultado la nueva pila correspondiente al candidato generado.

Programacin III
Solucin

Prueba Presencial Segunda Semana Enero - Febrero de 2005

UNIVERSIDAD NACIONAL DE EDUCACIN A DISTANCIA

Duracin: 2 horas Material permitido: NINGUNO

Cuestin 1 (2 puntos). Demuestra cul es el orden exacto de complejidad en funcin de la variable n, del siguiente programa: 1 2 3 4 5 6 7 8 9 procedimiento lona (n: entero, j: entero) para i desde 1 hasta n div 4 hacer j:=j+i; fpara si n>1 entonces lona(n-2,j); escribir j; lona(n-2,n-j); fsi

Planteamos una recurrencia con reduccin del problema mediante sustraccin n: tamao del problemas a: nmero de llamadas recursivas b: reduccin del problema en cada llamada recursiva n-b: tamao del subproblema nk: coste de las instrucciones que no son llamadas recursivas Recurrencia: cnk T(n)= aT(n-b)+cnk (nk) (nk+1) (an div b) si a<1 si a=1 si a>1 si nb si 0n<b

T(n) a=2; b=2; nk=n; k=1

Por tanto, T(n) (2n div 2) Nota: (2n div 2) no es equivalente a (2n), puesto que se le est aplicando la raz cuadrada y no el producto de una constante.

La resolucin del problema debe incluir, por este orden: 1. Eleccin razonada del esquema algortmico 2. Descripcin del esquema usado e identificacin con el problema 3. Estructuras de datos 4. Algoritmo completo a partir del refinamiento del esquema general 5. Estudio del coste

Cuestin 2 (1 punto). En qu se diferencia una bsqueda ciega en profundidad y un esquema de vuelta atrs? Pon un ejemplo. El esquema de vuelta atrs es una bsqueda en profundidad pero en la que se articula un mecanismo para detener la bsqueda en una determinada rama (poda). Para alcanzar una solucin final es necesario que los pasos intermedios sean soluciones parciales al problema. Si un determinado nodo no es una solucin parcial, entonces la solucin final no se puede alcanzar a partir de dicho nodo y la rama se poda. Esto se implementa en el esquema de vuelta atrs mediante la funcin condiciones_de_poda o funcin de factibilidad. El problema de colocar N reinas en un tablero de NxN sin que se amenacen entre s es un problema que se puede resolver mediante vuelta atrs, puesto que en cada nivel de la bsqueda se establece un problema parcial: en el nivel i se trata de colocar i reinas en un tablero de NxN sin que se amenacen entre s. Si un nodo no cumple esta condicin, por muchas ms reinas que se coloquen a continuacin nunca se va a encontrar una solucin final.

Cuestin 3 (2 puntos). Demuestra por induccin que el algoritmo de Dijkstra halla los caminos mnimos desde un nico origen hasta todos los dems nodos del grafo. (Solucin en el libro de texto, Brassard, pg. 225).

Problema (5 puntos). Utiliza el esquema de divide y vencers para implementar una funcin que tome un vector de enteros y le d estructura de montculo con el menor coste posible. 1. Eleccin del esquema (0 puntos) No es necesario razonar la eleccin del esquema puesto que viene impuesto en el problema.

2. Esquema general (0.5 puntos) 1. Descomponer el ejemplar en subejemplares del mismo tipo que el ejemplar original 2. Resolver independientemente cada subejemplar (subproblema) 3. Combinar los resultados para construir la solucin del ejemplar original Funcin DivideVencers(X) si suficiente_pequeo(X) entonces dev subalgoritmo_bsico(X) si no Descomponer(X, X1..Xn) para i=1 hasta n hacer Yi:=DivideVencers(Xi); fpara Recombinar(Y1..Yn, Y) dev Y fsi

3. Estructuras de datos (0 puntos) No se necesita ninguna estructura adicional a parte del vector de entrada. 4. Algoritmo completo (3 puntos) Como se trata de un rbol binario, descomponemos el problema en los dos subrboles bajo el nodo i, es decir, el que tiene por raz 2i y el que tiene por raiz 2i+1. Cada subrbol a su vez debe tener estructura de montculo lo que resulta un problema del mismo tipo que el original y, por tanto, corresponde a sendas llamadas recursivas, una para 2i y otra para 2i+1. Por ltimo, hay que colocar la raz i en su lugar. Para ello, hay que hundirla. Procedimiento crear_montculo(i, M[1..m]) si 2i<m entonces crear_montculo(2i, M) fsi si (2i+1)<m entonces crear_montculo(2i+1, M) fsi si (2im) entonces hundir(M, i) fsi M[8] 2 M[4] 4 M[5] M[9] 1 6 M[10] 7 5 M[6] M[7] 2 M[2] 7 M[3] 9 M[1]

La llamada inicial ser: crear_montculo(1,M). Como puede observarse, dividir el vector en dos mitades M[1..m/2], M[(m/2)+1..m] y tratar de resolver cada una de ellas supone un error. Una solucin que recorra completamente el vector y proceda a hundir o flotar cada elemento siempre tendr mayor coste. Ya que estamos en un esquema divide y vencers, podemos plantear el procedimiento hundir como un problema de reduccin. nicamente se tiene que decidir si el nodo debe intercambiarse por alguno de sus hijos, y en caso afirmativo intercambiarse con el mayor de ellos y realizar la correspondiente llamada recursiva para seguir hundindose. Procedimiento hundir(T[1..n], i) hmayor:=i si (2i n) y (T[2i] > T[hmayor]) entonces hmayor=2i

fsi si (2i < n) y (T[2i+1] > T[hmayor]) entonces hmayor=2i+1 fsi si (hmayor > i) entonces intercambiar(T[i], T[hmayor]) hundir(T[1..n], hmayor) fsi 5. Estudio del coste (1.5 puntos) El coste del procedimiento hundir se puede plantear mediante una recurrencia con reduccin del problema por divisin, ya que hundir prosigue por uno de los dos subrboles y, por tanto, el problema se ha reducido a la mitad. cnk T(n)= aT(n/b)+cnk (nk) (nk log n) (nlogb a) si nb si a<bk si a=bk si a>bk si 0n<b

T(n)

a=1; b=2; cnk=c, k=0; a=bk luego T(n)(log n) El coste de crear_montculo puede expresarse, entonces mediante la siguiente recurrencia: T(n)=2T(n/2)+log n Sin embargo, esta recurrencia no se puede resolver con la frmula anterior puesto que la parte no recursiva no tiene una complejidad polinomial. Para resolverlo, vamos a utilizar un cambio de variable: Sea h la altura del montculo de n nodos: h=log2 n. En cada llamada recursiva bajamos un nivel por lo que el problema se puede expresar mediante una recurrencia con reduccin del problema por sustraccin. Es decir, si en cada paso se baja un nivel, el problema se reduce en uno. cnk T(n)= aT(n-b)+cnk (nk) (nk+1) (an div b) si a<1 si a=1 si a>1 si nb si 0n<b

T(n)

En el caso de hundir T(h)=T(h-1)+c, con a=1 y b=1, luego T(h)(h), que deshaciendo el cambio de variable lleva a un tiempo en funcin de n: T(n)(log n) como habamos demostrado antes. Sin embargo, ahora ya podemos plantear la recurrencia para crear_montculo: T(h)=2T(h-1)+h, donde a=2 y b=1 y, por tanto, T(h)(2h). Deshaciendo el cambio de variable: 2h=2log2 n=n, y T(n)(n), que es el menor coste posible para dar estructura de montculo a un vector. NOTA: cualquier solucin que tenga mayor coste no ser puntuada.

Programacin III
Solucin

Prueba Presencial Original Septiembre de 2005

UNIVERSIDAD NACIONAL DE EDUCACIN A DISTANCIA

Prueba Presencial

Duracin: 2 horas Material permitido: NINGUNO

Cuestin 1 (2 puntos). Suponga que N personas numeradas de 1 a N deben elegir por votacin a una entre ellas. Sea V un vector en el que la componente V[i] contiene el nmero del candidato que ha elegido el votante i. Qu algoritmo utilizaras para determinar con un coste lineal si una persona ha obtenido ms de la mitad de los votos? Podra utilizarse una estrategia similar a la que emplea para ordenacin el algoritmo de la casilla (pgina 80 del libro), pero trasladado al conteo de elementos. La siguiente funcin almacena en el vector votos el nmero de votos que va sumando cada candidato votado. Devuelve un valor TRUE si hay alguno con mayora indicando de qu candidato se trata: funcin contar_votos(V[1..N) dev (booleano, elegido) votos[1..N]=0; para i=1 hasta N hacer votos[V[i]]=votos[V[i]]+1; si votos[V[i]]>N/2 entonces devolver (TRUE,V[i]) fsi; fpara devolver (FALSE,0); Cuestin 2 (1 punto). En el contexto de elegir un esquema algortmico para resolver un problema de optimizacin con restricciones, cundo se puede resolver mediante un esquema voraz y en qu casos sera necesario utilizar un esquema de ramificacin y poda? Para resolverlo con un esquema voraz es necesario que exista una funcin de seleccin de candidatos y una funcin de factibilidad que decida si se acepta o rechaza el candidato, de manera que la decisin es irreversible. Si no es posible encontrar las funciones de seleccin y de factibilidad de manera que se garantice que la eleccin de un candidato lleva a la solucin ptima, entonces optaramos por otro esquema como el de ramificacin y poda. Cuestin 3 (2 puntos). Sea T(n)=4n2-3n+2 el tiempo de ejecucin de un algoritmo. Demuestra si es cierta o falsa cada una de las siguientes afirmaciones (0.5 puntos cada una): Recordamos la regla del lmite:

c entonces f (n) lm = 0 entonces n g ( n ) + entonces


a) T(n) O(n2 ln n)

f ( n ) ( g ( n )) f ( n ) O ( g ( n )), f ( n ) ( g ( n )) f ( n ) ( g ( n )), f ( n ) ( g ( n ))

4n 2 3n + 2 8n 3 8 = lm = =0 2 n n 2n ln n + n 2 ln n + 3 n ln n lm
Luego pertenece al orden indicado y la cuestin a) es FALSA b) T(n) O(n3)

lm

4n 2 3n + 2 8n 3 8 = lm = =0 3 n n 3n 2 6n n

Por lo que T(n) pertenece a O(n3 ) y la cuestin b) es FALSA c) T(n) (n log n)

4n 2 3n + 2 8n 3 8 lm = lm = = + n n ln n + 1 1 n ln n n
con lo que c) es CIERTO

d) T(n) O(n2)

4n 2 3n + 2 8n 3 8 = lm = = 4 + 2 n n 2n 2 n lm
En este caso, al ser T(n) (n2) se cumple tambin que T(n) O (n2) luego d) es CIERTO Problema (5 puntos). Sea V[1..N] un vector con la votacin de unas elecciones. La componente V[i] contiene el nombre del candidato que ha elegido el votante i. Implementa un programa cuya funcin principal siga el esquema divide y vencers, que decida si algn candidato aparece en ms de la mitad de las componentes (tiene mayora absoluta) y que devuelva su nombre. Sirva como ayuda que para que un candidato tenga mayora absoluta considerando todo el vector (al menos N/2+1 de los N votos), es condicin necesaria pero no suficiente que tenga mayora absoluta en alguna de las mitades del vector. La resolucin del problema debe incluir, por este orden: 1. Descripcin del esquema divide y vencers y su aplicacin al problema (0.5 puntos). El esquema general Divide y Vencers consiste en: 1. Descomponer el ejemplar en subejemplares del mismo tipo que el original 2. Resolver independientemente cada subejemplar 3. Combinar los resultados para construir la solucin del ejemplar original Ms formalmente: Funcin DivideVencers(X) dev Y si suficiente_pequeo(X) entonces dev subalgoritmo_bsico(X) si no (X1..Xn)=Descomponer(X); para i=1 hasta n hacer Yi:=DivideVencers(Xi); fpara Y=Recombinar(Y1..Yn); dev Y; fsi

2. Algoritmo completo a partir del refinamiento del esquema general (3 puntos) funcin contar(V[1..N], i, j) dev (tiene_mayora, candidato, num_votos) si (i==j) entonces dev (TRUE, V[i], 1) si no /* Descomponer */ (tiene_mayora1, candidato1, num_votos1)=contar(V, i, (i+j)2); (tiene_mayora2, candidato2, num_votos2)=contar(V, (i+j)2+1, j); /* Recombinar */ si tiene_mayora1 entonces para k desde (i+j)2+1 hasta j hacer si es_igual(V[k], candidato1) entonces num_votos1=num_votos1+1; fsi fpara si (num_votos1>(j-i+1)/2) entonces devolver (cierto, candidato1, num_votos1); fsi fsi si tiene_mayora2 entonces para k desde i hasta (i+j)2 hacer si es_igual(V[k], candidato2) entonces num_votos2=num_votos2+1; fsi fpara si (num_votos2>(j-i+1)/2) entonces devolver (cierto, candidato2, num_votos2); fsi fsi devolver (falso,,0); fsi Llamada inicial contar(V,1,N);

3. Estudio del coste del algoritmo desarrollado (1.5 puntos) Planteamos la ecuacin de recurrencia T(n) = 2T(n2) + n2 + n2 = 2T(n2) + n La reduccin del problema se realiza mediante divisin, cuyos casos son los siguientes: (nk) T(n) = (nk log n) (nlogba) donde: n: tamao del problema a: nmero de llamadas recursivas n/b: tamao del subproblema nk: coste de las instrucciones que no son llamadas recursivas Aplicado a nuestro problema: cnk=n; k=1; b=2; a=2; bk=21=2 a=bk luego T(n) (n log n) si a<bk si a=bk si a>bk

Programacin III
Solucin

Prueba Presencial Primera Semana Enero - Febrero de 2006

UNIVERSIDAD NACIONAL DE EDUCACIN A DISTANCIA

Duracin: 2 horas Material permitido: NINGUNO

Cuestin 1 (2.5 puntos). En qu se diferencia una bsqueda ciega en profundidad y un esquema de vuelta atrs? (0.5 puntos) La bsqueda ciega explora todas las ramas alternativas mientras que en un esquema de vuelta atrs se establecen condiciones de poda que determinan si una rama puede alcanzar o no una solucin final. Si se determina que no es posible, entonces no se prosigue la bsqueda por dicha rama (se poda). Los problemas aptos para un esquema de vuelta atrs permiten expresar los nodos intermedios como soluciones parciales al problema. Aquellos nodos que no sean soluciones parciales no permiten alcanzar una solucin final y, por tanto, su rama se poda. Por ejemplo, el problema de poner N reinas en un tablero de NxN sin que se amenacen entre s, requiere ir solucionando la siguiente secuencia de soluciones parciales: poner 1 reina en un tablero de NxN sin que est amenazada (trivial) poner 2 reinas en un tablero de NxN sin que se amenacen entre s ... poner k reinas en un tablero de NxN sin que se amenacen entre s ... poner N reinas en un tablero de NxN sin que se amenacen entre s (solucin final) Si por una rama no se puede resolver el problema para k, entonces evidentemente no se podr resolver para N, por muchos intentos de aadir reinas hagamos. En el espacio de bsqueda, qu significa que un nodo sea k-prometedor? (1 punto) Significa que es solucin parcial para las k primeras componentes de la solucin y, por tanto, todava es posible encontrar una solucin final (incluyendo las N componentes). En el problema de las N reinas habramos colocado k reinas sin que se coman entre s. Que hay que hacer para decidir si un vector es k-prometedor sabiendo que es una extensin de un vector (k-1)-prometedor? (1 punto) Si es (k-1)-prometedor quiere decir que es solucin parcial para las primeras k-1 componentes y que, por tanto, estas cumplen las restricciones necesarias entre s y no hay que volver a verificarlas. Entonces, para decidir si una extensin considerando la siguiente componente k conforma un nodo k-prometedor, lo nico que hay que hacer es verificar si esta nueva componente k cumple las restricciones respecto a las otras k-1.

Cuestin 2 (1.5 puntos). Declara en Java o en Mdula-2 las clases y/o estructuras de datos que utilizaras en el problema del Sudoku (prctica de este ao) para comprobar en un tiempo de ejecucin constante respecto a la dimensin n del tablero (nxn) que una casilla contiene un valor factible. Existen varias alternativas, pero de nada sirve que verificar una casilla se realice en tiempo constante si luego actualizar su valor se realiza en tiempo lineal. En la siguiente solucin se declaran tres tablas de booleanos que indican si ya hay o no un determinado valor en una determinada fila, columna o regin, respectivamente. Si no es as, entonces es factible poner el valor en la casilla. Tanto la funcin de verificacin como las de actualizacin tienen un coste computacional constante.
public class Tablero { int N=9; int subN=(int)Math.sqrt(N); boolean val_en_fil[][] = new boolean[N][N]; boolean val_en_col[][] = new boolean[N][N]; boolean val_en_reg[][] = new boolean[N][N]; boolean valorFactible(int fil, int col, int val){ int reg=region(fil,col); return (!val_en_fil[fil][val] && !val_en_col[col][val] && !val_en_reg[reg][val]); } void poner(int fil, int col, int val) { int reg=region(fil,col); val_en_fil[fil][val]=true; val_en_col[col][val]=true; val_en_reg[reg][val]=true; } void quitar(int fil, int col, int val) { int reg=region(fil,col); val_en_fil[fil][val]=false; val_en_col[col][val]=false; val_en_reg[reg][val]=false; } int region(int fil, int col) { return (col/subN)*subN+fil/subN; // divisin entera } }

Cuestin 3 (2 puntos). Dado el siguiente grafo, rellena la tabla adjunta indicando paso a paso cmo el algoritmo de Dijkstra encuentra todos los caminos de menor coste desde el nodo 1.
4 5 1 1 3 2 11 5 6 1 3 2 Paso Nodos Nodos No Vector de Seleccionados Seleccionados distancias 2 3 4 Vector de predecesores 2 3 4 5

0 1 2 3

{1} {1,2} {1,2,4} {1,2,3,4}

{2,3,4,5} {3,4,5} {3,4} {5}

3 3 3 3

9 6 6

5 4 4 4

1 2 4 4

1 2 2 2

1 2 2 3

14 1 14 1 7 1

Problema (4 puntos). Una empresa de montajes tiene n montadores con distintos rendimientos segn el tipo de trabajo. Se trata de asignar los prximos n encargos, uno a cada montador, minimizando el coste total de todos los montajes. Para ello se conoce de antemano la tabla de costes C[1..n,1..n] en la que el valor cij corresponde al coste de que el montador i realice el montaje j. Se pide: 1. Determinar qu esquema algortmico es el ms apropiado para resolver el problema. Razonar la respuesta. (0.5 puntos) Se trata de un problema de optimizacin con restricciones. Por tanto, podra ser un esquema voraz o un esquema de ramificacin y poda. Sin embargo descartamos el esquema voraz porque no es posible encontrar una funcin de seleccin y de factibilidad tales que una vez aceptado un candidato se garantice que se va alcanzar la solucin ptima. Se trata, por tanto, de un algoritmo de ramificacin y poda. 2. Escribir el esquema general (0.5 puntos)
Funcin RamificacinPoda (nodo_raz) dev nodo Montculo:=montculoVaco(); cota:=acotar(nodo_raz); poner((cota,nodo_raz), Montculo); mientras no vaco(Montculo) hacer (cota, nodo):=quitarPrimero(Montculo); si solucin(nodo) entonces devolver nodo; si no para cada hijo en compleciones(nodo) hacer cota:=acotar(hijo); poner((cota,hijo),Montculo); fpara; fsi; fmientras devolver

3. Indicar que estructuras de datos son necesarias (0.5 puntos) nodo=tupla asignaciones: vector[1..N]; ltimo_asignado: cardinal; filas_no_asignadas: lista de cardinal; coste: cardinal; Montculo de mnimos (cota mejor la de menor coste)

4. Desarrollar el algoritmo completo (2.5 puntos) Las funciones generales del esquema general que hay que instanciar son: a. solucin(nodo): si se han realizado N asignaciones (ltimo_asignado==N) b. acotar(nodo,costes): nodo.coste + mnimo coste de las columnas no asignadas c. compleciones(nodo,costes): posibilidades para la siguiente asignacin (valores posibles para asignaciones[ltimo_asignado+1])
Funcin asignacin(costes[1..N,1..N]) dev solucin[1..N] Montculo:=montculoVaco(); nodo.ltimo_asignado=0; nodo.coste=0; cota:=acotar(nodo,costes); poner((cota,nodo),Montculo); mientras no vaco(Montculo) hacer (cota,nodo):=quitarPrimero(Montculo); si nodo.ltimo_asignado==N entonces devolver nodo.asignaciones; si no para cada hijo en compleciones(nodo,costes) hacer cota:=acotar(hijo,costes); poner((cota,hijo),Montculo); fsi; fmientras devolver ; Funcin acotar(nodo,costes[1..N,1..N]) dev cota cota:=nodo.coste; para columna desde nodo.ltimo_asignado+1 hasta N hacer mnimo=; para cada fila en nodo.filas_no_asignadas hacer si costes[columna,fila]<mnimo entonces mnimo:=costes[columna,fila]; fsi fpara cota:=cota+mnimo; fpara devolver cota; Funcin compleciones(nodo,costes[1..N,1..N]) dev lista_nodos lista:=crearLista(); para cada fila en nodo.filas_no_asignadas hacer hijo:=crearNodo(); hijo.ltimo_asignado:=nodo.ltimo_asignado+1; hijo.asignaciones=nodo.asignaciones; hijo.asignaciones[hijo.ltimo_asignado]:=fila; hijo.coste:=nodo.coste+costes[hijo.ltimo_asignado,fila]; hijo.filas_no_asignadas:=nodo.filas_no_asignadas; eliminar(fila,hijo.filas_no_asignadas); aadir(hijo,lista); fpara; devolver lista;

Programacin III
Solucin

Prueba Presencial Original Febrero de 2006 - 2

UNIVERSIDAD NACIONAL DE EDUCACIN A DISTANCIA

Prueba Presencial

Duracin: 2 horas Material permitido: NINGUNO

Cuestin 1 (1 puntos). En la prctica obligatoria del presente curso 2005/2006 se ha tenido que disear y desarrollar un algoritmo para resolver el juego del Su-doku. Codifique en java o en modula-2 un algoritmo iterativo que recorra el cuadrado de 3x3 casillas que corresponda a una casilla que ocupa las posiciones i,j del tablero. Solucin: Se trataba de encontrar la relacin entre las posiciones i,j del tablero y las posiciones de comienzo del cuadrado de 3x3 que les corresponde en el tablero del Su-doku 9x9. Supongamos que el tablero tiene como ndices 0..8, 0..8 y que i y j son de tipo entero, la relacin se puede establecer de la siguiente manera:
int coordFilaInicioCuadrado = (i / 3) * 3; // divisin entera int coordColumnaInicioCuadrado = (j / 3) * 3; // divisin entera

ahora slo queda hacer el recorrido:


for (int k= coordFilaInicioCuadrado; k < coordFilaInicioCuadrado+3; k++){ for (int l= coordColumnaInicioCuadrado; l < coordColumnaInicioCuadrado+3; l++){ procesar(tab[k][l]); } }

Cuestin 2 (2 puntos). Sea el famoso problema de la mochila. Se dispone de n objetos y una mochila. Para i= 1,2,,n, el objeto i tiene un peso positivo wi y un valor positivo vi. La mochila puede llevar un peso que no sobrepase W. El objetivo es llenar la mochila de tal manera que se maximice el valor de los objetos almacenados, respetando la limitacin de peso impuesta. Indique qu esquema o esquemas considera ms adecuados para resolver este problema en los siguientes casos: a) Los objetos se pueden fraccionar, luego se puede decidir llevar una fraccin xi del objeto i, tal que 0 xi 1 para 1 i n. b) Los objetos no se pueden fraccionar, por lo que un objeto puede o no ser aadido, pero en ste ltimo caso, slo se aade 1. Adems de nombrar el esquema o esquemas, explica el porqu de su eleccin, los aspectos destacados de cmo resolveras el problema y el coste asociado. No se piden los algoritmos. Solucin: En el caso a) se puede utilizar el esquema voraz ya que existe una funcin de seleccin que garantiza obtener una solucin ptima. La funcin de seleccin consiste en considerar los

objetos en orden decreciente de vi/wi. El coste est en O(n log n), incluyendo la ordenacin de los objetos. Ver pgina 227 del libro base de la asignatura. En el caso b) no se puede utilizar el esquema voraz ya que no existe una funcin de seleccin que garantice obtener una solucin ptima. Al ser un problema de optimizacin se puede utilizar el esquema de ramificacin y poda. Se podran seleccionar los elementos en orden decreciente de vi/wi. As, dado un determinado nodo, una cota superior del valor que se puede alcanzar siguiendo por esa rama se puede calcular suponiendo que la mochila la rellenamos con el siguiente elemento siguiendo el orden decreciente de vi/wi. El coste en el caso peor sera de orden exponencial, ya que en el rbol asociado al espacio de bsqueda, cada nodo tendr dos sucesores que representarn si el objeto se aade o no a la mochila, es decir, O(2n). Sin embargo, sera de esperar que, en la prctica, el uso de la cota para podar reduzca el nmero de nodos que se exploran. Cuestin 3 (3 puntos). Un dentista pretende dar servicio a n pacientes y conoce el tiempo requerido por cada uno de ellos, siendo ti , i= 1,2,,n el tiempo requerido por el paciente i. El objetivo es minimizar el tiempo total que todos los clientes estn en el sistema, y como el n de pacientes es fijo, minimizar la espera total equivale a minimizar la espera media. Se pide: 1. Identificar una funcin de seleccin que garantice que un algoritmo voraz puede construir una planificacin ptima. (0.5 puntos) 2. Hacer una demostracin de la optimalidad de dicha funcin de seleccin. (2.5 puntos) Solucin: los dos apartados estn solucionados en el libro base de la asignatura, apartado 6.6.1, pgina 231.

Problema (4 puntos). Dos socios que conforman una sociedad comercial deciden disolverla. Cada uno de los n activos que hay que repartir tiene un valor entero positivo. Los socios quieren repartir dichos activos a medias y, para ello, primero quieren comprobar si el conjunto de activos se puede dividir en dos subconjuntos disjuntos, de forma que cada uno de ellos tenga el mismo valor. La resolucin de este problema debe incluir, por este orden: 1. Eleccin del esquema ms apropiado y explicacin de su aplicacin al problema (1 puntos). 2. Descripcin de las estructuras de datos necesarias (0.5 puntos). 3. Algoritmo completo a partir del refinamiento del esquema general (2 puntos). 4. Estudio del coste del algoritmo desarrollado (0.5 puntos). Solucin 1. No se puede encontrar una funcin de seleccin que garantice, sin tener que reconsiderar decisiones, una eleccin de los activos que cumpla con la restriccin del enunciado, por ello no se puede aplicar el esquema voraz. Tampoco se puede dividir el problema en subproblemas que al combinarlos nos lleven a una solucin. Al no ser un problema de optimizacin, el esquema de exploracin de grafos ms adecuado es el esquema vuelta-atrs. Vuelta atrs es un recorrido en profundidad de un grafo dirigido implcito. En l una solucin puede expresarse como una n-tupla [x1, x2, x3, xn], donde cada xi, representa una decisin tomada en la etapa i-sima, de entre un conjunto finito de alternativas.

Descripcin algortmica del esquema:


funcin vuelta-atrs(e: ensayo) si valido(e) entonces dev e sino listaEnsayos complecciones(e) mientras vacia(listaEnsayos) resultado hacer hijo primero(listaEnsayos) listaEnsayos resto(listaEnsayos) si condicionesDePoda(hijo) entonces resultado vuelta-atrs(hijo) fsi fmientras dev resultado fsi ffuncin

Otra posible descripcin:


funcin vuelta-atrs(v[1..k]: nTupla) si solucion(v) entonces dev v sino Para cada vector w k+1-prometedor hacer si condicionesDePoda(w) entonces vuelta-atrs(w[1..k+1]) fsi fpara fsi ffuncin

En este caso, el espacio de bsqueda es un rbol de grado 2 y altura n+1. Cada nodo del i-simo nivel tiene dos hijos correspondientes a si el i-simo activo va a un socio o al otro. Para poder dividir el conjunto de activos en dos subconjuntos disjuntos, de forma que cada uno de ellos tenga el mismo valor, su valor debe ser par. As, si el conjunto inicial de activos no tiene un valor par el problema no tiene solucin.

2. Descripcin de las estructuras de datos necesarias. El conjunto de activos y sus valores se representa en un array de enteros v= [v1, v2, v3, vn], donde cada vi representa el valor del activo i-simo. La solucin se representa mediante una array de valores x= [x1, x2, x3, xn], donde cada xi, podr tomar el valor 1 o 2 en funcin de que el activo i-simo se asigne al subconjunto del un socio o del otro. Un array de dos elementos, suma, que acumule la suma de los activos de cada subconjunto.

3. Algoritmo completo a partir del refinamiento del esquema general. En esta solucin se sigue el segundo de los esquemas planteados en el apartado 2. Una posible condicin de poda consistir en que se dejarn de explorar aquellos nodos que verifiquen que alguno de los dos subconjuntos que se van construyendo tiene un valor mayor que la mitad del valor total.
funcin Solucion (k: entero; suma: array[1..2]) dev booleano

si (k = n) AND (suma[1] = suma [2]) entonces dev Verdadero sino dev Falso fsi ffuncion

funcin SeparacionSociosMitad (v: array[1..n], k: entero, suma: array[1..2], sumaTotal: entero) dev x: array[1..n]; separacion: boolean si Solucion (k, suma) entonces dev x, Verdadero sino para i desde 1 hasta 2 hacer x[k] i suma[i] suma[i] + v[k] si suma[i] <= (sumaTotal DIV 2) entonces si k < n entonces x SeparacionSociosMitad(v, k+1, suma, sumaTotal) fsi sino suma[i] suma[i] - v[k] fsi fpara fsi ffuncin funcin ProblemaSeparacionSociosMitad (v: n-tupla) dev x: n-tupla; separacion: boolean para i desde 1 hasta n hacer sumaTotal sumaTotal + v[i] fpara si par(sumTotal) entonces dev SeparacionSociosMitad (v, 1, suma[0,0], sumaTotal) sino dev 0 fsi ffuncion

Llamada inicial ProblemaSeparacionSociosMitad (v); 4. Estudio del coste del algoritmo desarrollado. En este caso, el coste viene dado por el nmero mximo de nodos del espacio de bsqueda, esto es: T(n) O(2n)

Programacin III
Cdigo de asignatura (marcar con una X): Sistemas: __ 402048 (plan viejo) __ 532044 (plan nuevo) Gestin: __ 41204- (plan viejo) __ 542046 (plan nuevo)

Prueba Presencial Ordinario Septiembre de 2006

UNIVERSIDAD NACIONAL DE EDUCACIN A DISTANCIA

Duracin: 2 horas Material permitido: NINGUNO


DNI: _______________________

Apellidos: ___________________________________________________________________________________

Nombre: ______________________________ Centro donde entreg la prctica: ____________________ e-mail: ___________________

Cuestin 1 (2 puntos). Demuestra que el tiempo de ejecucin en funcin de n del siguiente fragmento de cdigo est acotado superiormente por O(n2) e inferiormente por (n) (1.5 puntos). Demuestra tambin su orden exacto de complejidad (0.5 puntos). para i desde 1 hasta n hacer para j desde 1 hasta n div i hacer escribir i,j,k; fpara fpara Supn que el coste de escribir es constante. Solucin: En primer lugar debemos plantear el tiempo de ejecucin T(n) en funcin de n. Para ello, vamos a fijarnos en la instruccin barmetro (la instruccin que se ejecuta ms veces) y vamos a contar cuntas veces se ejecuta. Puesto que todas las instrucciones tienen un coste constante, la complejidad del programa estar en el orden del nmero de veces que se ejecute la instruccin barmetro.

T ( n ) = 1 =
i =1 j =1 i =1
n

n /i

n n 1 = n i i =1 i

1 i es un sumatorio de n elementos menores o iguales que 1, por lo que su suma total ser i =1
menor que n. Por tanto, T(n) nn, o en otras palabras, T(n) est acotado superiormente por n2: T(n)O(n2) como queramos demostrar.

Por otra parte,

i
i =1

es mayor que 1 y, por tanto T(n) n1, o en otras palabras, T(n) est

acotado inferiormente por n: T(n)(n) como queramos demostrar.

Para demostrar el orden exacto es necesario saber cmo crece la serie podemos aproximar la serie con la integral:

i
i =1

1
. Para ello,

1 x dx que corresponde al logaritmo natural de n. Por tanto, la serie crece tan rpidamente 1
como el ln(n). As pues, se pueden encontrar dos constantes c y d tal que T(n) est acotado superiormente por cnlog(n) e inferiormente por dnlog(n). En conclusin, el orden exacto de T(n) es nlog(n): T(n)(n log n)

Cuestin 2 (2 puntos). Escribe la salida al realizar la llamada pinta(5), dado el siguiente cdigo (1.5 puntos): funcin pinta(int n) si n>0 entonces escribir n; pinta(n-1); escribir n-1; fsi Demuestra el coste computacional de la funcin pinta suponiendo que escribir tiene coste constante (0.5 puntos). Solucin: La salida sera: 5 4 3 2 1 0 1 2 3 4 Para calcular el coste planteamos una recurrencia con reduccin del problema mediante sustraccin: n: tamao del problemas a: nmero de llamadas recursivas b: reduccin del problema en cada llamada recursiva n-b: tamao del subproblema nk: coste de las instrucciones que no son llamadas recursivas Recurrencia: cnk T(n)= aT(n-b)+cnk (nk) (nk+1) (an div b) si a<1 si a=1 si a>1 si nb si 0n<b

T(n)

a=1; b=1; nk=1; k=0 Por tanto, T(n) (n)

Cuestin 3 (2 puntos). Dibuja cmo evolucionara el siguiente vector al ordenarlo mediante el algoritmo de ordenacin rpida (Quicksort). Indica nicamente cada una de las modificaciones que sufrira el vector. 6 5 1 2 3 4 7 8 9 Solucin: Si se toma como pivote el primer elemento:

6 4 4 2 2 1

5 5 3 3 1 2

1 1 1 1 3 3

2 2 2 4 4 4

3 3 5 5 5 5

4 6 6 6 6 6

7 7 7 7 7 7

8 8 8 8 8 8

9 9 9 9 9 9

Si se toma como pivote el elemento que ocupa la posicin central, en este caso el primer pivote es el elemento que ocupa la posicin quinta, que es el 3: 6 2 2 2 1 1 5 5 1 1 2 2 1 1 5 3 3 3 2 6 6 6 6 4 3 3 3 5 5 5 4 4 4 4 4 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9

Problema (4 puntos). Desarrollar un programa que compruebe si es posible que un caballo de ajedrez mediante una secuencia de sus movimientos permitidos recorra todas las casillas de un tablero NxN a partir de una determinada casilla dada como entrada y sin repetir ninguna casilla. Se pide: 1. Determinar qu esquema algortmico es el ms apropiado para resolver el problema. Razonar la respuesta y escribir el esquema general (0.5 puntos) 2. Indicar que estructuras de datos son necesarias (0.5 puntos) 3. Desarrollar el algoritmo completo en el lenguaje de programacin que utilizaste para la prctica (2.5 puntos) 4. Hallar el orden de complejidad del algoritmo desarrollado (0.5 puntos) Solucin:

Una solucin en pseudocdigo se puede encontrar en la pgina 86 del libro de problemas de la asignatura: Esquemas Algortmicos: Enfoque Metodolgico y Problemas Resueltos. Julio Gonzalo Arroyo y Miguel Rodrguez Artacho. Cuadernos de la UNED.

Você também pode gostar