我目前正在研究递归回溯这个美丽的话题。我已经尝试过经典的例子,比如找到迷宫中的最短路径,或者 n-queens 问题。但是我现在正在处理的问题确实让我感到困惑:实际上,我认为解决一个简单的拼图游戏可能是一个简单的练习:我有一块大小为 n = a * b 的板,正好有这么多( n) 件。
最后,我想让所有的棋子按照一定的顺序放在板上,它们遵守一定的限制(比如匹配他们的邻居)。相当容易,我想,我想出了以下算法:
public board recursiveSolve(Board board, Piece[] pieces, int position){
// base case
if(position == board.getLength())
return board;
else{
// For each possible piece
for(int i = 0; i < pieces.length; i++){
// if the piece is placeable at that position
// place it and search on recursively
if(board.isValid(piece[i], position)){
board.putPiece(pieces[i], position);
// THIS IS THE FISHY PART!!
// Now I need to pass a set of pieces to the function recursively
// that does not contain the current one (pieces[i])
// But I fear my (following) approach is too heap-intensive
Piece[] subPieces = new Piece[pieces.length - 1];
// fill subPieces with all elements from pieces except from the one
// at position i
for (int j = 0; j < subPieces.length; j++) {
if(j >= i)
subPieces[j] = pieces[j+1];
else
subPieces[j] = pieces[j];
}
if(recursiveSolve(board, subPieces, position + 1) != null)
return board;
else
board.removePiece(position);
}
}
// If this is reached, none of the pieces have worked -> go back
return null;
}
基本上,这个算法做了它应该做的——但不幸的是它只适用于“小”板尺寸(n < 100)。因为如果我有一个像 10 x 10 正方形和 100 块的板,那么函数搜索和搜索直到 JVM 由于堆空间不足而崩溃时才结束。我什至尝试将 eclipse 的内存大小限制设置为 1.2g,这使得函数工作时间更长,但仍然不够。
所以我的问题是:是否可以优化上述算法以使其适用于 n > 100 的电路板尺寸?我究竟做错了什么?还是我采取了完全错误的方法?
非常感谢您提前提供的帮助。