Algoritmo 8 Reinas IV

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 8

ALGORITMO

8 REINAS METODOLOGIA ~1~

ALGORITMO 8 REINAS

Sabiendo el movimiento de la pieza de la reina en un tablero de ajedrez encontrar las posiciones de 8


reinas en el mismo tablero para que ninguna pueda comer a las otras 7 y por tanto tampoco ser comida.
(Investigando un poco encuentro que para este problema clsico hay 92 soluciones)

Primera valoracin del ejercicio

No se puede repetir fila ni columna

No se puede repetir diagonal

En cada fila solo 1 reina

En cada columna slo 1 reina

Marcar filas y columnas ocupadas

El algoritmo se podra definir con dos lneas como.

Probar a colocar la reina de la fila i-sima en cada una de las posiciones disponibles.

Colocar las reinas restantes operando de modo recursivo.


ALGORITMO
8 REINAS METODOLOGIA ~2~

Estado Inicial

Las reinas que hay

Estado final

Las posiciones que quedan libres

Procesamiento

Colocar ficha en lugar permitido y no ocupado

ENT Columnas ocupadas por vacas anteriores

SALIDA Columnas disponibles

Creacin del pseudocdigo

Disponibles(ocup). //recibe un vector o una lista con

d=[0,1,2,3,4,5,6,7]

k= tamao(ocup)

Para cada c en ocup:

Eliminar c de d

Eliminar (c+k) de d

Eliminar (c-k) de d

K--

devolver d

caso concreto

ocup=[3 5 0 4]

k=4 3 2 1

d=[0 1 2 3 4 5 6 7]
ALGORITMO
8 REINAS METODOLOGIA ~3~
Date: 2010-07-29

IMPLEMENTACIN ALGORITMO 8 REINAS EN JAVA

Implementamos el mtodo disponibles y comprobamos si funciona para un caso concreto.

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/** * @author nessy* */
public class OchoReinas {
//PSEUDOCODIGO
// Disponibles(ocup). //recibe un vector o una lista con
// d=[0,1,2,3,4,5,6,7]
// k= tamao(ocup)
// Para cada c en ocup:
// Eliminar c de d
// Eliminar (c+k) de d
// Eliminar (c-k) de d
// K - -
// devolver d
/**Este mtodo sirve para determinar las columnas en las que
* se puede colocar la siguiente reina, habindose puesto ya algunas
* reinas cuyas columnas se dan
* @param ocup Columnas que ocupan las reinas previas
* @return Columnas disponibles sin comerse */
public static List<Integer> disponibles(List<Integer>ocup){
//creamos la lista de disponibles que inicialmente tiene todas las
columnas
// d=[0,1,2,3,4,5,6,7]
List<Integer> d= new LinkedList<Integer>();//podra haber utilizado un
ArrayList
for(int i=0;i<8;i++){
d.add(new Integer(i));
}
//averiguamos cuntas reinas hay ya colocadas y lo guardamos en la
variable k
// k= tamao(ocup)
int k=ocup.size();
/*recorremos la lista de columnas ocupadas para ir tachando los lugares
que
* no nos vale. Podriamos hacerlo con un for, pero para listas mejor el
Iterator*/
//Para cada c en ocup:
// Eliminar c de d
// Eliminar (c+k) de d
// Eliminar (c-k) de d
// K - -
for (Iterator<Integer> j=ocup.iterator();j.hasNext();k--){
Integer c=j.next();
//trabajamos con objetos que contienen nmeros enteros por eso uso
el remove
d.remove(c);
d.remove(new Integer(c.intValue()+k));
d.remove(new Integer(c.intValue()-k));
}
//finalmente devolvemos lo que nos queda
//devolver d
return d;
}
ALGORITMO
8 REINAS METODOLOGIA ~4~
public static void main(String[] args) {
/* Creo un ejemplo para ver si la funcion disponibles funciona bien*/
/* Creamos la lista de prueba*/
LinkedList<Integer> a = new LinkedList<Integer>();
a.add(new Integer(3));
a.add(new Integer(5));
/* Creo otra lista para guardar lo que devuelve el mtodo disponibles*/
List<Integer> z = disponibles(a);
for (Iterator<Integer> j=z.iterator();j.hasNext();){
System.out.println(j.next().intValue());
}
}
}

