我正在试图弄清楚如何提高此算法的速度。它适用于两个游戏(2人游戏,CPU与人类游戏),但问题是当我分配超过三个堆(包含多个宝石,因此每个玩家可以拿起多个游戏),计算机播放器需要永远来计算动作:
public Object[] minimax(int depth, int player) {
if(hasPlayer1Won(player)){
return new Object[]{get_default_input(1),1};
}else if(hasPlayer2Won(player)){
return new Object[]{get_default_input(1),-1};
}
List<T> movesAvailable = getNextStates();
if(movesAvailable.isEmpty()){
return new Object[]{get_default_input(0), 0};
}
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
T computersMove = getNextStates().get(0);
int i = 0;
for (T move: movesAvailable) {
makeAMove(move, player);
Object[] result = minimax(depth + 1, player == G.PLAYER1 ? G.PLAYER2 : G.PLAYER1);
int currentScore = (int)result[1];
if(player == G.PLAYER1){
max = Math.max(currentScore, max);
if(currentScore >= 0 && depth == 0) {
computersMove = move;
}
if(currentScore == 1){
resetMove(move);
break;
}
if(i==movesAvailable.size() - 1 && max < 0){
if (depth == 0){
computersMove = move;
}
}
}else{
min = Math.min(currentScore, min);
if(min == -1) {
resetMove(move);
break;
}
}
i++;
resetMove(move);
}
return new Object[]{computersMove, player == G.PLAYER1 ? max: min};
}
答案 0 :(得分:1)
我已成功测试了以下改善极小极大的方法(用它来玩Tic-Tac-Toe和Domineering):
Alpha beta pruning - 使用这种修剪的特殊变体,结合Lazy evaluation - 基本上不是生成整个树,而是在每一层上生成最佳移动并保持懒惰其他国家行动对的持有人(应用懒惰的评估方法,通过利用供应商并在不同于我所持有的移动时调用它)。
Heuristic pruning - 请参阅该书中有关启发式的章节。我基本上只生成树的第一个d分支而不是确定性结果,我将该书中描述的启发函数应用于当前状态以确定启发式结果。每当移动(d + 1)时,我使用相同的方法生成另一个分支。 在这里,d是您选择的级别(最安全的方式是通过测试)
Parallel computing也看一下这个,你可能会觉得实施起来比较困难但是还是有回报
前两个选项为我节省了大量的计算时间,这样我就能够以最佳5x5的方式玩Domineering,启发式最高可达10x10(根据你想要的程度,它可以更好)。