Professional Documents
Culture Documents
Programacin III
Prcticas obligatorias
Realizado por: Alfonso Martn Murillo DNI: 11.820.406-Q e-mail: alfonsomartinmurillo@gmail.com Centro Asociado: Las Tablas Telfono mvil: 601058048
INDICE
Introduccin
___________________________________________________________
3
Entorno
de
desarrollo,
trabajo
y
ejecucin
___________________________________
3
Contenido
del
ZIP
y
ejecucin
de
la
aplicacin
________________________________
3
Respuesta
a
las
cuestiones
planteadas
en
el
enunciado
de
la
prctica
____________
4
Descripcin
del
algoritmo
utilizado
y
aplicacin
en
el
problema
_____________________
4
Representacin
de
los
datos
del
problema
____________________________________________
4
Recorrido
en
profundidad,
recorrido
en
anchura
y
vuelta
atrs
____________________________
6
Estructuras
de
Datos
______________________________________________________________
7
Particularizar
el
esquema
de
vuelta
atrs
_____________________________________________
8
Coste computacional de la prctica ____________________________________________ 9 Anlisis de alternativas al esquema utilizado ____________________________________ 9 Datos de prueba utilizados y resultados obtenidos _______________________________ 11
Pgina 2 de 2
Ejecucin del programa Para ejecutar el programa se deben de seguir los siguientes pasos: 1. Acceder al terminal (UNIX o MAC) o consola (Windows). Situarse en el directorio raiz generado por el proceso de descompresin del fichero ZIP. 2. Ejecutar desde la lnea de comandos la sentencia JAVA JAR SaltoCaballo.jar estableciendo los parmetros establecidos en el enunciado de la prctica. A continuacin se establecen a modo de ejemplo unas cuantas ejecuciones que ilustran el tratamiento de los parmetros: Java jar SaltoCaballo.jar n 6 Java jar SaltoCaballo.jar n 6 x 2 y 2 Java jar SaltoCaballo.jar n 6 -t Ejecucin del programa para un tablero de 6x6 con las coordenadas de inicio por defecto (x=1, y=1) Ejecucin del programa para un tablero de 6x6 estableciendo las coordenadas de inicio (x=2, y=2). Ejecucin del programa para un tablero de 6x6 invocando al modo traza, que va mostrando los diferentes estados por los que va pasando el tablero en su bsqueda de la solucin. Ejecucin del programa para un tablero de 6x6 y la obtencin de todas las soluciones existentes desde las coordenadas de partida. (No solicitado). Para la realizacin de pruebas se ha implementado el parmetro f, no obligatorio, y Pgina 3 de 3
Exploracin de grafos
Representacin de los datos del problema Analizando el problema podemos identificar los siguientes componentes: Un tablero. Representado como una matriz cuadrada de N filas y N columnas. Una posicin de inicio. Unas coordenadas x e y de las cuales parte nuestro caballo. Un conjunto de posibles movimientos o desplazamientos que puede hacer el caballo. Un camino o ruta. El recorrido que realiza el caballo en su bsqueda para recorrer todas las casillas del tablero.
La estructura que mas fielmente nos puede representar los caminos posibles o imposibles que realiza el caballo desde una posicin de partida es un rbol. El nodo inicial correspondera a la situacin de partida (Tablero, posicin inicial, longitud actual del camino). Cada nodo tiene tantos hijos como posibles movimientos pueda hacer el caballo en el tablero. Para ilustrar la estructura de rbol vamos a analizar un ejemplo sobre un tablero de 5x5 basado en una situacin en la cual el caballo comienza en las coordenadas 1,1. Inicialmente la situacin del tablero es que est ocupada la posicin 1,1. Podramos decir que tenemos una longitud de camino de 1.
Pgina 4 de 4
una vez analizadas las posibles posiciones a las que puede saltar el caballo nos encontraramos con 2 hijos:
Es decir, existen dos posibles alternativas para obtener un camino de longitud 2. A su vez cada una de estas alternativas generan nuevos hijos y nuevos caminos alternativos. Primera posibilidad de camino de longitud 3
El rbol entero desplegado nos ofrecera la visin de todos los caminos posibles existentes. Llegados a este punto tomamos nuestra primera decisin, utilizar algoritmos de exploracin de grafos.
Pgina 5 de 5
Pgina 6 de 6
El nmero obtenido correspondera al caso peor, ya que no siempre todas las posiciones son correctas, como hemos podido comprobar en el ejemplo partiendo de la posicin 1,1, donde nicamente existen 2 posiciones vlidas y no 8. Se han marcado en verde los niveles 25, 36 y 49. Estos niveles corresponderan a los que sera necesario llegar en el caso de un tablero de longitud 5, 6 y 7 respectivamente. Como podemos comprobar el nmero de posibles nodos es tan grande que no nos podemos permitir construir el rbol de forma explcita para aplicar posteriormente tcnicas de bsqueda. Nuestra estrategia va a consistir trabajar con un grafo implcito, es decir, conocemos como tienen que ser los nodos, cual es la mecnica para ir generando nodos hijos, cuando hemos obtenido una solucin, y por tanto vamos a aplicar un algoritmo de vuelta atrs. El algoritmo de vuelta atrs se justifica ya que a medida que vamos recorriendo niveles hacia abajo, si llegamos a un punto en el cual no obtenemos mas hijos, pero la longitud del camino no corresponde con el nmero de casillas del tablero, deberemos de corregir la situacin, volviendo hacia atrs en nuestro recorrido y probando un nuevo camino. Estructuras de Datos Necesitamos manejar los siguientes elementos: dimTablero. La dimensin que va a tener el tablero. Tablero[][]. Una matriz bidimensional que va a representar el tablero, con todas las posiciones, en funcin de la dimensin establecida al inicio. lCamino. La longitud del camino que est realizando el caballo en sus sucesivos movimientos. xActual. Posicin x actual del caballo. yActual. Posicin y actual del caballo. Pgina 7 de 7
Particularizar el esquema de vuelta atrs A continuacin se expone el esquema general de vuelta atrs: Fun vuelta-atrs (ensayo) Si vlido (ensayo) entonces Dev ensayo Si no Para cada hijo E compleciones (ensayo) Si condicionesdepoda (hijo) entonces vuelta-atrs (hijo) Fin para Fin si Fin Fun Un algoritmo de vuelta atrs acaba bien por haber encontrado la solucin, o bien porque no hay mas nodos hijos a explorar. En la siguiente tabla se particularizan cada uno de los componentes del esquema algortmico en relacin a nuestro problema concreto.: Componente Valido(ensayo) Particularizacin Esta funcin nos valida si hemos encontrado una solucin. En este caso si la longitud del camino recorrido es igual al cuadrado de la dimensin del tablero. Fun Valido (Ensayo) ffun Compleciones(ensayo) Esta funcin nos obtiene la lista de nodos hijos (siguientes casillas) que cumplen las reglas del juego. Fun compleciones (ensayo) Lista <- lista vaca; Para x de 0 a 7 hacer Despx=ensayo.xactual+xdesp[x] Despy=ensayo.yactual+ydesp[x] Si (despx > 0) y despx<=ensayo.dimtablero Pgina 8 de 8 Dev (ensayo.lcamino==dimtablero*dimtablero
Pgina 9 de 9
Divide y Vencers No es factible construir una solucin mediante la aplicacin a subproblemas mas pequeos.
Recorrido en profundidad Debemos de marcar todos los nodos del grafo como no visitados, por lo que debemos previamente disponer del grafo. Tal como hemos dicho, vamos a trabajar con un grafo implcito, que se va a construir a medida que se va construyendo la solucin, por lo que no podemos aplicar un algoritmo de Recorrido en Profundidad. Lo que si utilizamos es el concepto de que a la hora de recorrer el grafo primero recorremos a nivel hijo, y luego el resto de nodos adyacentes, es decir, buscamos la profundidad, ya que llegar a una solucin significa llegar al nivel mas profundo del rbol.
Pgina 10 de 10
Recorrido en Anchura En un recorrido en anchura el orden de visita es diferente. Cuando se llega a un nodo N se visitan en primer lugar todos los vecinos de N. No nos interesa aplicar este esquema algortmico, ya que nuestra solucin se basa en llegar lo antes posible al ltimo nivel (mas profundo) del rbol.
N=6
N=7
N=8
Saltocaballo5x5.sh
#SCRIPT
PARA
EJECUTAR
java
SaltoCaballo
-n
5
-x
1
-y
1
-f
5x5-1_1.txt
java
SaltoCaballo
-n
5
-x
1
-y
2
-f
5x5-1_2.txt
java
SaltoCaballo
-n
5
-x
1
-y
3
-f
5x5-1_3.txt
java
SaltoCaballo
-n
5
-x
1
-y
4
-f
5x5-1_4.txt
java
SaltoCaballo
-n
5
-x
1
-y
5
-f
5x5-1_5.txt
Pgina 12 de 12
Saltocaballo6x6.sh
#SCRIPT
PARA
EJECUTAR
java
SaltoCaballo
-n
6
-x
1
-y
1
-f
6x6-1_1.txt
java
SaltoCaballo
-n
6
-x
1
-y
2
-f
6x6-1_2.txt
java
SaltoCaballo
-n
6
-x
1
-y
3
-f
6x6-1_3.txt
java
SaltoCaballo
-n
6
-x
1
-y
4
-f
6x6-1_4.txt
Alfonso
Martn
Murillo
(alfonsomartinmurillo@gmail.com)
Pgina
13
de
13
Saltocaballo7x7.sh
Debido
al
tiempo
de
proceso
que
supone
la
ejecucin
de
cada
prueba
nicamente
se
han
generado
7
casos
de
prueba.
#SCRIPT
PARA
EJECUTAR
java
SaltoCaballo
-n
7
-x
1
-y
1
-f
7x7-1_1.txt
java
SaltoCaballo
-n
7
-x
1
-y
2
-f
7x7-1_2.txt
java
SaltoCaballo
-n
7
-x
1
-y
3
-f
7x7-1_3.txt
java
SaltoCaballo
-n
7
-x
1
-y
4
-f
7x7-1_4.txt
java
SaltoCaballo
-n
7
-x
1
-y
5
-f
7x7-1_5.txt
java
SaltoCaballo
-n
7
-x
1
-y
6
-f
7x7-1_6.txt
java
SaltoCaballo
-n
7
-x
1
-y
7
-f
7x7-1_7.txt
La
salida
de
los
diferentes
casos
de
prueba
pueden
encontrarse
en
el
directorio
OUTPUT.
Debido
a
la
cantidad
de
informacin
generada
me
ha
parecido
mas
adecuado
mantener
en
ficheros
separados
los
resultados
de
las
pruebas,
en
vez
de
incorporarlos
a
este
documento.
SaltoCaballo.JAVA
Pgina 15 de 15
//LISTA DE VARIABLES UTILIZADAS static Integer N; //Dimensin del tablero de Ajedrez. static Integer xInicio; //Posicin x inicial static Integer yInicio; //Posicin y inicial static Boolean modoTraza; //Establece si tenemos que imprimir todos los estados por los que pasa el tablero. static Boolean modoTodasSoluciones; //Establece si debemos de obtener todas las soluciones o nicamente la primera. static String nomFicheroSalida; //DE USO INTERNO PARA LA OBTENCIN DE FICHEROS DE SALIDA static int paramSalida; //Otras variables static PrintStream miConsola; //TODO Limpiar y Comentar public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException { //variables temporales //CONFIGURACIONES POR DEFECTO DE LA APLICACIN N=8; xInicio=1; yInicio=1; modoTraza=false; modoTodasSoluciones=false; nomFicheroSalida=new String("salida.txt"); paramSalida=0; //POR DEFECTO LA SALIDA ES POR CONSOLA. 0 CONSOLA 1 - FICHERO. //OBJETO FECHAHORA PARA IR GRABANDO LOS EVENTOS DE LA APLICACIN Date fechaHora=new Date(); // 1 - Evaluar que los parmetros enviados son los correctos. if (evalParametros(args)==false) { System.out.println("Los parametros suministrados no son correctos"); System.out.println("El programa finalizar su ejecucin"); System.exit(0); }
Pgina 16 de 16
//CONFIGURACIN DE CONSOLA DE SALIDA if (paramSalida==0) { miConsola=new PrintStream(System.out,true,"UTF-8"); } else { File file = new File(nomFicheroSalida); FileOutputStream fos = new FileOutputStream(file); miConsola=new PrintStream(fos,true,"UTF-8"); }
//CREACIN DE LA PARTIDA //listaSoluciones= new ArrayList<EstadoPartida>(); //COMIENZA MI PARTIDA EstadoPartida estadoInicial=new EstadoPartida(xInicio,yInicio,N,modoTraza,modoTodasSoluciones,miConsol a); miConsola.println(fechaHora.toString() + " Inicio del Proceso de generacin de soluciones: "); estadoInicial.evalPartida(); //MUESTRO UN MENSAJE EN AQUELLAS SITUACIONES EN LAS QUE NBO SE ENCUENTRE SOLUCIN if (estadoInicial.esSolucion==false) miConsola.println("No se ha encontrado un camino que satisfaga las condiciones de partida"); miConsola.println(fechaHora.toString() + " Finalizacin del Proceso de generacin de soluciones"); //FINALIZACIN DEL PROGRAMA } public static Boolean evalParametros(String[] args) { //FIXME -n 5 -x 3 y 3 no funciona. controlarlo. //FIXME -p 5 -x 3 y 3 no funciona. controlarlo.
//VARIABLES TEMPORALES int x=0; //RECORREMOS EL ARRAY DE PARMETROS Y EVALUAMOS try { //RECORRIDO DEL TOTAL DE PARMETROS INCORPORADOS while (x<args.length)
Pgina 17 de 17
{ //SI CAPTO -N LEO LA SIGUIENTE POSICIN QUE DEBE DE SER NUMRICA. EN CASO CONTRARIO SE OBTENDR UNA EXCEPCIN if (args[x].toString().toLowerCase().equals("n")) //CAPTO LA DIMENSIN DEL TABLERO QUE SER LA SIGUIENTE POSICIN { N=Integer.parseInt(args[x+1]); x++; } else { if (args[x].toString().toLowerCase().equals("-x")) //CAPTO LA X {
xInicio=Integer.parseInt(args[x+1]); x++; } else { if (args[x].toString().toLowerCase().equals("-y")) //CAPTO LA y { yInicio=Integer.parseInt(args[x+1]); x++; } else { //OBTENDO SI TRABAJO O NO EN MODO TRAZA if (args[x].toString().toLowerCase().equals("-t")) modoTraza=true; else { //OBTENGO SI DESEO TODAS LAS SOLUCIONES O NO if (args[x].toString().toLowerCase().equals("-a")) modoTodasSoluciones=true; else { if (args[x].toString().toLowerCase().equals("-f")) //CAPTO EL NOMBRE DEL FICHERO { paramSalida=1; //DESEO LA SALIDA POR FICHERO
Pgina 18 de 18
} }
} x++; } //SALIDA CORRECTA return true; } catch(Exception miExcepcion) { //SALIDA INCORRECTA return false; //ha habido algn tipo de error, por lo que debemos devolver false } }
EstadoPartida.JAVA
Pgina 19 de 19
//PROPIEDADES PBLICAS DE LA CLASE public int Tablero[][]; //MATRIZ BIDIMENSIONAL QUE REPRESENTA EL TABLERO public int lCamino;//LONGITUD DEL CAMINO. public int xActual; //POSICIN X EN LA QUE NOS ENCONTRAMOS public int yActual; //POSICIN Y EN LA QUE NOS ENCONTRAMOS public boolean modoTraza; public long numTrazas; //PARA CONOCER EL NMERO DE EVALUACIONES QUE LLEVAMOS REALIZADAS public boolean modotodasSoluciones; public int dimTablero; //INDICA LA DIMENSIN DEL TABLERO COMENZANDO POR 1 public int dimTableroidx0;//INDICA LA DIMENSIN DEL TABLERO COMENZANDO POR 0 public boolean esSolucion; //VARIABLE BOOLEANA QUE INDICA SI HEMOS OBTENIDO COMO MNIMO UNA SOLUCIN. public PrintStream miConsola; //VARIABLE QUE REPRESENTA LA CONSOLA DE SALIDA public int xDesp[]; //VECTOR QUE ALMACENA LOS POSIBLES DESPLAZAMIENTOS POR EL EJE X public int yDesp[]; //VECTOR QUE ALMACENA LOS POSIBLES DESPLAZAMIENTOS POR EL EJE Y public int numSoluciones; //VARIABLE QUE ALMACENA EL NMERO DE SOLUCIONES OBTENIDAS public int dimTableroQ2; //PARA QUE NO TENGA QUE HACER LA MULTIPLICACIN EN CADA LLAMADA RECURSIVA
//CONSTRUCTOR POR DEFECTO. public EstadoPartida() { try { initEstadoPartida(); } catch (UnsupportedEncodingException exc) { System.out.println(exc.toString()); } catch (FileNotFoundException exc) { System.out.println(exc.toString()); } } //CONSTRUCTOR DE LA CLASE DE TIPO ESTADOPARTIDA EN BASE A
Pgina 20 de 20
//Funcin que focaliza todo lo comn a los diferentes constructores public void initEstadoPartida() throws UnsupportedEncodingException, FileNotFoundException { //Funcin que focaliza todo lo comn a los diferentes constructores esSolucion=false; numSoluciones=0;
Pgina 21 de 21
} //FUNCIN PRINCIPAL DE CARACTER RECURSIVO QUE REALIZA LA BSQUEDA EN PROFUNDIDAD POR EL ARBOL public EstadoPartida evalPartida() { //VARIALBES UTILIZADAS. int x; //PARA MOVERNOS POR LOS POSIBLES 8 MOVIMIENTOS int xdesptemp; int ydesptemp; int xActualAnt; int yActualAnt;
//SI ESTOY EN MODO TRAZA SIEMPRE IMPRIMO TABLERO, INDEPENDIENTEMENTE DE QUE ME ENCUENTRE CON UNA SOLUCIN O NO if (modoTraza) { numTrazas++; miConsola.println("Traza: " + Long.toString(numTrazas)); miConsola.println("-----------------------------------------------------------------"); PintarTablero(); miConsola.println(); }
//ENCONTRAMOS UNA SOLUCIN if (lCamino==dimTableroQ2) { numSoluciones++; miConsola.println("Solucin encontrada nmero: "+ Integer.toString(numSoluciones)); //IMPRIMO EL TABLERO NICAMENTE SI NO ESTOY EN MODO TRAZA, YA QUE SI NO YA LO TENDRA EN PANTALLA if (modoTraza==false) {
Pgina 22 de 22
miConsola.println("Nmero de soluciones encontradas: "+ Integer.toString(numSoluciones)); miConsola.println("-----------------------------------------------------------------"); PintarTablero(); miConsola.println(); } esSolucion=true; } //OBTENCIN DE NUEVAS SOLUCIONES else { for (x=0;x<8;x++) { //COMPROBAR SI HAY QUE SEGUIR GENERANDO //GENERAREMOS SIEMPRE QUE, O BIEN NO HAYAMOS ENCONTRADO UNA SOLUCIN, O BIEN TENGAMOS QUE ENCONTRAR //TODAS LAS SOLUCIONES if (((modotodasSoluciones==false) && (esSolucion==true))==false) { xdesptemp=xActual+xDesp[x]; ydesptemp=yActual+yDesp[x]; //COMPROBAR QUE LA NUEVA POSICIN EST EN RANGO Y QUE ES UNA CASILLA NO VISITADA if (xdesptemp>=0) { if (xdesptemp<=dimTableroidx0) { if (ydesptemp>=0) { if (ydesptemp<=dimTableroidx0) { //COMPROBAR QUE LA CASILLA NO HA SIDO VISITADA AN if (Tablero[xdesptemp][ydesptemp]==0) { //TENGO UNA CASILLA VLIDA //ACTUALIZO TABLERO Y BAJO EN PROFUNDIDAD xActualAnt=xActual; yActualAnt=yActual;
Pgina 23 de 23
} //CIERRE IF } //CIERRE IF } //CIERRE IF } //CIERRE IF } //CIERRE IF } //CIERRE IF } //CIERRE FOR } //CIERRE ELSE return this; } //CIERRE FUNCIN //FUNCIN QUE PINTA EL TABLERO EN PANTALLA public void PintarTablero() { //VARIABLES TEMPORALES int x,y; for (y=dimTableroidx0;y>=0;y--) ////lo recorro al revs para representar que el eje X crece de abajo a arriba y no de arriba a abajo { for (x=0;x<dimTablero;x++) { if (Tablero[x][y]>9)
Pgina 24 de 24
{ miConsola.print(Integer.toString(Tablero[x][y])); } else { miConsola.print(" " + Integer.toString(Tablero[x][y])); } if (y!=dimTablero) { miConsola.print("\t"); } } miConsola.println(); //SALTO DE LINEA } }
Pgina 25 de 25