Vous êtes sur la page 1sur 19

// Declaraciones en el archivo .

h
const int INF = 1000000;
int cn; //cantidad de nodos
vector< vector<int> > ady; //matriz de adyacencia

// Devuelve la matriz de adyacencia del arbol minimo.


vector< vector<int> > Grafo :: prim(){
// uso una copia de ady porque necesito eliminar columnas
vector< vector<int> > adyacencia = this->ady;
vector< vector<int> > arbol(cn);
vector<int> markedLines;
vector<int> :: iterator itVec;

// Inicializo las distancias del arbol en INF.


for(int i = 0; i < cn; i++)
arbol[i] = vector<int> (cn, INF);

int padre = 0;
int hijo = 0;
while(markedLines.size() + 1 < cn){
padre = hijo;
// Marco la fila y elimino la columna del nodo padre.
markedLines.push_back(padre);
for(int i = 0; i < cn; i++)
adyacencia[i][padre] = INF;

// Encuentro la menor distancia entre las filas marcadas.


// El nodo padre es la linea marcada y el nodo hijo es la
columna del minimo.
int min = INF;
for(itVec = markedLines.begin(); itVec != markedLines.end();
itVec++)
for(int i = 0; i < cn; i++)
if(min > adyacencia[*itVec][i]){
min = adyacencia[*itVec][i];
padre = *itVec;
hijo = i;
}

arbol[padre][hijo] = min;
arbol[hijo][padre] = min;
}
return arbol;
}

Código en JAVA
public class Algorithms
{
public static Graph PrimsAlgorithm (Graph g, int
s)
{
int n = g.getNumberOfVertices ();
Entry[] table = new Entry [n];
for (int v = 0; v < n; ++v)
table [v] = new Entry ();
table [s].distance = 0;
PriorityQueue queue =
new BinaryHeap (g.getNumberOfEdges());
queue.enqueue (
new Association (new Int (0), g.getVertex
(s)));
while (!queue.isEmpty ())
{
Association assoc = (Association)
queue.dequeueMin();
Vertex v0 = (Vertex) assoc.getValue ();
int n0 = v0.getNumber ();
if (!table [n0].known)
{
table [n0].known = true;
Enumeration p = v0.getEmanatingEdges
();
while (p.hasMoreElements ())
{
Edge edge = (Edge) p.nextElement ();
Vertex v1 = edge.getMate (v0);
int n1 = v1.getNumber ();
Int wt = (Int) edge.getWeight ();
int d = wt.intValue ();
if (!table[n1].known &&
table[n1].distance>d)
{ table [n1].distance = d;
table [n1].predecessor = n0;
queue.enqueue (
new Association (new Int (d),
v1));
}
}
}
}
Graph result = new GraphAsLists (n);
for (int v = 0; v < n; ++v)
result.addVertex (v);
for (int v = 0; v < n; ++v)
if (v != s)
result.addEdge (v, table
[v].predecessor);
return result;
}
}

Problema de las ocho reinas

Movimientos posibles de una reina en un tablero de 4x4.

Una posible solución entre muchas en un tablero de 8x8


El problema de las ocho reinas se trata de un acertijo en el que se
colocan ocho reinas sin que se amenacen. Fue propuesto por el
ajedrecista alemán Max Bezzel en 1848. En el juego de ajedrez la reina
amenaza a aquellas fichas que se encuentren en su misma fila, columna
o diagonal. Las 8 reinas consiste en colocar sobre un tablero de ajedrez
ocho reinas sin que estas se den jaques entre ellas. Para resolver este
problema emplearemos un esquema vuelta atrás (o Backtracking).
Contenido
 [ocultar]

1 Historia
2 Planteamiento del Problema
o 2.1 Establecimiento del Algoritmo
o 2.2 Descripción del Algoritmo
3 El problema de las n Reinas
4 Soluciones al Problema de las Ocho Reinas
5 Referencias
6 Véase también
7 Enlaces externos

o 7.1 Enlaces a Soluciones

[editar]Historia

El problema fue originalmente propuesto en 1848 por el ajedrecista Max


Bezzel, y durante los años, muchos matematicos, inluyendo aGauss y
a Georg Cantor, han trabajado en este problema y lo han generalizado a
n-reinas. Las primeras soluciones fueron provistas por Franz Nauck en
1850. Nauck también se aboco a las n-reinas (en un tablero de nxn de
tamaño arbritario). En 1874, S. Günther propuso un método para hallar
las soluciones usando determinantes, y J.W.L. Glaisher redefinio su
aproximación.
Edsger Dijkstra uso este problema en 1972 para ilustrar el poder de la
llamada programación estructurada. Él publico una altamente detallada
descripción del desarrollo del algoritmo de backtracking, "depth-first".
Este acertijo apareció en el popular juego de computadora de los '90
llamado "The 7th Guest".

