MCTS RAVE работает плохо в области искусственного интеллекта для настольных игр.
Краткое содержание
Я использую Monte Carlo Tree Search с выбором UCT, чтобы попытаться создать ИИ игрока для сложной многопользовательской настольной игры. Мой обычный UCT MCTS работает нормально, побеждая против случайных и базовых жадных игроков или игроков варианта "параноидального" alpha-beta с небольшой глубиной, но я искал способы улучшить его и нашел RAVE. В RAVE, для данного узла игрового дерева N, его дочерние узлы Ci хранят не только статистику побед в розыгрышах, начатых в узле N, но и статистику побед во всех розыгрышах, начатых в узле N и ниже него, если они содержат ход i (даже если ход был сыгран в дереве между узлом N и розыгрышем). Таким образом, содержимое узлов дерева подвергается влиянию не только ходов, сыгранных непосредственно в данной позиции, но и тех же ходов, сыгранных позже. Я нашёл много литературы об этом, и предполагалось, что это даст хорошие результаты – 70%-80% победного процента против базового UCT в игре TicTacToe3D. Я реализовал его как своего рода бенчмарк, версию 4x4x4, прежде чем...
Полный текст
Спросили 5 лет, 9 месяцев назад Изменено сегодня Просмотрено 854 раза
Спросили 5 лет, 9 месяцев назад
4 $\begingroup$ Я использую поиск древовидных деревьев с Монте-Карло с выбором UCT, чтобы попытаться создать ИИ игрока для сложной многопользовательской настольной игры. Мой обычный UCT MCTS работает нормально, побеждает с использованием случайных и базовых жадных игроков или игроков с вариантом "параноидального" альфа-бета на низкой глубине, но я искал некоторые методы для улучшения его и нашёл RAVE. "В RAVE, для данного узла игрового дерева N, дочерние узлы Ci хранят не только статистику побед в играх, начатых в узле N, но также статистику побед во всех играх, начатых в узле N и ниже него, если они содержат ход i (также когда ход был сыгран в дереве между узлом N и игрой), при этом это происходит даже если ход был сыгран в дереве. Это позволяет содержимому узлов дерева влиять не только на ходы, сыгранные непосредственно в данной позиции, но и на те же ходы, сыгранные позже.". Я нашёл много литературы об этом, и предполагалось, что оно даст хорошие результаты - 70%-80% победного процента против базового UCT на игре TicTacToe3D. Я реализовал его как своего рода эталон, версию 4x4x4, прежде чем пытаться применить его к моей целевой игре. Однако я пытался настраивать параметры, и у меня получались худшие результаты, победный процент составлял не более 46%. Я вычислял значения узлов следующим образом: visits[i] — это количество посещений дочернего i родителя p, на котором выполняется выборка, wins[i] — это количество побед согласно UCT, AMAFvisits и AMAFwins назначаются на основе действия источника узла -> обновляются после завершения симуляции, если действие источника (действие, которое изменило состояние игры в этот статус) было сыграно в симуляции игроком корневого узла MCTS дерева. для (int i = 0; i < nChildren; i++) { if (visits[i] < 1) { value = Double.MAX_VALUE - rnd.nextDouble(); } else if (m[i] < 1) { double vUCT = wins[i]/visits[i] + C*Math.sqrt(Math.log(sumVisits)/(visits[i])); value = vUCT; } else { double beta = Math.sqrt(k/(3*visits[i] + k)); double vRAVE = (AMAFscores[i])/(m[i]) + C*Math.sqrt(Math.log(mChildren)/(m[i])); double vUCT = (wins[i])/(visits[i])+ C*Math.sqrt(Math.log(sumVisits)/(visits[i])); value = beta * vRAVE + (1 - beta) * vUCT; value += rnd.nextDouble() * eps; /*double beta = Math.sqrt(k/(3*visits[i] + k)); double vRAVE = (AMAFscores[i])/(m[i]); double vUCT = (wins[i])/(visits[i]); value = beta * vRAVE + (1 - beta) * vUCT; value += C*Math.sqrt(Math.log(sumVisits)/(visits[i])); value += rnd.nextDouble() * eps;*/ } if (maxValue <= value) { maxValue = value; index = i; } } chosen = tree.getTreeNode(children.get(index)); Вот изображение, отражающее мое понимание того, как должен работать RAVE -> https://i.sstatic.net/naQXE.jpg. Пропускаю ли я что-нибудь? Неправильно ли моя реализация? Вот остальной код, отвечающий за обход дерева "в стиле RAVE": https://www.paste.org/104476 . Функция расширения в дереве расширяет дерево для всех действий и возвращает случайное из них, которое затем посещается, остальные должны быть посещены в других итерациях. Я сначала протестировал код с k = 250, как это рекомендовалось авторам статьи-эталона https://dke.maastrichtuniversity.nl/m.winands/documents/CIG2016_RAVE.pdf, а также с 100, 1000 и 10000 итерациями, с глубиной дерева 20 или 50. Я также экспериментировал с другими значениями k и другими параметрами. game-ai monte-carlo-tree-search Share Improve this question Follow asked Apr 18, 2020 at 11:22 NaN 41 1 1 bronze badge $\endgroup$ Add a comment | 1 Answer 1 Sorted by: Reset to default Highest score (default) Date modified (newest first) Date created (oldest first) 0 $\begingroup$ Нет реализации RAVE в академической среде, о которой я знаю, использует фактор исследования в AMAF value ( C*Math.sqrt(Math.log(mChildren)/(m[i])) в вашей реализации). AMAF value используется только для смещения поиска к узлам с более многообещающими ходами и не заботится об исследовании менее посещенных ходов. Это не означает, что это не выгодно делать, но я думаю