Tic-Tac-Toe 的遗传算法

我被分配到一个任务,要使用遗传算法编写一个 5x5x5 的井字游戏 AI。我的方法是从 3×3 开始,先让它运行起来,然后扩展到 5×5,最后到 5x5x5。

它的工作方式如下:

  • 模拟一大堆游戏,在每局游戏的每一轮中,都在相应的表(X 表或 O 表,用 C++ stdlib map 实现)中查找响应。如果棋盘不存在,则将棋盘添加到表中。否则,随机做出响应。

  • 在我有完整的表格后,我初始化一大堆玩家(每个玩家都有棋盘表格的副本,并用随机响应初始化),让他们相互对战。

  • 使用他们的胜/负来评估适应度,我保留一定百分比的最佳玩家,他们可以继续。重复 X 代,应该会出现一个最佳玩家。

对于 3×3,排除掉棋盘是其他棋盘的反射/旋转,以及该步棋是“直接赢”或“阻挡赢”的情况,我遇到的棋盘总数是 53 或 38,这取决于你是先手还是后手。太棒了!不到一个小时就生成了一个最佳玩家。非常酷!

对于 5×5,我使用相同的策略,我知道表格的大小会增加,但没有意识到它会增加得如此之快。即使排除旋转/反射和强制移动,我的表格也有大约 360 万个条目,而且看不到尽头。

好吧,这显然行不通,我需要一个新的计划。如果我不枚举所有的棋盘,而只是枚举一些棋盘呢?嗯,这似乎也不起作用,因为如果每个玩家只有可能看到的棋盘的一小部分,那么他们会做出很多随机移动,显然是朝着与最优相反的方向前进。

有什么现实的方法可以解决这个问题吗?我是否会被迫使用棋盘特征?目标是尽可能少地硬编码游戏功能。

我一直在做研究,但我读到的一切都表明,带有 A-B 剪枝的 min/max 是唯一可行的选择。我当然可以这样做,但遗传算法真的很酷,我目前的方法在这里有点超出实际情况了。

编辑 问题几乎已经解决:

使用一个相似性函数,结合了开放空间的汉明距离、可能的获胜条件以及其他一些度量,将表格缩小到一个非常易于管理的 2500 个可能性,std::map 可以在不到一秒的时间内处理这些可能性。


回答:

我对遗传算法的了解非常有限,但在对棋盘配置进行建模时,你是否问错了问题?你的任务不是枚举所有可能的获胜配置——你试图做的是找到一系列通往获胜配置的动作。也许你应该关注的种群不是一组棋盘,而是一组移动序列。

编辑:我考虑的更多的是从一个空棋盘开始,而不是从一个特定的棋盘开始。在 3×3 的棋盘上,很明显以 (1,1) 开头的移动序列对 X 最有利。重要的不是最终的棋盘中间有一个 X,而是 X 首先被放在中间。如果 X 有一个或多个最佳第一步,那么 X 也有最佳的第二步、第三步或第四步吗?经过几轮的适应度测试和重组,我们会发现 X 的第二步通常是相同的,还是属于一小组值中的一个?第三步呢?

这不是极小极大算法,因为你不是基于棋盘的先前状态一次寻找最佳移动,而是在同时寻找所有最佳移动,希望收敛到一种获胜策略。

我知道这不能解决你的问题,但如果目的是进化出一种获胜策略,那么你自然会想要关注移动序列而不是棋盘状态。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注