[editar]Planteamiento del Problema


Como cada reina puede amenazar a todas las reinas que estén en la
misma fila, cada una ha de situarse en una fila diferente. Podemos
representar las 8 reinas mediante un vector[1-8], teniendo en cuenta que
cada índice del vector representa una fila y el valor una columna. Así
cada reina estaría en la posición (i, v[i]) para i = 1-8.
Ejemplo de dos reinas amenazadas en el tablero de 4 por 4.

El vector (3,1,6,2,8,6,4,7) significa que la reina 1 esta en la columna 3,


fila1; la reina 2 en la columna 1, fila 2; la reina 3 en la columna 6, fila 3; la
reina 4 en la columna 2, fila 4; etc... Como se puede apreciar esta
solución es incorrecta ya que estarían la reina 3 y la 6 en la misma
columna. Por tanto el vector correspondería a una permutación de los
ocho primeros números enteros.
El problema de las filas y columnas lo tenemos cubierto, ¿pero qué
ocurre con las diagonales? Para las posiciones sobre una misma
diagonal descendente se cumple que tienen el mismo valor fila − columna,
mientras que para las posiciones en la misma diagonal ascendente se
cumple que tienen el mismo valor fila + columna. Así, si tenemos dos
reinas colocadas en posiciones (i,j) y (k,l) entonces están en la misma
diagonal si y solo si cumple:
i − j = k − l o i + j = k + l
j − l = i − k o j − l = k − i
Con todas las consideraciones tenidas en cuenta podemos aplicar el
esquema de vuelta atrás para implementar las ocho reinas de una
manera realmente eficiente. Para ello, reformulamos el problema como
un problema de búsqueda en un árbol. Decimos que en un vector   
de enteros entre 1 y 8 es k-prometedor, para   , si ninguna de
las k reinas colocadas en las posiciones   
amenaza a ninguna de las otras. Las soluciones a nuestro problema se
corresponden con aquellos vectores que son 8-prometedores.
[editar]Establecimiento del Algoritmo
Sea N el conjunto de vectores de k-prometedores,  ,
sea   el grafo dirigido tal que   si y solo si existe
un entero k, con   tal que

 U es k-prometedor
 V es (k + 1)-prometedor
 Ui = Vi para todo 

Este grafo es un árbol. Su raíz es el vector vacío correspondiente a k = 0.


sus hojas son o bien soluciones (k = 8), o posiciones sin salida (k < 8).
Las soluciones del problema de las ocho reinas se pueden obtener
explorando este árbol. Sin embargo no generamos explícitamente el
árbol para explorarlo después. Los nodos se van generando y
abandonando en el transcurso de la exploración mediante un recorrido
en profundidad.

Esquema reducido del árbol de soluciones.

Hay que decidir si un vector es k-prometedor, sabiendo que es una


extensión de un vector (k − 1)-prometedor, únicamente necesitamos
comprobar la última reina que haya que añadir. Este se puede acelerar si
asociamos a cada nodo prometedor el conjunto de columnas, el de
diagonales positivas (a 45 grados) y el de diagonales negativas (a 135
grados) controlados por las reinas que ya están puestas.
[editar]Descripción del Algoritmo
A continuación se muestra el algoritmo que arroja la solución de nuestro
problema, en el cual   es un vector global. Para imprimir todas las
soluciones, la llamada inicial es  .

procedimiento 
//  es k-prometedor//
// //
//

//
//

//
si   entonces //un vector 8-
prometedor es una solución//
escribir 
si no //explorar las extensiones (k + 1)-
prometedoras de sol//
para   hasta   hacer
si   y   
y   entonces
//  es (k + 1)-
prometedor//

El algoritmo comprueba primero si k = 8, si esto es cierto resulta que


tenemos ante nosotros un vector 8-prometedor, lo cual indica que
cumple todas las restricciones originando una solución. Si k es
distinto de 8, el algoritmo explora las extensiones (k + 1)-
prometedoras, para ello realiza un bucle, el cual va de 1 a 8, debido
al número de reinas. En este bucle se comprueba si entran en jaque
las reinas colocadas en el tablero, si no entran en jaque, se realiza
una recurrencia en la cual incrementamos k (buscamos (k + 1)-
prometedor) y añadimos la nueva fila, columna y diagonales al
conjunto de restricciones. Al realizar la recurrencia hemos añadido al
vector sol una nueva reina la cual no entra en jaque con ninguna de
las anteriores, además hemos incrementado el conjunto de
restricciones añadiendo una nueva fila, columna y diagonales (una
positiva y otra negativa) prohibidas.

[editar]El problema de las n Reinas


