【发布时间】:2017-03-15 22:05:00
【问题描述】:
所以我正在尝试为奥赛罗游戏实现蒙特卡洛搜索树。我有一个根节点和子节点,如果您可以在一次合法移动中从“y”移动到“x”,则“x”是“y”的子节点。
在每个节点上,我存储一个“Board”对象,该对象包含所有棋盘信息,例如每个图块的值。我遇到的第一个问题是,如果我更改了子节点的板对象,它也会更改父节点的值。我通过为每个子节点创建一个“新”板对象来解决此问题,但这会导致在我运行模拟数千次时使用过多的内存,以至于内存不足。
如果有一种方法可以更改子节点中的棋盘信息而不更改父节点的棋盘信息,或者是否有更好的方法将棋盘信息存储在每个节点而不是创建每个节点都有一个新的 Board 对象。
如果有什么需要澄清的,请在下方评论,感谢阅读!
编辑:
for (int x = 0; x < numberOfChildren; x += 1) {
// Resets *currentBoard to the same state as the node being expanded
Board *currentBoard = nodeToExpand->getCurrentBoard();
// Retrives the board value information
int** temporaryBoardValues = currentBoard->getBoardValues();
// Makes a new board object with the previous parameters
Board *temporaryBoard = new Board(blockSize, boardSize, offset);
// Sets the new board values to the same as the old ones
temporaryBoard->setBoardValues(temporaryBoardValues);
// Creates a clone of that board state
// Board *temporaryBoard = cloneBoard(*currentBoard);
// Creates a node with the cloned board state, setting the parent to be the node being expanded.
// Assigns it one of the available moves
// Produces the array of child nodes
myChildren[x] = new Node(nodeToExpand, temporaryBoard, availableMoves[x], currentPlayer);
//delete temporaryBoard;
}
小代码sn-p。它是我创建一个用完所有内存的新 Board 对象的部分。
【问题讨论】:
-
你能发布一个小代码示例吗?
-
对于深度为
n的分支树搜索:您只需要在内存中保留 (1) 当前最佳移动和n节点。您不需要只保留整个树,只保留沿着 1 个分支到深度n的当前搜索/评估,这可以很容易地保存在堆栈中 - 如果您在堆上保存了许多板,那么您可能做错了。 (另见 alpha-beta 算法)。 -
那么为什么不将 moves 存储在节点中,并简单地在节点 n 处从所需的序列节点中的移动序列构建棋盘从根到节点n?
-
@MatthewFennell 建议——在您编写一行代码之前,您的设计中应该考虑到内存要求。最终可能发生的事情是不得不废弃很多,如果不是所有当前代码的话。
-
从对蒙特卡洛搜索树的维基百科文章的非常肤浅的阅读来看,在我看来,这是一种很好的理论方法,但却是一种糟糕的实践方法。 YMMV。
标签: c++ object nodes heap-memory montecarlo