Вы находитесь на странице: 1из 3

UNA SOLUCIÓN EJERCICIO PRÁCTICA

Dada una matriz NxM, que representa un laberinto, encontrar un conjunto de movimientos a realizar para encontrar la salida en la posición (N-1,M-1),
desde la posición (0,0). Asuma que el laberinto puede tener posiciones libres (por donde se puede caminar) o bloqueadas (paredes).

Procedure Backtracking(paso) Type Integer Direccion; // 0=Ninguna, 1=Norte, 2=Sur, 3=Este, 4=Oeste;
InicializarAlternativa(alternativa); Const Integer Libre=0;
Repeat Const Integer Pared=1;
ObtenerSiguienteAlternativa(alternativa); Const Integer Visitado=2;
If (AlternativaValida(alternativa)) Then // variables globales
IncluirAlternativa(alternativa, solucionParcial); Array IncI[0..4] of Integer = {0,-1,+1,0,0};
If EsSolucion(solucionParcial) then Array IncJ[0..4] of Integer = {0,0,0,+1,-1};
encontreSolucion = true; Array solucion[0..*] of Integer; // graba las direcciones
ProcesarSolucion(solucionParcial);
Else Integer tamaño_solucion;
nuevoPaso = GenerarNuevoPaso(paso); Boolean encontro;
Backtracking(nuevoPaso); // cada celda puede tener los valores Libre, pared, visitado
If not encontreSolucion Then Array A[0..N-1][0..M-1] of Integer;
Paso = DeshacerPaso(nuevoPaso);
ExcluirAlternativa(alternativa, Procedure Main()
solucionParcial); LeerMatriz(A,N,M);
EndIf tamaño_solucion = 0;
EndIf encontro = false;
EndIf A[0,0] = Visitado;
Until SeAcabaronLasAternativas(alternativa) or Laberinto(0,0);
encontreSolucion==true; EndProcedure

Procedure Laberinto(Integer pasoI, Integer pasoJ)


// tenemos 4 alternativas (Norte, Sur, Este, Oeste)
Integer Alternativa;

// inicializar alternativa con la dirección “ninguna”


Alternativa = 0;
Repeat
// obtener siguiente alternativa
Alternativa = Alternativa+1;

// chequear si la alternativa es válida


If (pasoI+IncI[Alternativa]>=0 and pasoI+IncI[Alternativa]<N and
pasoJ+IncJ[Alternativa]>=0 and pasoJ+IncJ[Alternativa]<N and
A[pasoI+IncI[Alternativa]][ pasoJ+IncJ[Alternativa]] == Libre) then
// incluir alternativa
tamaño_solucion = tamaño_solucion+1;
solucion[tamaño_solucion] = Alternativa;
// chequeando si es solución
If (pasoI == N-1 and pasoJ == M-1) then
// encontramos una solución
encontro = true;
// se imprime la solución
ProcesarSolucion(solucion, tamaño_solucion);
Else
// GenerarNuevoPaso
pasoI = pasoI+ IncI[Alternativa];
pasoJ = pasoJ+ IncJ[Alternativa];
A[pasoI][pasoJ] = Visitado;
// backtracking (nuevo_paso)
Laberinto(pasoI, pasoJ);
If (not encontro) then
// DeshacerPaso
A[pasoI][pasoJ] = Libre;
pasoI = pasoI – IncI[Alternativa];
pasoJ = pasoJ – IncJ[Alternativa];
// ExcluirAlternativa
tamano_solucion = tamano_solucion-1;
EndIf
EndIf
EndIf
Until encontro==true or Alternativa==4;
EndProcedure
Tarea:
Utilizando los esquemas, adapte el algoritmo de laberinto para
1. Encontrar la solución óptima (la que tenga menos movimientos)
2. Imprimir todas las soluciones
TODAS LAS SOLUCIONES EJERCICIO PRÁCTICA
Procedure Backtracking(paso) Ejercicio2: las permutaciones
InicializarAlternativa(alternativa); Imprimir todas las permutaciones de un arreglo de N elementos (Backtracking). En este caso,
Repeat la solución más intuitiva es una simplificación del esquema general. El problema de hallar las
ObtenerSiguienteAlternativa(alternativa); permutaciones de n elementos puede tener diversos usos. Por ejemplo, una implementación
If (AlternativaValida(alternativa)) Then posible de ordenar n elementos es examinar las permutaciones de un arreglo, y chequear cuál
IncluirAlternativa(alternativa, solucionParcial); de las permutaciones resulta un arreglo ordenado.
If EsSolucion(solucionParcial) then
ProcesarSolucion(solucionParcial); Procedure Perm(Ref Array A[1..N] of Elemento, Integer paso)
Else Integer i;
nuevoPaso = GenerarNuevoPaso(paso); If (paso == N) Then // Es solución?
Backtracking(nuevoPaso); For i=1 To N Do
Paso = DeshacerPaso(nuevoPaso); Write(A[i]);
EndIf EndFor
ExcluirAlternativa(alternativa, solucionParcial); Else
EndIf For i=paso To N Do // barremos todas las alternativas
Until SeAcabaronLasAternativas(alternativa) or Swap(A[paso], A[i]); // incluir alternativa
encontreSolucion==true; Perm(A,paso+1); // permutamos un subarreglo
EndProcedure Swap(A[paso], A[i]); // excluir alternativa
EndFor
EndIf
EndProcedure
A continuación se instancia el esquema general para solucionar el problema. Utilizamos un
lógico que indica si el elemento fue visitado, y un arreglo GLOBAL llamado “secuencia” que
almacena la permutación parcial (solucionParcial). Inicialmente los elementos de V están en
false.

