【发布时间】:2024-01-23 19:19:01
【问题描述】:
我创建了一个极小极大算法,该算法使用 alpha beta 剪枝和转置表来加快搜索速度。我目前正在使用一个哈希图,它使用棋盘状态作为键并将分数保存为值。 (游戏是 5x5 板上的井字游戏)
这个问题是散列很慢,并且使用整个板状态作为键会占用大量内存。棋盘状态由具有 3 种可能类型的 2d 枚举数组表示:空白、X 和 O。我想使用自己的哈希(可能是 zobrist)作为键,根本不保存棋盘状态,但哈希图会拿走我的钥匙并再次对其进行哈希处理。我考虑过使用将键视为唯一的 btree 映射,但访问时间是 log(n) 而不是 O(1)。我也不关心键的顺序,所以 btree 似乎并不适合这里。
所以我的问题是,哪种数据结构在这里是理想的?即使第二次对我的键进行哈希处理,我也应该使用哈希映射吗?
【问题讨论】:
-
如果您实现自己的散列算法,散列成整数值(比如
u64),那么重新散列它的成本基本上是零。但是,您遇到的问题是,除非您可以保证您的哈希为每个棋盘状态生成唯一值,否则您不能不保存棋盘状态,否则您可能会因哈希冲突而得到不正确的结果。 -
没有“正确”的数据结构。使用
HashMap和BTreeMap为您的用例编写基准并进行比较。对于小型集合(BTreeMap 通常更快,但确切的限制取决于许多因素(例如缓存行中适合多少项目等),因此基准测试是了解的唯一方法。跨度> -
棋盘状态如何存储?
-
如果您使用 Zobrist 散列,您可以将散列存储在棋盘状态旁边,以避免每次都重新计算。特别是因为 Zobrist 哈希可以以非常低的成本增量计算。
-
为此目的使用位编码将非常有效地使用内存。为每个单元格留出 2 位(3 个状态 0、X、空白),您可以保证每个生成的代码都是唯一的,并且可以更快地计算为键。
标签: rust hashmap minimax btreemap