【发布时间】:2014-07-11 06:37:36
【问题描述】:
编辑:如果您想看看是否可以让 AI 表现得更好,请上传完整的源代码:https://www.dropbox.com/s/ous72hidygbnqv6/MCTS_TTT.rar
编辑:搜索搜索空间并找到导致损失的移动。但是由于 UCT 算法,导致损失的移动并不经常被访问。
为了了解 MCTS(蒙特卡洛树搜索),我使用该算法为经典的井字游戏制作 AI。我使用以下设计实现了算法:
树策略基于 UCT,默认策略是执行随机移动直到游戏结束。我在实施过程中观察到,计算机有时会做出错误的动作,因为它无法“看到”特定的动作会直接导致损失。
例如: 请注意动作 6(红色方块)的价值如何略高于蓝色方块,因此计算机标记了这个点。我认为这是因为游戏策略基于随机移动,因此很有可能人类不会在蓝色框中输入“2”。如果玩家没有在蓝色框中输入 2,则计算机将获胜。
我的问题
1) 这是 MCTS 的已知问题还是实施失败的结果?
2) 可能的解决方案是什么?我正在考虑将动作限制在选择阶段,但我不确定:-)
核心 MCTS 的代码:
//THE EXECUTING FUNCTION
public unsafe byte GetBestMove(Game game, int player, TreeView tv)
{
//Setup root and initial variables
Node root = new Node(null, 0, Opponent(player));
int startPlayer = player;
helper.CopyBytes(root.state, game.board);
//four phases: descent, roll-out, update and growth done iteratively X times
//-----------------------------------------------------------------------------------------------------
for (int iteration = 0; iteration < 1000; iteration++)
{
Node current = Selection(root, game);
int value = Rollout(current, game, startPlayer);
Update(current, value);
}
//Restore game state and return move with highest value
helper.CopyBytes(game.board, root.state);
//Draw tree
DrawTree(tv, root);
//return root.children.Aggregate((i1, i2) => i1.visits > i2.visits ? i1 : i2).action;
return BestChildUCB(root, 0).action;
}
//#1. Select a node if 1: we have more valid feasible moves or 2: it is terminal
public Node Selection(Node current, Game game)
{
while (!game.IsTerminal(current.state))
{
List<byte> validMoves = game.GetValidMoves(current.state);
if (validMoves.Count > current.children.Count)
return Expand(current, game);
else
current = BestChildUCB(current, 1.44);
}
return current;
}
//#1. Helper
public Node BestChildUCB(Node current, double C)
{
Node bestChild = null;
double best = double.NegativeInfinity;
foreach (Node child in current.children)
{
double UCB1 = ((double)child.value / (double)child.visits) + C * Math.Sqrt((2.0 * Math.Log((double)current.visits)) / (double)child.visits);
if (UCB1 > best)
{
bestChild = child;
best = UCB1;
}
}
return bestChild;
}
//#2. Expand a node by creating a new move and returning the node
public Node Expand(Node current, Game game)
{
//Copy current state to the game
helper.CopyBytes(game.board, current.state);
List<byte> validMoves = game.GetValidMoves(current.state);
for (int i = 0; i < validMoves.Count; i++)
{
//We already have evaluated this move
if (current.children.Exists(a => a.action == validMoves[i]))
continue;
int playerActing = Opponent(current.PlayerTookAction);
Node node = new Node(current, validMoves[i], playerActing);
current.children.Add(node);
//Do the move in the game and save it to the child node
game.Mark(playerActing, validMoves[i]);
helper.CopyBytes(node.state, game.board);
//Return to the previous game state
helper.CopyBytes(game.board, current.state);
return node;
}
throw new Exception("Error");
}
//#3. Roll-out. Simulate a game with a given policy and return the value
public int Rollout(Node current, Game game, int startPlayer)
{
Random r = new Random(1337);
helper.CopyBytes(game.board, current.state);
int player = Opponent(current.PlayerTookAction);
//Do the policy until a winner is found for the first (change?) node added
while (game.GetWinner() == 0)
{
//Random
List<byte> moves = game.GetValidMoves();
byte move = moves[r.Next(0, moves.Count)];
game.Mark(player, move);
player = Opponent(player);
}
if (game.GetWinner() == startPlayer)
return 1;
return 0;
}
//#4. Update
public unsafe void Update(Node current, int value)
{
do
{
current.visits++;
current.value += value;
current = current.parent;
}
while (current != null);
}
【问题讨论】:
-
我不明白将 C * Math.Sqrt((2.0 * Math.Log((double)current.visits)) / (double)child.visits) 添加到 UCB 行的基本原理。这个词是干什么用的?如果你只是删除这部分会发生什么?
-
这是根据:cameronius.com/cv/mcts-survey-master.pdf(第 9 页)- BestChild 编码的。如果我删除它,人工智能仍然会执行“愚蠢”的动作。
-
论文提到该算法适用于“深度受限的极小极大搜索”。在 minimax 中,你对你的移动和对手应用相同的分数启发式。我从来没有听说过一个人工智能会假设它正在与一个随机移动的对手对抗。
-
Groo:如果我理解正确的话,Monte Carlo Tree Search 不使用 heutistics(它可以用于诸如 go 等领域知识难以指定的游戏中)。在推出阶段,使用特定策略来模拟游戏,这通常是(再次,如果我理解算法正确的话)随机移动
-
这是在 github 上的任何地方吗?
标签: c# algorithm artificial-intelligence tic-tac-toe montecarlo