Solución Examen Algorítmica Feb`07

Anuncio
Dpto. O.E.I. – U.P.M.
ALGORÍTMICA
07/FEB/07
1º) (3'5 Puntos) Sea G un Grafo Dirigido Valorado con N vértices representado por su
matriz de costes.
Se pide: Desarrollar un algoritmo en Pascal que obtenga, si es que existe, la cadena con
menor coste posible que pase una única vez por cada uno de los vértices del grafo.
(* En el vector de visitados se almacenará además el orden en que se visitan los vértices *)
TYPE
tVisitados = ARRAY [1..N] OF Integer;
(* Cadena de menor coste que pasa por todos los vértices una sola vez.
Esquema de selección óptima *)
PROCEDURE CadeMin (GDV: tMatrizCoste; vActual, costeActual, pos: Integer; VAR costeMin: Integer;
VAR Visitados, Solucion: tVisitados);
VAR
i, w, arcoMenor: Integer;
BEGIN
FOR w := 1 TO N DO
IF
(Visitados[w] = 0) AND (GDV[vActual, w] <> Infinito OR GDV[w, vActual] <> Infinito)
THEN BEGIN
IF
GDV[vActual, w] < GDV[w, vActual] (* arco de menor coste, es cadena *)
THEN arcoMenor := GDV[vActual, w]
ELSE arcoMenor := GDV[w, vActual];
Visitados[w] := pos; (* orden en el que se visitan los vértices *)
IF
costeActual + arcoMenor < costeMin
THEN IF
pos = N (* se han visitado todos los vértices *)
THEN BEGIN (* nueva solución óptima *)
costeMin := costeActual + arcoMenor;
FOR i := 1 TO N DO
Solucion[i] := Visitados[i];
END
ELSE CadeMin(GDV, w, costeActual+arcoMenor, pos+1, costeMin, Visitados, Solucion);
Visitados[w] := 0
END
END;
(* CadeMin *)
(* PROGRAMA PRINCIPAL *)
BEGIN
costeMin := Infinito;
FOR i := 1 TO N DO
Visitados[i] := 0;
(* el origen de la solución puede ser cualquier vértice *)
FOR vInicio := 1 TO N DO
BEGIN
Visitados[vInicio] := 1;
CadeMin(GDV, vInicio, 0, 2, costeMin, Visitados, Solucion)
Visitados[vInicio] := 0;
END;
(* mostrar resultados *)
IF
costeMin = Infinito
THEN writeLn('No existe solución')
ELSE BEGIN
writeLn('Coste de la cadena mínima: ', costeMin);
writeLn('Los vértices se deben visitar en el siguiente orden:');
FOR i := 1 TO N DO
writeLn('Vértice ', i:2, ': orden', Solucion[i]:2);
END
END.
2º) (3,5 Puntos) Se dispone de una matriz de NxN enteros. Se desea saber si en dicha
matriz existe un conjunto de N coordenadas (X, Y) que cumplan las siguientes condiciones:
El contenido de la matriz en cada una de las coordenadas (X, Y) coincide con el valor
de Y, es decir, M[X, Y] = Y
No pueden aparecer 2 ó más coordenadas con el mismo valor de X.
Se pide: Desarrollar un algoritmo en Pascal que determine si existe un conjunto de N
coordenadas que cumplan las condiciones anteriores.
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
1
2
4
5
6
1
2
1
2
1
2
3
4
5
6
7
3
2
2
1
6
7
3
8
4
5
5
4
5
1
2
5
5
5
1
7
7
7
7
2
6
8
6
2
6
7
5
6
7
1
2
7
8
8
5
7
8
2
1
5
5
8
8
7
Dado el tablero de la izquierda, un posible conjunto de
N coordenadas que cumple las condiciones
establecidas sería el formado por:
{
C = (1,1), (3,2), (7,3), (4,4), (2,5), (5,6), (8,7), (6,8)
FUNCTION Buscar_Coordenadas(Tablero: tTablero): Boolean;
VAR
X, Y: Integer;
Encontrado: Boolean;
BEGIN
Encontrado := True;
X := 1;
WHILE (X <= N) AND Encontrado DO
BEGIN
Y := 1;
Encontrado := False;
WHILE (Y <= N) AND (Not Encontrado) DO
BEGIN
IF (Tablero[X, Y] = Y) THEN
Encontrado := True;
Y := Y + 1
END;
X := X + 1
END;
Buscar_Coordenadas := Encontrado
END;
(* PROGRAMA PRINCIPAL *)
Solucion := Buscar_Coordenadas(Tablero);
}
Dpto. O.E.I. – U.P.M.
ALGORÍTMICA
07/FEB/07
3º) (3 Puntos) Sea G un Grafo Árbol Dirigido no valorado representado por listas de
adyacencia, y dado Costes que es un vector de enteros que contiene el coste asociado a
cada vértice de G. Se define el Coste Ponderado por Descendiente (CPD) del grafo como:
CPD =
Costes v * numerodedescendientes(v)
v V
Se pide: Siguiendo el esquema Divide y Vencerás, desarrollar un algoritmo en Pascal que
obtenga el Coste Ponderado por Descendiente del Grafo (la raíz es el vértice 1).
1
2
Vector de Costes
3
5
4
6
7
8
1
2
3
4
5
6
7
8
9
10
10
20
20
20
30
30
30
30
CPD = Costes[1]*8 + Costes[3]*5 + Costes[6]*3 =
10*8 + 20*5 +30 *3 = 270
9
FUNCTION CPD(G: tGrafoListasAdy; actual: Integer; Costes: tArray; VAR Hijos: Integer): Integer;
VAR
CPDs, Descendientes: ARRAY [1..N] OF Integer ;
Resultado, Trato: Integer;
Aux: tListaAdyacencia;
BEGIN
IF (G[actual] = NIL) THEN (* caso base *)
BEGIN
Hijos := 1;
Resultado := 0;
END
ELSE BEGIN
(* Inicialización variables locales para recoger los resultados de las llamadas *)
FOR Trato := 1 TO N DO
BEGIN
Descendientes[Trato] := 0;
CPDs[Trato] := 0
END;
(* División del problema. Hay que generar una llamada por cada hijo *)
Aux := G[actual];
WHILE Aux <> NIL DO
BEGIN
CPDs[Aux^.Nodo] := CPD (G, Aux^.Nodo, Costes, Descendientes[Aux^.Nodo]);
Aux := Aux^.Siguiente
END;
(* Proceso de Mezcla *)
Resultado := 0;
(* Cuento el número de Hijos *)
FOR Trato := 1 TO N DO
Resultado := Resultado + Descendientes[Trato];
Hijos := Resultado + 1; (* Hay que contar el nodo actual *)
(* coste del vértice actual *)
Resultado := Resultado * Costes [actual];
(* sumatorio pedido *)
FOR Trato := 1 TO N DO
Resultado := Resultado + CPDs[Trato]
END;
CPD := Resultado
END; (* CPD *)
BEGIN
Hijos := 0;
Resultado := CPD(Grafo, 1, Costes, Hijos);
writeLn ('El resultado es:', Resultado)
END.
Descargar