You are on page 1of 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 Date: 2010-07-29

METODOLOGIA

~3~

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 oc upan 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(); /*recorre mos 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: d disponibles(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(ocu p) 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 Date 2010-07-30

METODOLOGIA

~7~

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

You might also like