SOLUCIÓN - Universidad Politécnica de Madrid

Anuncio
Dpto. O.E.I. – U.P.M.
ALGORÍTMICA
03/FEB/10
1º) (3’5 Puntos)
Se dispone de una matriz con N filas y M columnas inicializada aleatoriamente con
ceros y unos. La última columna sólo contiene unos. También se dispone de una ficha que
sólo puede desplazarse a las casillas que contengan un uno según los movimientos que se
muestran en la siguiente figura:
⊗
Se pide: implementar un algoritmo en Pascal que partiendo de una de
una determinada casilla, y pasando exclusivamente por celdas que contengan
unos, determine si es posible llegar a todas las celdas de la última columna.
CONST
N = …;
M = …;
Movimientos = 3;
TYPE
tTablero = ARRAY[1 .. N, T1 .. M] OF 0 .. 1;
tDesplazamiento = ARRAY [1 .. Movimientos] OF -1 .. 1;
tAlcanzado = ARRAY [1 .. N] OF Boolean;
VAR
Tablero : tTablero; DesplazamientoFila: tDesplazamiento;
Alcanzado: tAlcanzado; Solucion: Boolean; I: Integer;
FUNCTION Aceptable(Tablero: tTablero; Fila, Columna: Integer): Boolean;
BEGIN
IF
(Fila >= 1) AND (Fila <= N)
THEN Aceptable := (Tablero[Fila, Columna] = 1)
ELSE Aceptable := False
END;
FUNCTION EsSolucion(Alcanzado: tAlcanzado): Boolean;
VAR Ok: Boolean; I: Integer;
BEGIN
Ok := True;
I := 1;
WHILE (I <= N) AND Ok DO
BEGIN
Ok := Alcanzado[I]; I := I + 1
END;
EsSolucion := Ok
END;
PROCEDURE Ensayar(VAR Tablero: tTablero; Fila, Columna: Integer; VAR Alcanzado: tAlcanzado;
DesplazamintoFila: tDesplazamiento; VAR Solucion: Boolean);
VAR Posibilidad, NF, NC: Integer;
BEGIN
Posibilidad := 0;
REPEAT
Posibilidad := Posibilidad + 1;
NF := Fila + DesplazamintoFila[Posibilidad];
NC := Columna + 1;
IF Aceptable(Tablero, NF, NC) THEN
IF NC = M THEN
BEGIN
Alcanzado[NF] := true;
IF EsSolucion(Alcanzado) THEN Solucion := True
END
ELSE Ensayar(Tablero, NF, NC, Alcanzado, DesplazamintoFila, Solucion);
UNTIL (Posibilidad = Movimientos) OR Solucion
END;
BEGIN
…
DesplazamientoFila[1] := -1;
DesplazamientoFila[2] := 0;
DesplazamientoFila[3] := +1;
FOR I:=1 TO N DO
Alcanzado[I] := False;
Solucion := False;
Ensayar(Tablero, 2, 1, Alcanzado, DesplazamientoFila, Solucion);
IF
Solucion THEN Writeln('SÍ EXISTE')
ELSE Writeln('NO EXISTE SOLUCIÓN')
END.
Universidad Politécnica de Madrid – E.U. Informática Página 1 2º) (3’5 Puntos)
Sea G un Grafo Dirigido representado por su matriz de adyacencia. Se dice que un
camino de G <V0, V1, V2, …, Vk> es creciente si se cumple que V0 < V1, V1 < V2, …, y Vk-1 < Vk
Se pide: desarrollar un algoritmo en Pascal que determine cual es el camino creciente
de mayor longitud entre dos vértices dados (el algoritmo contemplará la posibilidad de que no
exista ningún camino creciente entre dichos vértices)
CONST
NMax = 25;
(* Número máximo de vértices *)
TYPE
tMatrizAdy = ARRAY [1..NMax, 1..NMax] OF Boolean; (* Matriz de Adyacencia *)
tVisitados = ARRAY [1..NMax] OF Boolean;
VAR
GD: tMatrizAdy; v, N, numVertMaximo: Integer;
Visitados, VisitadosOpt: tVisitados;
(* N: Número real de vértices *)
(* Algoritmo de selección óptima *)
PROCEDURE CaminoCreciente(VAR GD: tMatrizAdy; (* por ref. para ahorrar memoria *)
vActual, vDestino, numVertActual: Integer;
VAR numVertMaximo: Integer; VAR Visitados, VisitadosOpt: tVisitados);
VAR v: Integer;
BEGIN
(* vActual < candidatos_aceptables < vDestino *)
FOR v := (vActual + 1) TO vDestino DO
IF
GD[vActual, v] (* aceptable: existe el arco *)
THEN BEGIN
(* anotar *)
numVertActual := numVertActual + 1;
Visitados[v] := True;
IF
v = vDestino (* es solución *)
THEN BEGIN
IF
numVertActual > numVertMaximo
THEN BEGIN
numVertMaximo := numVertActual;
VisitadosOpt := Visitados;
END
END
ELSE CaminoCreciente(GD, v, vDestino, numVertActual, numVertMaximo,
Visitados, VisitadosOpt);
(* desanotar *)
numVertActual := numVertActual - 1;
Visitados[v] := False;
END
END; (* CaminoCreciente *)
PROCEDURE Escribir_Camino(Visitados: tVisitados; Origen, Destino: Integer);
BEGIN
FOR v := Origen TO Destino DO
IF
Visitados[v]
THEN Write(v, ', ')
END; (* Escribir_Camino *)
BEGIN
CargarMatriz(GD);
(* Inicializamos el vector de Visitados *)
FOR v := 1 TO N DO
Visitados[v] := False;
(* Llamada al algoritmo de selección óptima: p.ej. origen=1, destino=N *)
numVertMaximo := 1;
Visitados[1] := True;
CaminoCreciente(GD, 1, N, 1, numVertMaximo, Visitados, VisitadosOpt);
IF
numVertMaximo = 1
(* No se ha encontrado ningún camino *)
THEN WriteLn('No hay camino')
ELSE BEGIN
Escribir_Camino(VisitadosOpt, 1, N);
WriteLn(' (', numVertMaximo, ' vértices)')
END
END.
Universidad Politécnica de Madrid – E.U. Informática Página 2 3º) (3 Puntos)
Sea G un Grafo Dirigido Valorado. Un vértice w es alcanzable desde v si existe camino
en G de v a w. Adicionalmente, se define la accesibilidad de un vértice v como el número de
vértices alcanzables desde v.
Dada la matriz CM que se obtiene tras la aplicación del algoritmo de Floyd sobre G, se
pide: siguiendo el esquema Divide y Vencerás, implementar un algoritmo que determine el
vértice (o conjunto de vértices) de G con mayor accesibilidad.
CONST
NMax = 25; (* Número máximo de vértices *)
FichGrafo = 'gdv.txt';
Infinito = MaxInt;
TYPE
tMatrizCoste = ARRAY [1..NMax, 1..NMax] OF Integer;
tVisitados = ARRAY [1..NMax] OF Boolean;
VAR
CM, GDV: tMatrizCoste;
v, N, numVertMaximo: Integer;
Visitados: tVisitados;
(* N: Número real de vértices *)
(* Calcula la accesibilidad del vértice ‘Fila’ *)
FUNCTION DyV_Accesibilidad(CM: tMatrizCoste; Fila, Iz, De: Integer): Integer;
VAR
medio, v, acce1, acce2: Integer;
BEGIN
IF
Iz = De (* caso base *)
THEN IF
CM[Fila, Iz] = Infinito
THEN DyV_Accesibilidad := 0
ELSE DyV_Accesibilidad := 1
ELSE BEGIN
medio := (Iz + De) DIV 2;
acce1 := DyV_Accesibilidad(CM, Fila, Iz, medio);
acce2 := DyV_Accesibilidad(CM, Fila, medio + 1, De);
DyV_Accesibilidad := acce1 + acce2; (* suma de los vértices accesibles *)
END
END; (* DyV_Accesibilidad *)
PROCEDURE DyV_MayorAccesibilidad(CM: tMatrizCoste; Inf, Sup: Integer;
VAR Vertices: tVisitados; VAR accesibilidad: Integer);
VAR
Vert1, Vert2: tVisitados;
medio, v, acce1, acce2: Integer;
BEGIN
IF
Inf = Sup (* caso base *)
THEN BEGIN
accesibilidad := DyV_Accesibilidad(CM, Inf, 1, N);
FOR v := 1 TO N DO Vertices[v] := False;
Vertices[Inf] := True;
END
ELSE BEGIN
medio := (Inf + Sup) DIV 2;
DyV_MayorAccesibilidad(CM, Inf, medio, Vert1, acce1);
DyV_MayorAccesibilidad(CM, medio + 1, Sup, Vert2, acce2);
IF
acce1 > acce2
THEN BEGIN
Vertices := Vert1;
accesibilidad := acce1;
END
ELSE IF
acce2 > acce1
THEN BEGIN
Vertices := Vert2;
accesibilidad := acce2;
END
ELSE BEGIN (* misma accesibilidad *)
Vertices := Vert1;
FOR v := medio + 1 TO Sup DO Vertices[v] := Vert2[v];
accesibilidad := acce1
END
END
END; (* DyV_MayorAccesibilidad *)
Universidad Politécnica de Madrid – E.U. Informática Página 3 PROCEDURE MayorAccesibilidad(CM: tMatrizCoste);
VAR
Vertices: tVisitados;
accesibilidad, v: Integer;
BEGIN
DyV_MayorAccesibilidad(CM, 1, N, Vertices, accesibilidad);
WriteLn('Máxima accesibilidad: ', accesibilidad);
Write('Vértices: ');
FOR v := 1 TO N DO
IF Vertices[v]
THEN Write(v, ' ')
END;
BEGIN (* programa principal *)
CargarMatriz(GDV);
Floyd(GDV, CM);
MayorAccesibilidad(CM);
END.
Universidad Politécnica de Madrid – E.U. Informática Página 4 
Descargar