Je fais un exercice dans SML dans lequel je suis dans une grille et commence à partir de la cellule (i,j)
et je veux aller à la cellule (x,y)
. Pour simuler ceci chaque cellule est traitée comme un état (i,j,move)
où déplacer comment il est arrivé là de la cellule précédente. Puis j'ai écrit un algorithme de traversée simple (plus semblable à dfs) qui commence à chercher les états jusqu'à ce qu'il trouve celui désiré.Création d'un ORD_MAP avec Tupples comme clé dans SML
Notez que pour la fonction de traversée, j'utilise un Map-Dictionary qui prend un état en tant qu'index afin de garder une trace des états visités.
code:
val startp = (0,0)
val endp = (3,0)
val (N,M) = (4,4)
(*Define the Basic structures tht will be used*)
datatype movement = RIGHT | DOWN | LEFT | UP
type State = int * int * movement
val firstState = (#1 startp,#2 startp,UP): State
structure STATES_KEY: ORD_KEY =
struct
type ord_key = State
val compare = fn (s1:State, s2:State) =>
if (#1 s1 = #1 s2) andalso (#2 s1 = #2 s2)
then EQUAL
else if (#1 s1 > #1 s2) then GREATER
else LESS
end
structure StatesMap = SplayMapFn(STATES_KEY)
fun convert_ij id = (id div M, id mod N)
fun getNextStates ((i,j,_):State): State list =
[ (i,j+1,RIGHT),
(i+1,j,DOWN),
(i,j-1,LEFT),
(i-1,j,UP)]
fun getPrevState ((i,j,move):State): State =
case move of
RIGHT => (i,j-1,UP)
| LEFT => (i,j+1,UP)
| UP => (i+1,j,UP)
| DOWN => (i-1,j,UP)
(*True -> Invalid State*)
fun checkInvalidState ((i,j,_):State) =
if (i < 0 orelse i > N-1 orelse j < 0 orelse j > M-1)
then true
else false
fun checkEnd ((i,j,_):State) =
if (i = #1 endp andalso j = #2 endp)
then true
else false
fun traversal [] visited = visited
| traversal (h::t) visited =
if (checkEnd h) then visited
else if (checkInvalidState h) then traversal t visited
else if (StatesMap.find (visited, h) = NONE)
then
let
val [s1,s2,s3,s4] = getNextStates h
in
traversal (s1::s2::s3::s4::t) (StatesMap.insert (visited, h, h))
end
else traversal t visited
val it = traversal [firstState] StatesMap.empty
Quand je lance le programme, il est dans une boucle infinie lors de l'exécution de la fonction transversale. Il va de l'état: (1,0)->(0,0)->(0,1)->(0,2)->(0,3)->(1,3)->(2,3)->(3,3)
Et à partir de là, il continue entre États (3,3)
et (3,2)
. Aussi, j'ai vérifié la structure de carte quand la fonction de traversée est dans l'état (3,2)
et l'état (3,3)
existe dedans, signifiant qu'il ne devrait pas le regarder encore et continuer à vérifier les autres états.
Qu'est-ce qui ne fonctionne pas exactement comme je le pense et provoque cette boucle?