Está en la página 1de 11

8-PUZZLE APLICANDO

ALGORITMO A*
Algoritmo A*
• Al momento de seleccionar un nodo a expandir, A* elige aquel
que promete arribara una mejor solución. ( ya explorado )
N
( sin explorar )

Nodo

• Para cada nodo N en la frontera, A* conoce: inicial Meta

h( N )
ƒ el costo del camino usado para alcanzar N: g(N)
ƒ la estimac. del costo del camino desde N hasta una meta:
h(N).
g = es el nivel del árbol O llamadas de recursividad

h = es comparar las 2 matrices la actual con la que se quiere


llegar

Entonces f(N)= g(N)+h(N) es una estimación del costo total de


un camino a la meta (i.e., de una solución) que pasa por N. • A*
selecciona el nodo que tenga menor valor asociado por f. 51
• Al efectuar búsqueda A* puede efectuarse control de ciclos por
razones de eficiencia, podando aquellas ramas del árbol
correspondientes a estados ya generados previamente.
• No obstante, un mismo estado E puede pertenecer a distintos caminos,
con distintos costos.
• Por lo tanto, si un estado es generado nuevamente, pero sobre un
mejor camino, vale la pena volver a considerarlo.
Generación repetida de un nodo
• Si existe en Front un nodo N etiquetado con un estado E, y generamos E por un mejor
camino que el representado por N, entonces reemplazamos N en Front por un nodo N’
para E con este nuevo camino.
• Si existe en Vis un nodo N etiquetado con un estado E, y generamos E por un mejor
camino, entonces N es eliminado de Vis y se agrega a Front un nuevo nodo N’ para E
con este nuevo camino.
• De esta forma, E podrá ser ser reconsiderado en el futuro.
#include <iostream>
using namespace std;
int dx[] = { 1,0,-1,0 };
int dy[] = { 0,1,0,-1 };
bool validarCamino(int x, int y){
return x >= 0 && y >= 0 && x < 3 && y < 3;
}
void intercambiarCasilla(int matrizActual[][3], int x1, int x2, int y1, int y2){
int tmp = matrizActual[x1][y1];
matrizActual[x1][y1] = matrizActual[x2][y2]; matrizActual[x2][y2] = tmp;}
int calcularH(int matrizActual[][3], int matrizFinal[][3]){ int
restantes = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++)
{ if (matriz Actual[i][j] != matrizFinal[i][j])
restantes++; }
}
return restantes;

} void mostrarMatriz(int matrizActual[][3]){


for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (!matrizActual[i][j]) cout << "X ";
else cout << matrizActual[i][j] << " ";
}
cout << "\n";
}
cout << "\n";
}
void algoritmoA(int matrizActual[][3], int matrizFinal[][3], int x, int y, int nivel, int &f)
{
//cout << "Nivel: " << nivel << "\n";
int h = calcularH(matrizActual, matrizFinal);
//cout << "h: " << h << "\n"; int g = nivel; //mostrarMatriz(matrizActual);
if (nivel == 9) return;
if (h == 0) {
if (f > h + g) {
f = h + g;
cout << "Encontre un camino optimo con f = g(" << g << ") + (" << h << ") = " << f << "\n";
mostrarMatriz(matrizActual);
} return;
}
for (int i = 0; i < 4; i++) {
int nx = dx[i] + x; int ny = dy[i] + y;
if (validarCamino(nx, ny))
{ intercambiarCasilla(matrizActual, x, nx, y, ny);
algoritmoA(matrizActual, matrizFinal, nx, ny, nivel + 1, f); intercambiarCasilla(matrizActual,
nx, x, ny, y); }
}
}
int main(){
int matrizInicio[3][3] = { {2, 8, 3} ,{1, 6, 4},{7, 0, 5} };
int matrizFinal[3][3] = { {1, 2, 3} ,{8, 0, 4},{7, 6, 5} };
int x, y;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (matrizInicio[i][j] == 0) {
x = i; y = j;
break; }
}
}
//Funcion F = G + H int f = 100;
algoritmoA(matrizInicio, matrizFinal, x, y, 0, f);
cout << "camino optimo: " << f << " niveles\n";
return 0;}

También podría gustarte