El problema de las 8 Reinas es generalizado por el problema de
las n Reinas. El problema consiste en colocar n Reinas en un tablero
de ajedrez de   de tal manera que ninguna de las Reinas quede
atacando a otra.
Su análisis y solución es isomorfo al de las 8 Reinas.

[editar]Soluciones al Problema de las Ocho


Reinas
El problema de las ocho reinas tiene 92 soluciones, de las cuales 12
son esencialmente distintas, es decir las 92 soluciones existentes se pueden
obtener a partir de simetrías, rotaciones y traslaciones de las 12 soluciones únicas,
que se muestran a continuación:

Solución única 1 Solución única 2 Solución única 3

Solución única 4 Solución única 5 Solución única 6


Solución única 7 Solución única 8 Solución única 9

Solución única 10 Solución única 11 Solución única 12

Codigo en java
tablero = new Array(
new Array(),
new Array(),
new Array(),
new Array(),
new Array(),
new Array(),
new Array(),
new Array()
);

restricciones = new Array();


var cosa = new Array();
var solucion = 0;
var limite = 0;
var reinas = 0;
for (i=0; i<8; i++) {
for (k=0; k<8; k++) {
tablero[i][k] = 0;
}
restricciones[i] = -1;
cosa[i] = "";
}
for (i=0; i<8; i++) {
for (k=0; k<8; k++) {
if (restricciones[i]<="0)" tablero[y]
[x]--;="" y++;="" x="" style="padding-top: 0em; padding-
right: 0em; padding-bottom: 0em; padding-left: 0em;
margin-top: 0em; margin-right: 0em; margin-bottom: 0em;
margin-left: 0em; ">=0; x--) {
if (tablero[y][x]<=0) {
tablero[y][x]--;
}
y--;
}
y = i;
for (x=k; x>=0; x--) {
if (tablero[y][x]<=0) {
tablero[y][x]--;
}
y++;
}
y = i;
for (x=k; x<8; x++) {
if (tablero[y][x]<=0) {
tablero[y][x]--;
}
y--;
}
break;
} else if (k == 7) {
restricciones[i] = -1;
i--;

for (k=0; k<8; k++) {


if (tablero[i][k]>0) {
for (x=0; x<8; x++) {
if (x != k) {
tablero[i][x]
++;
}
if (x != i) {
tablero[x][k]
++;
}
}
y = i;
for (x=k; x<8; x++) {
if (tablero[y]
[x]<0) {
tablero[y][x]
++;
}
y++;
}
y = i;
for (x=k; x>=0; x--) {
if (tablero[y]
[x]<0) {
tablero[y][x]
++;
}
y--;
}
y = i;
for (x=k; x>=0; x--) {
if (tablero[y]
[x]<0) {
tablero[y][x]
++;
}
y++;
}
y = i;
for (x=k; x<8; x++) {
if (tablero[y]
[x]<0) {
tablero[y][x]
++;
}
y--;
}
tablero[i][k] = 0;
restricciones[i] = k;
}
}
k = -1;
}
}
}

Other code
import java.util.*;

