启发式函数验证迭代加深

huangapple go评论52阅读模式
英文:

Heuristic function ivalidating iterative deepening

问题

以下是您提供的代码的翻译部分:

public int optimize(GameState currentBoard) {
    List<Integer> aiMove = this.getMoves(currentBoard.getNextPlayer());

    double maxScore = 1e-30;
    int bestMove = -1;

    int maxTime = 5000;
    int moves = aiMove.size();

    long timeForEach = maxTime / moves;

    for (var moveForPit : aiMove) {
        GameState gameClone = new GameState(currentBoard);

        gameClone.makeMove(moveForPit);

        double score = iterativeDeepSearch(gameClone, timeForEach);

        if (score >= MAX_CUTOFF) {
            return moveForPit;
        }

        if (score > maxScore) {
            maxScore = score;
            bestMove = moveForPit;
        }
    }

    return bestMove;
}

private double iterativeDeepSearch(GameState gameClone, long timeForEachMove) {
    long sTime = System.currentTimeMillis();
    long endTime = sTime + timeForEachMove;

    int depth = 1;
    double score = 0;

    searchCutoff = false;

    while (true) {
        long cTime = System.currentTimeMillis();

        if (endTime - cTime < 0)
            break;

        double searchResults = this.alphaBetaPruning(gameClone, depth, Double.MIN_VALUE, Double.MAX_VALUE, cTime,
                endTime - cTime);

        if (searchResults >= MAX_CUTOFF) {
            return searchResults;
        }

        if (!searchCutoff) {
            score = searchResults;
        }

        depth++;
    }

    return score;
}

private double alphaBetaPruning(GameState gameClone, int depth, double alpha, double beta, long startTime, long timeLimit) {

    boolean isAi = gameClone.getNextPlayer() == 2;
    double score = gameClone.scoreHeuristic();

    long currentTime = System.currentTimeMillis();
    long elapsedTime = (currentTime - startTime);

    boolean won = gameClone.gameEnded();

    searchCutoff = elapsedTime - timeLimit >= 0;

    if (won || searchCutoff || (depth == 0) || (score >= MAX_CUTOFF) || (score <= MIN_CUTOFF)) {
        return score;
    }

    if (isAi) {
        List<Integer> moveList = this.getMoves(Players.AI.id);
        double value = Double.MIN_VALUE;
        for (var m : moveList) {
            GameState childClone = new GameState(gameClone);
            if (childClone.makeMove(m)) {

                value = alphaBetaPruning(childClone, depth - 1, alpha, beta, startTime, timeLimit);
                alpha = Math.max(alpha, value);

                int comp = Double.compare(alpha, beta);
                if (comp >= 0) {
                    break;
                }
            }
        }

        return value;
    } else {
        List<Integer> moveList = this.getMoves(Players.HUMAN.id);
        double value = Double.MAX_VALUE;
        for (var m : moveList) {
            GameState childClone = new GameState(gameClone);
            if (childClone.makeMove(m)) {

                value = alphaBetaPruning(childClone, depth - 1, alpha, beta, startTime, timeLimit);
                beta = Math.min(beta, value);

                int comp = Double.compare(beta, alpha);
                if (comp >= 0) {
                    break;
                }
            }
        }

        return value;
    }
}

希望这些翻译能对您有所帮助。如果您有任何其他问题,请随时问我。

英文:

For a Mancala game, I'm writing an iterative deepening algorithm. This is the code:

public int optimize(GameState currentBoard) {
List&lt;Integer&gt; aiMove = this.getMoves(currentBoard.getNextPlayer());
double maxScore = 1e-30;
int bestMove = -1;
int maxTime = 5000;
int moves = aiMove.size();
long timeForEach = maxTime / moves;
for (var moveForPit : aiMove) {
GameState gameClone = new GameState(currentBoard);
gameClone.makeMove(moveForPit);
double score = iterativeDeepSearch(gameClone, timeForEach);
if (score &gt;= MAX_CUTOFF) {
return moveForPit;
}
if (score &gt; maxScore) {
maxScore = score;
bestMove = moveForPit;
}
}
return bestMove;
}
private double iterativeDeepSearch(GameState gameClone, long timeForEachMove) {
long sTime = System.currentTimeMillis();
long endTime = sTime + timeForEachMove;
int depth = 1;
double score = 0;
searchCutoff = false;
while (true) {
long cTime = System.currentTimeMillis();
if (endTime - cTime &lt; 0)
break;
double searchResults = this.alphaBetaPruning(gameClone, depth, Double.MIN_VALUE, Double.MAX_VALUE, cTime,
endTime - cTime);
if (searchResults &gt;= MAX_CUTOFF) {
return searchResults;
}
if (!searchCutoff) {
score = searchResults;
}
depth++;
}
return score;
}
private double alphaBetaPruning(GameState gameClone, int depth, double alpha, double beta, long startTime, long timeLimit) {
boolean isAi = gameClone.getNextPlayer() == 2;
double score = gameClone.scoreHeuristic();
long currentTime = System.currentTimeMillis();
long elapsedTime = (currentTime - startTime);
boolean won = gameClone.gameEnded();
searchCutoff = elapsedTime - timeLimit &gt;= 0;
if (won || searchCutoff || (depth == 0) || (score &gt;= MAX_CUTOFF) || (score &lt;= MIN_CUTOFF)) {
return score;
}
if (isAi) {
List&lt;Integer&gt; moveList = this.getMoves(Players.AI.id);
double value = Double.MIN_VALUE;
for (var m : moveList) {
GameState childClone = new GameState(gameClone);
if (childClone.makeMove(m)) {
value = alphaBetaPruning(childClone, depth - 1, alpha, beta, startTime, timeLimit);
alpha = Math.max(alpha, value);
int comp = Double.compare(alpha, beta);
if (comp &gt;= 0) {
break;
}
}
}
return value;
} else {
List&lt;Integer&gt; moveList = this.getMoves(Players.HUMAN.id);
double value = Double.MAX_VALUE;
for (var m : moveList) {
GameState childClone = new GameState(gameClone);
if (childClone.makeMove(m)) {
value = alphaBetaPruning(childClone, depth - 1, alpha, beta, startTime, timeLimit);
beta = Math.min(beta, value);
int comp = Double.compare(beta, alpha);
if (comp &gt;= 0) {
break;
}
}
}
return value;
}
}

I also supply a heuristic function, given by board.scoreHeuristic(). This is essentially the players differnce in score divided by the total amount possible to win with. In this version of Mancala, this should be 72 (12 pits, 6 ambos in each pit). I understand that this is impossible, but almost, anyway.

My code occassionally runs into an infinite loop, and I believe that the issue is the heuristic, which some times returns 0. I cannot understand why this infinite loop happens.

答案1

得分: 0

原来,正如许多Java程序员所知道的那样,clone()并不等同于在克隆中分配数组…
对于其他不知道的程序员(比如我自己…):

这个

GameState(GameState parent) {
this.board = parent.board; // 不好!
}

应该改成这样:

GameState(GameState parent) {
this.board = parent.board.clone(); // 或者使用Arraycopy…
}
英文:

Turns out, as many Java programmers know, that clone() is not the same as assigning arrays in a clone...
For other programmers out there who are not aware (such as myself..):

This

GameState(GameState parent) {
this.board = parent.board; // BAD!
}

Is supposed to be this:

GameState(GameState parent) {
this.board = parent.board.clone(); // or Arraycopy...
}

huangapple
  • 本文由 发表于 2020年9月14日 17:25:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/63881576.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定