Examen - Web del laboratorio del DIT

Anuncio
dit
UPM
Depto. Ingeniería de Sistemas
Telemáticos
Universidad Politécnica de Madrid
ETSI Telecomunicación
Laboratorio de Programación
19 de Junio de 2002
Soluciones
EJERCICIO 1 (UNA PÁGINA: UNA HOJA POR UNA CARA)
Se desea añadir un iterador específico para la clase SerieGeometrica. Para ello, se define la clase
IteraSerieGeometrica, que implementa la interface Iterator. El método next() deberá calcular cada
elemento de la serie como el producto del valor anterior y la constante multiplicativa de la serie.
Conteste a los siguientes apartados:
1.1. Escriba la declaración de las variables de instancia necesarias en IteraSerieGeometrica.
1.2. Escriba el constructor de IteraSerieGeometrica que asigna los valores iniciales a las variables
de
instancia
del
apartado
anterior.
1.3. Escriba el método next().
1.4. Describa brevemente qué otras clases o interfaces modificaría, y cómo, para que el resultado
del siguiente método fuera true:
boolean pruebaIteraSerieGeometrica () {
Serie s= new SerieGeometrica (1, 2);
return (s.iterator() instanceof IteraSerieGeometrica);
}
1.1 int sig;
// valor siguiente de la serie geometrica
int factor;
// constante multiplicativa de la serie
geometrica
1.2 public IteraSerieGeometrica (int inicial, int _factor){
sig= inicial;
factor= _factor;
}
1.3 public Object next (){
Integer r= new Integer (sig); // valor que se va a
devolver
sig *= factor; // se deja listo sig para la próxima
vez
return r;
}
1.4 Se debe redefinir el método iterator en la clase SerieGeometrica, de manera que
devuelva un objeto de la nueva clase IteraSerieGeometrica. En SerieGeometrica.java se
debería incluir el siguiente método:
public Iterator iterator () {
return new IteraSerieGeometrica (s1, factor);
}
1
EJERCICIO 2 (DOS PÁGINAS: UNA HOJA POR AMBAS CARAS)
Queremos modificar el simulador de la bancada de modems para introducir la siguiente
funcionalidad:
Cada vez que la simulación detecte el rechazo de n llamadas seguidas el simulador
introducirá el estado actual de la lista de eventos en una estructura de datos con
disciplina de cola, vaciará la lista de eventos y seguirá la simulación.
2.1.
Diseñe la estructura de datos “cola de lista de eventos”
2.2.
Modifique ModemSim para que:
a. admita un nuevo parámetro n: número de llamadas rechazadas que disparan
la nueva funcionalidad
b. detecte el rechazo e introduzca la lista de eventos en la cola
c. imprima al final de la simulación la cola de listas de eventos, con el formato:
Log 1
Evento 1
Evento 2
...
Evento n
Log 2
Evento 1
Evento 2
...
Evento n
...
Log n
Evento 1
Evento 2
...
Evento n
2.1 Ver apuntes para diseño de una cola con nodos lista de eventos. Esta clase es
ColaListaEventos.
2.2
Añadir una constante en MiModemSim, número máximo de llamadas
consecutivas
static final int NUM_RECHAZOS = 3;
En runSim añadir una variable que cuente los rechazos seguidos y crear una cola
de
lista
de
eventos
int
rechazosSeguidos
=
0;
ColaListaEventos
colaListaEventos
=
new
ColaListaEventos();
Al comparar los modems libres, cuando se acepta una conexión, poner a cero
rechazosSeguidos (sólo se tienen en cuenta llamadas consecutivas). Si la llamada
se rechaza, incrementar rechazsosSeguidos y comprobar si llegamos a
NUM_RECHAZOS. Si llegamos, introducir el estado en ColaListaEventos,
vaciar la lista de eventos y reinciar rechazosSeguidos. Al final el método runSim
al salir del bucle while añadimos que se imprima la lista de eventos tras la
simulación.
2
if (freeModems > 0) {
freeModems--;
...
rechazosSeguidos = 0;
} else {
System.out.println(“pero recibe señal de ocupado”);
rechazosSeguidos++;
if (rechazosSeguidos >= NUM_RECHAZOS) {
colaListaEventos.add(eventSet);
eventSet.makeEmpty();
rechazosSeguidos = 0;
}
nextCall(freqOfCalls);
}
System.out.println(colaListaEventos.printListaEventos());
EJERCICIO 3 (DOS PÁGINAS: UNA HOJA POR AMBAS CARAS)
En la práctica del laboratorio se ha supuesto en todo momento que los nodos son capaces de gestionar
todo el flujo que haga falta, sin más limitación que la capacidad de los enlaces. Vamos a alterar este
supuesto: los nodos pueden tener un límite en el flujo que circula por ellos
flujo entrante = flujo saliente = F1 (ver nota al pie)
F≤L
Donde el límite L puede establecerse de forma independiente para cada nodo.
3.1. Indique cómo modificaría el fichero de datos para poder imponer un límite a algunos nodos
(no necesariamente a todos).
3.2. Indique qué pruebas debería desarrollar en FicheroDatosTest.java para probar esta
nueva información. No escriba las pruebas; sólo indique qué pruebas haría.
3.3. Modifique el código de Datos.java.
3.4. Modifique
el
código
de
MisPosibilidades.java:
Indique
qué
se
debería
modificar
en
cada
uno
de
los
métodos
combinaciones(),validos()
y
busca()
(puede que alguno de ellos no requiera modificación alguna)
3.5. Indique qué pruebas debería desarrollar en PosibilidadesTest.java para probar el
funcionamiento del algoritmo sobre redes con nodos de capacidad limitada. No escriba las
pruebas; sólo indique qué pruebas haría.
3.1 Hay que introducir un nuevo tipo de línea en el fichero de entrada que incluya
el número del nodo al que vamos a aplicar el límite
el límite
con las condiciones siguientes
el nodo debe estar dentro de los existentes
1
Esta ecuación es cierta para todos los nodos, excepto el nodo origen (que carece de flujo
entrante) y el nodo destino (que carece de flujo saliente).
3
el límite debe ser mayor o igual a cero, L ≥ 0
Para distinguir esta línea de las ya existentes podemos, por ejemplo, diferenciarla
insertando un primer caracter especial: por ejemplo un asterisco, de forma que
*24 100
indica que el nodo 24 tiene un límite de 100 en el flujo asumible.
3.2 Hay que probar que
1. se carga el límite
2. se detecta un nodo incorrecto (negativo o más allá del número total de nodos
3. se detecta un flujo negativo
3.3 Hay que preparar una estructura de datos para almacenar el límite, si existe. Como
tiene que ser positivo, codificaremos con el valor –1 aquellos nodos que no tienen
límite, que será lo normal salvo que el fichero de datos lo imponga.
private int limite[];
// inicialización
public Datos (int n, ...) {
...
limite= new int[n];
for (int i= 0; i < n; i++)
limite[n]= -1;
}
// carga de valores
public void limite (int nodo, int max) {
limite[nodo]= max;
}
public int limite (int nodo) {
return limite[nodo];
}
3.4 combinaciones()
no hay que modificar nada
validos()
hay que aceptar sólo aquellas asignaciones de flujo que respeten el valor
máximo si lo hubiera
...
boolean ok= n == origen || n == destino || f.flujo(n)
== 0;
int lim= datos.limite(n);
if (lim >= 0) {
int entrante= 0;
for (int i= 0; i < tamanno; i++)
if (f.flujo(i, n) > 0)
entrante++;
ok&= entrante <= lim;
}
if (ok)
valen.add(f);
4
busca()
No hay que modificar nada.
3.5 Se toma un caso de prueba cuya solución implique que por un nodo N pasan X datos,
siendo X mayor que cero. A continuación se preparan dos casos de prueba:
1. se limita el tráfico por N a 0 y se observa que cambia la solución, respetando el
límite
2. se limita el tráfico por N a algún valor entre 0 y X y se observa que cambia la
solución, respetando el límite
3. se limita el tráfico por N al valor X y se observa que no cambia la solución
4. se limita el tráfico por N a un valor superior a X y se observa que no cambia la
solución
5
Descargar