public class Hanoi {


public static void main(String args[]){
int n;
Scanner sc=new Scanner(System.in);

System.out.print("Escriba el número de discos en la torre de hanoi: ");


n=sc.nextInt();
while(n<0){
System.out.print("Error, reescriba el número de discos en la torre:
");
n=sc.nextInt();
}

algoritmoHanoi(n,"Primera Torre","Segunda Torre","Tercera Torre");


}

public static void algoritmoHanoi(int n, String from, String temp, String to) {
if (n == 0) return;
algoritmoHanoi(n-1, from, to, temp);
System.out.println("Mover disco " + n + " de " + from + " a " + to);
algoritmoHanoi(n-1, temp, from, to);
}

Código Fuente torres hanoi :

import java.awt.*;

import java.applet.*;

public class Hanoi extends Applet

static final int XDOTS = 400;

static final int YDOTS = 200;

static final int NULL = -1;

static final int MAX = 20;

static final int MIN = 3;

static final int MAXCOLS = 6;

static final int MINCOLS = 3;

static final Color cfondo=new Color(228,233,243);

static final Color cbarra=Color.black;


static final Color cfin =Color.red;

static final Color ctorre=Color.blue;

boolean first=true;

int origen,destino;

int movimientos;

int h[] = new int[MAXCOLS];

int Ficha[][] = new int[MAXCOLS][MAX];

int Centorr[] = new int[MAXCOLS];

Button B[] = new Button[MAXCOLS];

TextField TFTorres, TFCols, TFMovimientos;

int numtorres=5, numcols=3;

void Parametros()

String param;

param = getParameter("TORRES");

if (param != null) numtorres = Integer.parseInt(param);

param = getParameter("COLS");

if (param != null) numcols = Integer.parseInt(param);

public void init()

int i;

setBackground(cfondo);

resize(XDOTS,YDOTS);

if (first)

Parametros();

Herramientas();

first=false;
}

for (i=0; i< MAXCOLS; i++)

if (i< numcols) B[i].enable();

else B[i].disable();

for (i=0; i< numcols; i++)

Centorr[i]=(XDOTS/(numcols+1))*(i+1);

h[0]=numtorres;

for (i=1; i< numcols; i++)

h[i]=0;

for (i=0; i< numtorres; i++)

Ficha[0][i]=numtorres-i;

movimientos=0;

origen=destino=NULL;

public void Herramientas()

setLayout(new BorderLayout());

Panel p= new Panel();

p.setBackground(cfondo);

for (int i=0; i< MAXCOLS; i++)

p.add(B[i]=new Button(Integer.toString(i+1));

p.add(new Button("Cancelar"));

p.add(new Button("Resolver"));

p.add(new Button("Nueva"));

add("South",p);

Panel g= new Panel();

g.setBackground(cfondo);

g.add(new Label("Columnas"));

g.add(TFCols= new TextField(Integer.toString(numcols));


g.add(new Label("Torres"));

g.add(TFTorres=new TextField(Integer.toString(numtorres));

g.add(new Label("Movimientos"));

TFMovimientos=new TextField("0",8);

TFMovimientos.disable();

g.add(TFMovimientos);

add("North",g);

public void Dibujar_Torres (Graphics g, Color coltorr)

int x,y, Long;

int l,k;

int anchomin=(Centorr[1]-Centorr[0])/numtorres;

int altotorre=(YDOTS-85)/numtorres;

g.setColor(cbarra);

for (k=0; k< numcols; k++)

g.fillRect(Centorr[k]-1, 35, 2, YDOTS-75);

g.setColor(coltorr);

for (k=0; k< numcols; k++)

for (l=0; l< h[k]; l++)

Long=anchomin*Ficha[k][l];

x=(Centorr[k]-(Long/2));

y=YDOTS-60-l*altotorre;

g.fillRect(x,y,Long,altotorre-altotorre/3);

public void paint(Graphics g)

{
Dibujar_Torres(g, ctorre);

TFMovimientos.setText(Integer.toString(movimientos));

for (int i=1; i< numcols; i++)

if (h[i]==numtorres) Final();

public void Final()

Dibujar_Torres(getGraphics(), cfin);

boolean valido(int origen, int destino)

if (origen==NULL || destino==NULL || origen==destino) return false;

if (h[origen]==0) return false;

if (h[destino]==0) return true;

if (Ficha[destino][h[destino]-1]< Ficha[origen][h[origen]-1]) return false;

return true;

public void Resolver()

Mover(numtorres,0,1,numcols-1);

void Desplazar(int origen, int destino)

h[origen]--;

Ficha[destino][h[destino]]=Ficha[origen][h[origen]];

h[destino]++;

movimientos++;

void Mover(int Numero, int Comienzo, int Auxiliar, int Final)


{

int varaux;

for (int i=Numero; i>0; i--)

Mover(i-1,Comienzo,Final,Auxiliar);

Desplazar(Comienzo,Final);

update(getGraphics());

varaux=Comienzo;

Comienzo=Auxiliar;

Auxiliar=varaux;

public boolean action(Event e, Object o)

if (e.target instanceof Button)

int i;

for (i=0 ; i< numcols; i++)

if ((Integer.toString(i+1)).equals(e.arg))

if (origen==NULL)

origen=i;

B[origen].disable();

else

destino=i;

for (i=0; i< numcols; i++)


B[i].enable();

break;

if( "Nueva".equals(e.arg) || "Resolver".equals(e.arg))

numtorres=Integer.parseInt(TFTorres.getText());

numcols =Integer.parseInt(TFCols.getText());

if (numtorres< MIN) numtorres=MIN;

else if (numtorres>MAX) numtorres=MAX;

if (numcols< MINCOLS) numcols=MINCOLS;

else if (numcols>MAXCOLS) numcols=MAXCOLS;

TFTorres.setText(Integer.toString(numtorres));

TFCols.setText(Integer.toString(numcols));

TFMovimientos.setText("0");

init();

if( "Cancelar".equals(e.arg))

origen=destino=NULL;

for (i=0; i< numcols; i++)

B[i].enable();

if( "Resolver".equals(e.arg)) Resolver();

if (valido(origen,destino))

Desplazar(origen,destino);

origen=destino=NULL;

}
repaint();

return true;

return false;

public String getAppletInfo()

return "Nombre : Torres de Hanoi\r\n" +

"Autor : Manuel Barrera \r\n" +

"e-mail : mbarrera@inf.uach.cl.\r\n";

Vous aimerez peut-être aussi