使用AI解决拼图游戏

我制作了一个拼图游戏,玩家需要滑动方块到目标位置 – 规则相当简单:

  1. 每次只能移动一个滑动方块
  2. 目标是将滑动方块移动到目标节点 – 你只需要填满目标节点,不一定需要所有滑动方块都进入目标节点。
  3. 如果滑动方块在冰面上滑动,它会继续朝那个方向移动,直到被停止或移动
  4. 如果滑动方块撞到固体物体(混凝土、另一个方块),它会停止并可以再次移动(显然不能移动到混凝土上)
  5. 如果滑动方块滑到木头上,它会在木头上停止并可以移动
  6. 如果滑动方块滑到目标节点,它将无法再移动
  7. 方块可以通过某些方块移动,例如,箭头方块会将方块朝那个方向推动
  8. 有开关方块可以开启“门”,这些“门”可以被移动以开启和关闭
  9. 有按钮方块,其操作类似于开关,但必须有方块压在上面才能激活“门”
  10. 当门关闭时,它们就像混凝土一样。当门打开时,它们就像冰面一样。

我想这些就是规则了。以下是一些截图:

拼图的初始状态

在这里,玩家必须移动方块,使它们相互碰撞以解决拼图。

拼图距离解决还有三步

拼图接近解决的状态。注意方块如何撞到另一个方块并停止

这里是另一个包含推动方块机制的拼图:

这里可以移动方块

如果我们将右上角的方块向下滑动,会发生以下情况:

方块被推向左侧,到达木方块

如你所见,方块在撞到箭头方块后被推向左侧,并在木方块上停止。

我想编写一个AI解决方案来解决这些拼图 – 我在考虑使用某种深度优先搜索,但我不知道从哪里开始。任何关于如何实现这一点的建议都将非常有帮助!


回答:

你的问题是一个经典的状态空间搜索问题。根据你特定实例的特性,可以使用不同的算法来解决。

无论你的特定实例如何,你需要定义四个组件:

  1. 初始状态,在你的问题中是初始配置
  2. 一个函数,返回从任何状态可达的所有可能状态,在你的问题中,可达状态是通过移动滑动方块可以得到的所有可能的拼图配置。当一个状态的可达状态被访问时,该状态被称为已扩展。
  3. 目标测试,一个函数,判断给定状态是否为目标状态,在你的问题中,你会检查所有目标方块是否已被填满,
  4. 成本函数,给出从一个状态到另一个状态的成本,使你的算法能够选择执行的最佳动作。在你的情况下,我认为你可以为每个动作使用常数值1,并搜索执行的最小动作数以达到目标状态之一。

由于你的问题可以用这四个组件来定义,你的问题可以用以下算法之一来解决:

  1. 广度优先搜索(BFS):我们首先测试初始状态是否为目标状态(显然对于非平凡问题不是),然后我们扩展初始状态,测试其每个可达状态,如果不是,则扩展这些状态,依此类推,按层级进行…可以使用队列来实现。
  2. 深度优先搜索(DFS):从初始状态开始,测试目标,然后扩展一个邻居状态,测试目标,然后扩展该状态,依此类推,向下深入到状态空间的最深处。这可以用堆栈来实现。

为了评估哪种算法最合适,我们可以考虑以下因素:

  1. 完整性:算法是否保证在存在解决方案时找到解决方案?
  2. 最优性:算法能否找到最优解?
  3. 时间复杂度:需要多长时间?
  4. 空间复杂度:需要多少内存?

如果我们考虑BFS策略,我们可以看到它是完整的,因为它系统地按层级探索状态空间,它只有在状态深度增加时成本函数不减少的情况下才是最优的(这是我们的情况,因为所有动作都有恒定成本)。现在是坏消息:假设每个节点的扩展最多可以产生个状态,并且第一个解决方案在深度,那么你将需要存储和扩展最多个状态。

在DFS的情况下,我们必须考虑到它可能会在一条路径上长时间(可能无限)卡住,而不同的选择可能很快找到解决方案。因此,当状态空间是无限时,这个算法既不完整也不最优。如果我们考虑作为状态空间的最大深度,我们将得到最多的空间复杂度,而时间复杂度仍然是指数级的:

那么,我们能做什么呢?我们可以混合这两种策略,使用迭代加深深度优先搜索。在这种搜索中,我们将从0开始迭代地运行DFS,限制最大深度到一个最大深度级别。这种方法具有两种搜索策略的优点:空间复杂度,其中是第一个最优解的深度,时间(我们无法做得更好),它是完整的(它会找到解决方案,因为它按层级迭代地探索所有状态),并且它是最优的(假设成本函数随路径长度非递减)出于与BFS相同的原因是最优的。

参考:人工智能:现代方法

注意:显然存在其他无信息策略,但正如书中所述,IDDFS是无信息搜索问题的一个好选择,在这种情况下你对搜索空间没有额外信息。请参阅书籍以了解其他类型的搜索策略,例如有信息搜索,我们对目标状态与当前状态的距离有一定的了解。

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中创建了一个多类分类项目。该项目可以对…

发表回复

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