繁体   English   中英

如果它在每次迭代后返回到其原始状态,我可以安全地改变我正在迭代的数组吗?

[英]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 如果是这种情况, 文档很清楚:

此类的iteratorlistIterator方法返回的iterator是快速失败的:如果在创建迭代器之后的任何时候对列表进行结构修改,除了通过迭代器自己的removeadd方法之外,迭代器将抛出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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM