Tema 7: Algoritmos de vuelta atrás

Anuncio
Tema 7: Algoritmos de vuelta atrás
7.1
7.2
7.3
7.4
7.5
Introducción
Esquema general
Colocación de Reinas en un tablero
Recorrido del Rey en ajedrez
La mochila (4 versiones)
1
Esquema general una solución (I)
func btUna(x: Etapa) dev (exito: Logico)
var
xsig: Etapa
cand: Candidatos
alg
si esSolucion(x):
exito := cierto
| otras:
exito := falso
cand := calculaCandidatos(x)
mientras NO exito Y quedanCandidatos(cand)
xsig = seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
exito := btUna(xsig)
si NO exito:
cancelaAnotacion(cand, x, xsig)
fsi
fsi
fmientras
fsi
fin
2
Esquema general una solución (II)
<abstracto>
<abstracto>
<abstracto>
<abstracto>
<abstracto>
<abstracto>
<abstracto>
func esSolucion(x: Etapa) dev (b: Logico)
func calculaCandidatos(x: Etapa) dev (cand: Candidatos)
func quedanCandidatos(cand: Candidatos) dev (b: Logico)
func seleccionaCandidato(cand: Candidatos; ent/sal x: Etapa) dev (xsig: Etapa)
func esPrometedor(cand:Candidatos; x, xsig: Etapa) dev (b: Logico)
proc anotaSolucion(cand:Candidatos; ent/sal x, xsig: Etapa)
proc cancelaAnotacion(cand: Candidatos; ent/sal x, xsig: Etapa)
3
Esquema general todas soluciones
proc btTodas(x: Etapa)
var
xsig: Etapa
cand: Candidatos
alg
si esSolucion(x):
comunicaSolucion()
fsi
cand := calculaCandidatos(x)
mientras quedanCandidatos(cand)
xsig := seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
btTodas(xsig)
cancelaAnotacion(cand, x, xsig)
fsi
fmientras
fin
<abstracto> proc comunicaSolucion()
4
Esquema general solución óptima
proc btOptimo(x: Etapa)
var
xsig: Etapa
cand: Candidatos
alg
si esSolucion(x):
si esMejor():
actualizaSolucion()
fsi
fsi
cand := calculaCandidatos(x)
mientras quedanCandidatos(cand)
xsig = seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
btOptimo(xsig)
cancelaAnotacion(cand, x, xsig)
fsi
fmientras
fin
<abstracto> func esMejor() dev (b:Logico)
<abstracto> proc actualizaSolucion()
5
Colocar Reinas en tablero – Una (1)
clase ReinasBT_UNA
N: Entero
sol: Solucion
clase Solucion
s: array [1..N] de Entero
fclase
clase Etapa
k: Entero
fclase
clase Candidatos
i: Entero
fclase
func colocaReinas() dev (exito: Logico)
var x: Etapa
alg
x.k := 0
//no haría falta, solo que esté creado el array
sol.s := < crea array de ceros >
exito := btUna(x)
si exito:
<tratar sol>
fsi
fin
func esSolucion(x: Etapa) dev (b: Logico)
alg
b := (x.k = N)
fin
6
Colocar Reinas en tablero – Una (2)
func calculaCandidatos(x: Etapa) dev (cand: Candidatos)
alg
// los candidatos son los enteros desde 1 a N
cand.i := 0
fin
func quedanCandidatos(cand: Candidatos) dev (b: Logico)
alg
b := (cand.i < N)
fin
func btUna(x: Etapa) dev (exito: Logico)
var
xsig: Etapa
cand: Candidatos
alg
si esSolucion(x):
exito := cierto
| otras:
exito := falso
cand := calculaCandidatos(x)
mientras NO exito Y quedanCandidatos(cand)
xsig := seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
exito := btUna(xsig)
si NO exito:
cancelaAnotacion(cand, x, xsig)
fsi
fsi
fmientras
fsi
fin
func seleccionaCandidato (ent/sal cand: Candidatos; ent/sal x: Etapa) dev (xsig: Etapa)
alg
cand.i := cand.i + 1
xsig.k := x.k + 1
fin
7
Colocar Reinas en tablero – Una (3)
func esPrometedor(cand:Candidatos; x, xsig: Etapa) dev (b: Logico)
var
func btUna(x: Etapa) dev (exito: Logico)
i: Entero
var
alg // sol es (x.k)-prometedor
xsig: Etapa
cand: Candidatos
<b, i> := <cierto, 1>
alg
mientras (i <= xsig.k - 1) Y (b)
si esSolucion(x):
exito := cierto
si (sol.s[i] = cand.i) O (Abs(sol.s[i]-cand.i) = Abs(i-xsig.k)):
| otras:
b:=falso
exito := falso
fsi
cand := calculaCandidatos(x)
mientras NO exito Y quedanCandidatos(cand)
i:=i+1
xsig := seleccionaCandidato(cand, x)
fmientras
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
fin
proc anotaSolucion(cand: Candidatos; ent/sal x, xsig: Etapa)
alg
sol.s[xsig.k] := cand.i
fin
exito := btUna(xsig)
si NO exito:
cancelaAnotacion(cand, x, xsig)
fsi
fsi
fmientras
fsi
fin
proc cancelaAnotacion(cand: Candidatos; ent/sal x, xsig: Etapa)
alg
fin
8
Colocar Reinas en tablero – Todas (1)
clase ReinasBT_TODAS
N: Entero
sol: Solucion
clase Solucion
s: array [1..N] de Entero
fclase
proc colocaReinas()
var x: Etapa
alg
x.k := 0
sol.s := < crea array de ceros >
btTodas(x)
fin
clase Etapa
k: Entero
fclase
clase Candidatos
i: Entero
fclase
9
Colocar Reinas en tablero – Todas (2)
func calculaCandidatos(x: Etapa) dev (cand: Candidatos)
alg
si x.k < N:
// los candidatos son los enteros desde 1 a N
proc btTodas(x: Etapa)
cand.i := 0
var
xsig: Etapa
| otras:
cand: Candidatos
cand.i := N // para que no haya más candidatos alg
si esSolucion(x):
fsi
comunicaSolucion()
fsi
fin
proc comunicaSolucion()
alg
<imprime sol>
fin
cand := calculaCandidatos(x)
mientras quedanCandidatos(cand)
xsig := seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
btTodas(xsig)
cancelaAnotacion(cand, x, xsig)
fsi
fmientras
fin
10
Recorridos del Rey en Ajedrez – Una (1)
clase ReyBT_UNA
N: Entero
i0, j0: Entero // posición inicial
sol: Solucion
mov_x, mov_y: array [1..8] de Entero
proc movimientosPosibles()
alg
<mov_x[1],mov_y[1]> :=
<mov_x[2],mov_y[2]> :=
<mov_x[3],mov_y[3]> :=
<mov_x[4],mov_y[4]> :=
<mov_x[5],mov_y[5]> :=
<mov_x[6],mov_y[6]> :=
<mov_x[7],mov_y[7]> :=
<mov_x[8],mov_y[8]> :=
fin
<-1,-1>
<-1,0>
<-1,1>
<0,-1>
<0,1>
<1,-1>
<1,0>
<1,1>
func btUna(x: Etapa) dev (exito: Logico)
var
xsig: Etapa
cand: Candidatos
alg
si esSolucion(x):
exito := cierto
| otras:
exito := falso
cand := calculaCandidatos(x)
mientras NO exito Y quedanCandidatos(cand)
xsig := seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
exito := btUna(xsig)
si NO exito:
cancelaAnotacion(cand, x,xsig)
fsi
fsi
fmientras
fsi
fin
11
Recorridos del Rey en Ajedrez – Una (2)
clase Solucion
s: array [1..N, 1..N] de Entero
fclase
clase Etapa
k: Entero
i, j: Entero
fclase
// número de casillas visitadas
// casilla actual
clase Candidatos
c: Entero
fclase
func btUna(x: Etapa) dev (exito: Logico)
var
xsig: Etapa
cand: Candidatos
alg
si esSolucion(x):
exito := cierto
| otras:
exito := falso
cand := calculaCandidatos(x)
mientras NO exito Y quedanCandidatos(cand)
xsig := seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
exito := btUna(xsig)
si NO exito:
cancelaAnotacion(cand, x, xsig)
fsi
fsi
fmientras
fsi
fin
12
Recorridos del Rey en Ajedrez – Una (3)
func recorridoRey() dev (exito: Logico)
var x: Etapa
alg
<x.k, x.i, x.j> := <1, i0, j0>
sol.s := < crea array de ceros >
sol.s[i0, j0] := 1
exito := btUna(x)
si exito:
<tratar sol>
fsi
fin
func esSolucion(x: Etapa) dev (b:Logico)
alg
b := (x.k = N * N)
fin
func btUna(x: Etapa) dev (exito: Logico)
var
xsig: Etapa
cand: Candidatos
alg
si esSolucion(x):
exito := cierto
| otras:
exito := falso
cand := calculaCandidatos(x)
mientras NO exito Y quedanCandidatos(cand)
xsig := seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
exito := btUna(xsig)
si NO exito:
cancelaAnotacion(cand, x, xsig)
fsi
fsi
fmientras
fsi
fin
13
Recorridos del Rey en Ajedrez – Una (4)
func calculaCandidatos(x: Etapa) dev (cand: Candidatos)
alg
// los candidatos son los enteros desde 1 a 8
cand.c := 0
fin
func quedanCandidatos(cand: Candidatos) dev (b: Logico)
alg
b := (cand.c < 8)
fin
func btUna(x: Etapa) dev (exito: Logico)
var
xsig: Etapa
cand: Candidatos
alg
si esSolucion(x):
exito := cierto
| otras:
exito := falso
cand := calculaCandidatos(x)
mientras NO exito Y quedanCandidatos(cand)
xsig := seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
exito := btUna(xsig)
si NO exito:
cancelaAnotacion(cand, x, xsig)
fsi
fsi
fmientras
fsi
fin
func seleccionaCandidato(ent/sal cand: Candidatos; ent/sal x: Etapa) dev (xsig: Etapa)
alg
cand.c := cand.c + 1
xsig.k := x.k + 1
<xsig.i, xsig.j> := <x.i + mov_x[cand.c], x.j + mov_y[cand.c]>
fin
14
Recorridos del Rey en Ajedrez – Una (5)
func esPrometedor(cand: Candidatos; x, xsig: Etapa) dev (b: Logico)
alg
b := (xsig.i>=1 Y xsig.i<=N Y xsig.j>=1 Y xsig.j<=N Y
func btUna(x: Etapa) dev (exito: Logico)
sol.s[xsig.i, xsig.j]=0)
var
fin
xsig: Etapa
proc anotaSolucion(cand:Candidatos; ent/sal x, xsig: Etapa)
alg
sol.s[xsig.i, xsig.j] = xsig.k
fin
proc cancelaAnotacion(cand: Candidatos; ent/sal x, xsig: Etapa)
alg
sol.s[xsig.i, xsig.j] = 0
fin
cand: Candidatos
alg
si esSolucion(x):
exito := cierto
| otras:
exito := falso
cand := calculaCandidatos(x)
mientras NO exito Y quedanCandidatos(cand)
xsig := seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
exito := btUna(xsig)
si NO exito:
cancelaAnotacion(cand, x, xsig)
fsi
fsi
fmientras
fsi
fin
15
Recorridos del Rey en Ajedrez – Todas (1)
clase ReyBT_TODAS
N: Entero
i0, j0: Entero
sol: Solucion
mov_x, mov_y: array [1..8] de Entero
clase Solucion
s: array [1..N, 1..N] de Entero
fclase
clase Etapa
k: Entero
// número de casillas visitadas
i, j: Entero // casilla actual
fclase
clase Candidatos
c: Entero
fclase
16
Recorridos del Rey en Ajedrez – Todas (2)
func recorridoRey() dev (éxito: Logico)
alg
<x.k, x.i, x.j> := <1, i0, j0>
sol.s := < crea array de ceros >
sol.s[i0,j0] := 1
BT_TODAS(x)
fin
func calculaCandidatos(x: Etapa) dev (cand: Candidatos)
alg
si x.k < N * N:
// los candidatos son los enteros desde 1 a 8
cand.c := 0
| otras // para que no haya más candidatos
cand.c := N *N
fin
proc comunicaSolucion()
alg
<imprime sol>
fin
proc btTodas(x: Etapa)
var
xsig: Etapa
cand: Candidatos
alg
si esSolucion(x):
comunicaSolucion()
fsi
cand := calculaCandidatos(x)
mientras quedanCandidatos(cand)
xsig := seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
btTodas(xsig)
cancelaAnotacion(cand, x, xsig)
fsi
fmientras
fin
17
La Mochila 1 – Sin Repetición (1)
clase MochilaSinRepetBT
// número de objetos
N: Entero
pesos, valores: array [1..N] de Entero
pesoMax: Entero
solOpt: Solucion
sol: Solucion
clase Solucion
s: array [1..N] de Entero
// valor hasta el momento
valor: Entero
fclase
clase Etapa
k: Entero
// peso aún disponible
capac: Entero
fclase
clase Candidatos
i: Entero
// cap: Entero
fclase
proc resuelveMochila()
var x: Etapa
alg
solOpt.s := < crea array de ceros >
solOpt.valor := 0
x.k := 0
x.capac := pesoMax
sol.valor := 0
sol.s := < crea array de ceros >
btOptimo(x)
<imprime solOpt.s y solOpt.valor>
fin
18
La Mochila 1 – Sin Repetición (2)
func esSolucion(x: Etapa) dev (b: Logico)
alg
b := (x.k = N)
fin
func esMejor() dev (b:Logico)
alg
b := (sol.valor > solOpt.valor)
fin
proc actualizaSolucion()
alg
<solOpt.s, solOpt.valor> := <sol.s, sol.valor>
fin
proc btOptimo(x: Etapa)
var
xsig: Etapa
cand: Candidatos
alg
si esSolucion(x):
si esMejor():
actualizaSolucion()
fsi
fsi
cand := calculaCandidatos(x)
mientras quedanCandidatos(cand)
xsig := seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
btOptimo(xsig)
cancelaAnotacion(cand, x, xsig)
fsi
fmientras
fin
19
La Mochila 1 – Sin Repetición (3)
func calculaCandidatos(x: Etapa) dev (cand: Candidatos)
alg
si x.k < N:
cand.i := – 1 // los candidatos son 0 ó 1
| otras:
cand.i := 1 // para que no haya más candidatos
fsi
fin
func quedanCandidatos(cand: Candidatos) dev (b:Logico)
alg
b := (cand.i < 1)
fin
proc btOptimo(x: Etapa)
var
xsig: Etapa
cand: Candidatos
alg
si esSolucion(x):
si esMejor():
actualizaSolucion()
fsi
fsi
cand := calculaCandidatos(x)
mientras quedanCandidatos(cand)
xsig := seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
btOptimo(xsig)
cancelaAnotacion(cand, x, xsig)
fsi
fmientras
fin
func seleccionaCandidato(ent/sal cand: Candidatos; ent/sal x: Etapa) dev (xsig: etapa)
alg
cand.i := cand.i + 1
xsig.k = x.k + 1
xsig.capac = x.capac - (cand.i * pesos[xsig.k])
fin
20
La Mochila 1 – Sin Repetición (4)
func esPrometedor(cand: Candidatos; x, xsig: Etapa) dev (b: Logico)
alg
b := (xsig.capac >= 0)
fin
proc btOptimo(x: Etapa)
proc anotaSolucion(cand:Candidatos; ent/sal x, xsig: Etapa)
alg
sol.s[xsig.k] := cand.i
sol.valor := sol.valor + (cand.i * valores[xsig.k])
fin
proc cancelaAnotacion(cand: Candidatos; ent/sal x, xsig : Etapa)
alg
sol.valor := sol.valor – (cand.i * valores[xsig.k])
fin
var
xsig: Etapa
cand: Candidatos
alg
si esSolucion(x):
si esMejor():
actualizaSolucion()
fsi
fsi
cand := calculaCandidatos(x)
mientras quedanCandidatos(cand)
xsig := seleccionaCandidato(cand, x)
si esPrometedor(cand, x, xsig):
anotaSolucion(cand, x, xsig)
btOptimo(xsig)
cancelaAnotacion(cand, x, xsig)
fsi
fmientras
fin
21
Descargar