Procedure Perm(Ref Array A[1..N] of Elem, Ref Array V[1..N] of Boolean, Integer paso)

Integer i = 0, j; // Inicializar_alternativa(alternativa)

Repeat
i = i+1; // Obtener_siguiente_alternativa(alternativa)

If (V[i] == false) Then // alternativa válida


secuencia[paso] = A[i]; // Incluir alternativa
V[i] = true; // Incluir alternativa
If (paso == N) Then // EsSolucion(Solucion)
For j=1 To N Do // Procesar solucion
Write(secuencia[j]);
EndFor
Else
paso = paso+1; // GenerarNuevoPaso
Perm(A, V, paso); // Backtracking(NuevoPaso)
paso = paso-1; // deshacer paso
EndIf
V[i] = false; // Excluir Alternativa
EndIf
Until (i==N); // se acabaron las alternativas
EndProcedure
SOLUCIÓN ÓPTIMA EJERCICIO PRÁCTICA
Ejercicio 3: la mochila
Dados n elementos, cada uno con un peso, indicar cuáles de estos elementos pueden llevarse en una mochila que tiene una capacidad de k kilos, de
manera de maximizar el número de kilos llevados en la mochila.

Ejemplo 1: Si los elementos son 7, 5, 6, 3, 8, 8, 4 y la mochila tiene una capacidad de 21 kilos, me llevaría los siguientes elementos:
5, 8, 8
Ejemplo 2: Si los elementos son 7, 5, 3, 9 y la mochila tiene una capacidad de 20 kilos, me llevaría los siguientes elementos:
7, 3, 9

Solución algorítmica:
Const Integer n = 30; // número de elementos (asumimos 30)
// tipos de datos
Type Record Mochila =
Integer kilos; // kilogramos que está cargando la mochila
Integer m; // número de elementos llevados en la mochila
Array x[1..n] of Integer; // elementos dentro de la mochila
EndRecord
// variables globales
Array elem[1..n] of Integer; // elementos a considerar
Integer capacidadMaxima; // capacidad máxima de la mochila
Mochila actual, mejor;

// Procedimiento principal
Procedure Main()
// se lee la capacidad máxima de la mochila (k)
Read(capacidadMaxima);
// se leen los elementos candidatos
For i=1 To n Do
Read(elem[i]);
EndFor
// inicialmente no hay nada en ninguna mochila
actual.m = 0;
actual.kilos = 0;
mejor.m = 0;
mejor.kilos = -1;
//se invoca al backtracking
Backtracking(1);
//se imprime la solución
Write(“Me llevo “, mejor.kilos, “kilos en la mochila”);
For i=1 To mejor.m Do
Write(mejor.x[i]);
EndFor
EndProcedure
G
Procedure Backtracking(paso) Procedure Backtracking(Integer paso)
InicializarAlternativa(alternativa); Integer alternativa;
Repeat // inicializar alternativa
ObtenerSiguienteAlternativa(alternativa); alternativa = paso-1;
If (AlternativaValida(alternativa)) Then Repeat
IncluirAlternativa(alternativa, solucionParcial); //selecciono la próxima alternativa
If EsSolucion(solucionParcial) then alternativa = alternativa+1;
If EsMejor(solucionParcial, solucionOptima) Then //chequeo si la alternativa es válida
solucionOptima = solucionParcial; If (actual.kilos + elem[alternativa] <= capacidadMaxima) then
EndIf //incluir alternativa
Else actual.kilos = actual.kilos+ elem[alternativa];
nuevoPaso = GenerarNuevoPaso(paso); actual.m = actual.m+1;
Backtracking(nuevoPaso); actual.x[actual.m] = elem[alternativa];
Paso = DeshacerPaso(nuevoPaso); //chequeo si la solución actual es mejor
EndIf If (actual.kilos > mejor.kilos) then
ExcluirAlternativa(alternativa, solucionParcial); mejor = actual;
EndIf EndIf
Until SeAcabaronLasAternativas(alternativa) or encontreSolucion==true; // llamada recursiva con el nuevo paso (paso+1)
EndProcedure Backtracking(paso+1);
//excluir alternativa tomada
actual.kilos = actual.kilos - elem[alternativa];
actual.m = actual.m - 1;
EndIf
Until (alternartiva==n); // hasta que se acaben las alternativas
EndProcedure

Вам также может понравиться