[英]Can I safely mutate an array I am iterating over, if it returns to its original state after each iteration?
我正在為Java中的游戲編寫一個minimax算法,並且出於速度目的,當我遞歸地通過決策樹時,改變游戲狀態。 但是,這涉及修改我迭代的移動列表。
public int minimax(int currentDepth) {
if (currentDepth == depth || board.legalMoves.isEmpty()) {
int eval = board.eval();
board.takeBack(1);
return eval;
}
int x = Integer.MIN_VALUE;
for (Tuple move : board.legalMoves) {
board.move(move);
x = max(x, -1*minimax(currentDepth+1));
board.takeBack(1);
}
return x
}
board.move()
方法改變了ArrayList legalMoves
,但takeBack(1)
將其恢復到原始狀態。 這會導致任何問題嗎?
總之,是的。
您沒有指定board.legalMoves
的類型。 你說它是數組,但它不可能,因為你在它上面調用isEmpty()
。 因此我懷疑你的意思是ArrayList
。 如果是這種情況, 文檔很清楚:
此類的
iterator
和listIterator
方法返回的iterator
是快速失敗的:如果在創建迭代器之后的任何時候對列表進行結構修改,除了通過迭代器自己的remove
或add
方法之外,迭代器將拋出ConcurrentModificationException
。 因此,在並發修改的情況下,迭代器快速而干凈地失敗,而不是在未來的未確定時間冒着任意的,非確定性行為的風險。
我看到兩種解決方法:
1) 避免結構修改。 換句話說,可以更改元素的值 ,但添加/刪除元素是不行的。
2) 使用索引迭代ArrayList
:
for (int i = 0; i < board.legalMoves.size(); i++) {
Tuple move = board.get(i);
...
}
是的,你可以,但這很危險。 我建議將minmax算法移動到一個新類並傳遞數據以分析到構造函數中。
現在,您可以在構造函數中復制一次數據,並且方法可以在副本上運行。 該算法現在可以以任何方式修改數據,它不會影響游戲的其他部分或其他線程。 此外,如果您有任何問題,它們必須來自一個類中的代碼。
總體目標是為代碼的每個修改部分提供所需數據的副本,以減少可能導致問題的依賴性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.