268
TÉCNICAS DE DISEÑO DE ALGORITMOS
La segunda corresponde a la suma de las distancias de Manhattan de la posición de cada pieza a su casilla final, y que hace uso de una función que calcula el valor absoluto de la diferencia de dos números naturales: PROCEDURE ValAbs(a,b:CARDINAL):CARDINAL; (* valor absoluto de la diferencia de sus argumentos: |a-b| *) BEGIN IF a>b THEN RETURN a-b ELSE RETURN b-a END; END ValAbs; PROCEDURE h2(n:nodo):CARDINAL; (* calcula la suma de las distancias de Manhattan *) VAR i,j,x,y,cuenta:CARDINAL; BEGIN cuenta:=0; FOR i:=1 TO dim DO FOR j:=1 TO dim DO IF n^.p[i,j] = 0 THEN x:=dim; y:=dim ELSE x:=((n^.p[i,j]-1) DIV dim)+1; y:=((n^.p[i,j]-1) MOD dim)+1; END; cuenta:=cuenta+ValAbs(x,i)+ValAbs(y,j); END END; RETURN cuenta; END h2;
También es preciso implementar una función para determinar cuándo un nodo es solución. En nuestro caso consiste en decidir cuándo un tablero coincide con la disposición final del juego y para esto es suficiente comprobar que su función de coste vale cero (cualquiera de las dos funciones vistas): PROCEDURE EsSolucion(n:nodo):BOOLEAN; BEGIN RETURN h(n)=0; END EsSolucion;
También es necesario implementar la función NoHaySolucion, que devuelve un valor especial para indicar que el problema no admite solución: PROCEDURE NoHaySolucion():nodo; BEGIN RETURN NIL; END NoHaySolucion;