在smlnj中打开骑士之旅(回溯)算法

时间:2011-04-12 09:44:34

标签: algorithm sml backtracking

我必须编写SML代码来解决骑士在回溯中的旅行问题。国际象棋骑士必须遍布棋盘(大小:NxN)并且必须完全访问每个方格一次(最后不需要回到第一个方格)。

我已经编写了所有的功能来创建一个空板,在棋盘上设置或获得方块,以获得可能的骑士下一步动作列表。但我不知道如何在SML中编写递归函数(我知道如何用C编写这个算法,但不知道用SML编写)。

用于8x8棋盘的C算法

dl and dr are array : (delta to calculate next moves)   
dl = [-2,-2, -1, 1, 2,  2, 1, -1]  
dr = [-1, 1,  2, 2, 1, -1,-2, -2]


    bool backtracking(int** board, int k/*current step*/, int line, int row, int* dl, int* dr)
    {
    bool success = false;
    int way = 0;
    do{
         way++;
         int new_line = line + dl[way];
         int new_row = row + dr[way];

    if(legal_move(board, new_line, new_row))
    {
        setBoard(board,new_line, new_row,k); //write the current step number k in board
            if(k<64)
            {
                    success = backtracking(board, k+1, new_line, new_row, dl, dc);
                    if(!success)
                    {
                            setBoard(board,new_line, new_row,0);
                    }   
            }
            else
                    success = true;
    }
    }
    while(!(success || way = 8));
    return success;
    }

1 个答案:

答案 0 :(得分:1)

不要像C一样思考!这是一种讨厌的思维方式!用C /命令法编写算法永远不会有用。你需要做好功课,学会正确思考。

您将如何设计该计划?它必须存储状态,每个州必须记录骑士的去向。将您的状态设计为棋盘的元组(遍历的bool记录方块列表)和移动((int,int)列表)。因此,函数调用看起来像这样:

exception Back
fun iter (state, []) = 
      if boardFull state then state else raise Back
  | iter (state, next::ns) =
      iter (next, states next) handle Back => iter (state, ns)

fun states (board, ps) =
    <a move is a pair (int, int); write out the list of eight moves; map a next fn down the list, and filter it by legal moves> (2 or 3 lines of code for you to write)
fun boardFull (board, pos::ps) = <foldl twice to apply the 'and' fn over the whole board> (1 line of code for you to write)