Database 如何在数据库中存储稀疏决策树(移动列表)?

Database 如何在数据库中存储稀疏决策树(移动列表)?,database,data-structures,artificial-intelligence,storage,decision-tree,Database,Data Structures,Artificial Intelligence,Storage,Decision Tree,很长一段时间以来,我一直在考虑为棋盘游戏制作人工智能,最近我开始收集资源和算法。这场比赛是非随机的,大多数时候,一名球员的招式少于3次,有时,招式超过20次。我想储存关键的动作,或者模棱两可的动作,这样AI就能从错误中吸取教训,下次也不会犯同样的错误。肯定赢或输的动作不需要存储。所以我在游戏开始时有一个稀疏的决策树。 我想知道我应该如何在数据库中存储此决策树?数据库不需要是SQL,我不知道哪个数据库适合这个特定问题 编辑:请不要告诉我如何将决策树解析到内存中,只要想象一下像国际象棋一样复杂的游戏

很长一段时间以来,我一直在考虑为棋盘游戏制作人工智能,最近我开始收集资源和算法。这场比赛是非随机的,大多数时候,一名球员的招式少于3次,有时,招式超过20次。我想储存关键的动作,或者模棱两可的动作,这样AI就能从错误中吸取教训,下次也不会犯同样的错误。肯定赢或输的动作不需要存储。所以我在游戏开始时有一个稀疏的决策树。 我想知道我应该如何在数据库中存储此决策树?数据库不需要是SQL,我不知道哪个数据库适合这个特定问题


编辑:请不要告诉我如何将决策树解析到内存中,只要想象一下像国际象棋一样复杂的游戏。

我假设你的问题是关于如何将决策树转换为串行格式,该格式可以写入某个位置,然后用于重建树

尝试使用树的预顺序遍历,使用toString()函数(或其等效函数)将存储在决策树的每个节点上的数据转换为文本描述符。通过预顺序遍历,我的意思是实现一种算法,该算法首先对节点执行toString()操作,然后将输出写入数据库或文件,然后按指定顺序对其子节点递归执行相同的操作。因为您处理的是稀疏树,所以toString()操作还应该包含有关子树存在或不存在的信息


重建树很简单-第一个存储值是根节点,第二个是左子树的根成员,依此类推。为每个节点存储的串行数据应提供有关下一个输入节点应属于哪个子树的信息。

首先,您尝试执行的操作听起来像是基于案例的推理(CBR)问题,请参见:。CBR将有一个决策数据库,理论上,您的系统将选择可用的最佳结果

因此,我建议使用neo4j,它是一个nosql图形数据库


因此,为了表示游戏,每个位置都是图中的一个节点,每个节点都应该包含来自该位置的潜在移动。您可以跟踪随着比赛的进展而学习的得分指标,以便AI了解更多信息

当您将遍历树时,neo4j对我来说似乎是一个很好的解决方案。SQL不是一个好的选择,因为查询需要很多连接。正如我所理解的,您正在寻求一种在数据库中存储一些图形的方法,而neo4j是一个明确用于图形的数据库。对于稀疏性,您可以使用PropertyContainers将原语或字符串数组附加到图形的边缘,以对移动序列进行编码(我说的稀疏性和跳过节点是否正确,您的树边缘是移动序列而不是单个移动?)。

我会使用文档数据库(NOSQL)因为您可以在数据库中存储任何数据结构

文档不像普通的SQL数据库那样扁平,它允许您直接存储层次结构数据,如树:

{ 
   decision: 'Go forward', 
   childs: [ 
      { decision: 'Go backwards' },
      { 
         decision: 'Stay there',
         childs: [
            { decision: 'Go backwards' }
         ]
      }
   ]
}
这里您可以看到一个示例JSON树,它可以存储在RavenDB中

RavenDB还有一个内置功能,用于查询分层数据:

请查看以获取RavenDB如何工作的更多信息

资源:

您可以将其用作存储器。
首先,创建“编译器”。此编译器将解析文本文件并将其转换为紧凑的二进制表示形式。主应用程序将此二进制优化文件映射到内存中。这将解决内存大小限制的问题

从简单的数据库表设计开始

决定: 当前状态二进制(57)|新状态二进制(57)|分数整数

CurrentState和NewState是游戏状态的序列化版本。分数是给NewState的权重(正面分数是好的移动,负面分数是坏的移动),你的AI可以适当地更新这些分数

Renju使用15x15板,每个位置可以是黑色、白色或空的,因此需要天花板((2位*15*15)/8)字节来序列化板。在SQL中,这将是T-SQL中的二进制(57)

你的AI会选择它存储的当前移动,如

SELECT NewState FROM Decisions WHERE CurrentState = @SerializedState ORDER BY Score DESC
您将获得从当前游戏状态存储的所有下一步移动的列表,按最佳分数到最低分数的顺序排列

您的表结构在(CurrentState,NewState)上有一个复合唯一索引(主键),以便于搜索和避免重复


这不是最好的/最理想的解决方案,但由于您缺乏数据库知识,我相信这将是最容易实现的解决方案,并为您提供一个良好的开端。

如果我与国际象棋引擎进行比较,那些从内存中进行游戏的引擎,可能除了打开库之外。国际象棋太复杂,无法存储决胜决策树。国际象棋引擎通过给潜在的和暂时的未来位置(不是移动)分配启发式评估来进行游戏。未来的位置是通过某种有限深度的搜索找到的,可能会在内存中缓存一段时间,但通常会在每一轮中进行简单的重新计算,因为搜索空间太大,无法以比重新计算更快的方式进行存储。

你知道解决跳棋的AI吗?它通过编译每个可能的结局的数据库来做到这一点。虽然这并不完全是您正在做的事情,但您可以从中学习。

我无法清楚地想象您在树中处理的数据结构及其复杂性

但以下是一些您可能感兴趣的想法:

  • 将决策树映射到稀疏矩阵中,树毕竟是一个图
  • 利用稀疏矩阵特性设计存储/检索策略

我会用传统的方式在国际象棋引擎中处理开卷:

  • 将军
    struct book_entry {
        uint64_t hash
        uint32_t score
    }