ALGORITMO RESOLVER

MEJORA. Pseudocdigo del mtodo resolver que nos va a mostrar las 92 soluciones posibles de colocar las 8
reinas.

resolver(ocup):
si tamao(ocup)<8:
ddisponibles(ocup)
para cada c en d:
resolver(ocup+c)
en caso contrario:
mostrar solucin
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/** * @author nessy* */
public class OchoReinas {
static int cont=0;//para contar el nmero de soluciones del mtodo resolver
//PSEUDOCODIGO
// Disponibles(ocup). //recibe un vector o una lista con
// d=[0,1,2,3,4,5,6,7]
// k= tamao(ocup)
// Para cada c en ocup:
// Eliminar c de d
// Eliminar (c+k) de d
// Eliminar (c-k) de d
// K - -
// devolver d
/**Este mtodo sirve para determinar las columnas en las que
* se puede colocar la siguiente reina, habindose puesto ya algunas
* reinas cuyas columnas se dan
* @param ocup Columnas que ocupan las reinas previas
* @return Columnas disponibles sin comerse */
public static List<Integer> disponibles(List<Integer>ocup){
//creamos la lista de disponibles que inicialmente tiene todas las
columnas
// d=[0,1,2,3,4,5,6,7]
List<Integer> d= new LinkedList<Integer>();//podra haber utilizado un
ArrayList
for(int i=0;i<8;i++){
d.add(new Integer(i));
}
//averiguamos cuntas reinas hay ya colocadas y lo guardamos en la
variable k
ALGORITMO
8 REINAS METODOLOGIA ~5~
// k= tamao(ocup)
int k=ocup.size();
/*recorremos la lista de columnas ocupadas para ir tachando los lugares
que
* no nos vale. Podriamos hacerlo con un for, pero para listas mejor el
Iterator*/
//Para cada c en ocup:
// Eliminar c de d
// Eliminar (c+k) de d
// Eliminar (c-k) de d
// K - -
for (Iterator<Integer> j=ocup.iterator();j.hasNext();k--){
Integer c=j.next();
//trabajamos con objetos que contienen nmeros enteros por eso uso
el remove
d.remove(c);
d.remove(new Integer(c.intValue()+k));
d.remove(new Integer(c.intValue()-k));
}
//finalmente devolvemos lo que nos queda
//devolver d
return d;
}
// resolver(ocup):
// si tamao(ocup)<8:
// d=disponibles(ocup)
// para cada c en d:
// resolver(ocup+c)
// en caso contrario:
// mostrar solucin
/** Encuentra todas las soluciones para el problema de las 8 reinas
* @param ocup Lista con las ocupaciones previas, siendo su valor inicial una
lista vaca
* resolver(ocup):
* si tamao(ocup)<8:
* d=disponibles(ocup)
* para cada c en d:
* resolver(ocup+c)
* en caso contrario:
* mostrar solucin
*/
public static void resolver(List<Integer> ocup){
// si tenemos ya 8 reinas ubicadas, es que encontramos una solucin, si
no, hay que iterar recursivamente
if (ocup.size()<8){
// d=disponibles(ocup)
List<Integer> d = disponibles(ocup);
// para cada c en d:
for (Iterator<Integer> c=d.iterator();c.hasNext();){
//resolver(ocup+c) Aqu tengo que crear una lista provisional
List<Integer> provisional = new LinkedList<Integer>(ocup);
provisional.add(c.next());
resolver(provisional);
}
}else{
//mostramos la solucin por pantalla como una linea
String solucion="";
for (Iterator<Integer> j=ocup.iterator();j.hasNext();){
solucion += j.next().intValue();
}
cont++;
ALGORITMO
8 REINAS METODOLOGIA ~6~
System.out.println("Solucion " + cont+" "+solucion + " ");
}
}

public static void main(String[] args) {


//1 OPCION con el mtodo disponibles
/* Creo un ejemplo para ver si la funcion disponibles funciona bien*/
/* Creamos la lista de prueba*/
LinkedList<Integer> a = new LinkedList<Integer>();
a.add(new Integer(3));
a.add(new Integer(5));
/* Creo otra lista para guardar lo que devuelve el mtodo disponibles*/
List<Integer> z = disponibles(a);
for (Iterator<Integer> j=z.iterator();j.hasNext();){
System.out.println(j.next().intValue());
}
// 2 OPCION con el algoritmo resolver
LinkedList<Integer> b = new LinkedList<Integer>();
System.out.println("La solucn con el mtodo resolver es: ");
resolver(b);
}
}
ALGORITMO
8 REINAS METODOLOGIA ~7~
Date 2010-07-30

MEJORA. Mostrar la salida del programa de forma que muestre simblicamente el tablero poniendo en los
huecos un punto y donde hay una reina un asterisco.

Para ello crearemos el mtodo pintaTablero( ).

El pseudocdigo sera.

para i=0 hasta 7


fila=
r= elemento i de reinas // en java seria int r=reinas.get(i).intValue();
para j=0 hasta 7
si (j = = r): fila +=*
en caso contrario: fila +=.
imprimir fila

El mtodo pintaTablero tiene esta pinta:

public static void pintaTablero(List<Integer>reinas){


for (int i=0;i<8;i++){
String fila="";
int r=reinas.get(i).intValue();
for(int j=0;j<8;j++){
if (j == r){
fila +='*';
}else{
fila +='';
}
}
System.out.println(fila);
}

Para comprobar su funcionamiento:

1 Opcin: Creo un ejemplo con una solucin posible y luego se la envo al mtodo pintaTablero para que la
muestre

Para ello en el main incluyo:

//MEJORA. Visualizar el resultado en un tablero


//Aqui creo "a mano" un caso concreto y luego lo pinto con
//el mtodo pintaTablero
LinkedList<Integer> p = new LinkedList<Integer>();
p.add(new Integer(0));
p.add(new Integer(4));
p.add(new Integer(7));
p.add(new Integer(5));
p.add(new Integer(2));
p.add(new Integer(6));
p.add(new Integer(1));
p.add(new Integer(3));
pintaTablero(p);
ALGORITMO
8 REINAS METODOLOGIA ~8~
2 opcin. Que pinte el tablero justo despus de obtener cada opcin posible

Para ello en el mtodo Resolver hacemos una llamada al mtodo pintarTablero, quedando el mtodo:

public static void resolver(List<Integer> ocup){


// si tenemos ya 8 reinas ubicadas, es que encontramos una solucin, si
no, hay que iterar recursivamente
if (ocup.size()<8){
// d=disponibles(ocup)
List<Integer> d = disponibles(ocup);
// para cada c en d:
for (Iterator<Integer> c=d.iterator();c.hasNext();){
//resolver(ocup+c) Aqu tengo que crear una lista provisional
List<Integer> provisional = new LinkedList<Integer>(ocup);
provisional.add(c.next());
resolver(provisional);
}
}else{
//mostramos la solucin por pantalla como una linea
String solucion="";
for (Iterator<Integer> j=ocup.iterator();j.hasNext();){
solucion += j.next().intValue();
}
cont++;
System.out.println("Solucion " + cont+" "+solucion + " ");
pintaTablero(ocup);// con esta lnea "pinta" todos los tableros
posibles
}
}

Para mostrar solo la primera posibilidad posible que devuelve el mtodo resolver

De momento esto queda pendiente

También podría gustarte