我在C ++中设计一个简单的马尔可夫链,它将采用类型T
和大小N
的状态。我有一些关于如何设计国家以及最好/最有效的容器存储的问题。我需要将包含N
类型T
元素的状态映射到类型为T
的单个值以及权重。
马尔可夫链主要用于字符串,但它应该允许任意大小,理想情况下是任意类型。
状态
状态应该是可以清除的(或者至少允许容易计算哈希值)。当前选项是使用std::vector<T>
或std::deque<T>
以及迭代/累积散列算法,例如Boost&#39; hash_range
。但是,对于字符串,碰撞的可能性会增加,特别是对于较大的状态大小(尽管理智的值不会高于5-7左右)。但是,我没有看到解决这个问题的方法。它不是单独存储每个州,而是
容器
我研究了使用邻接矩阵。找到所有相关状态所需的O(N)复杂度,当然还有O(1)用于索引,但问题是我甚至不能使用vector<bool>
特化来节省空间,因为我需要存储一个加权值,所以这似乎会使用大量不必要的内存。绝大多数连接都是0。
目前的想法:
using T = /*some type*/ std::string;
using state_t = /*some type that will contain N elements of type T*/;
// the value (unhashed) and weight
using key_t = std::map<T, unsigned>;
// keep track of N-sized states only when they're at the beginning of a sequence
// Key: the hash of the state
// Value: The entire state (unhashed)
std::unordered_map<size_t, state_t> beginning_states;
// Otherwise, only keep track of the hash of the state to conserve memory
// Key: the hash of the previous state
// Value: the next value of type T and a weight (incremented by 1 each time)
std::unordered_map<size_t, key_t> connections;
然后我会使用std::deque<T>
变量并遍历用户的给定输入。它将保持N
的大小,并根据需要pop_front
/ push_back
。每个N
大小的状态将存储其累积哈希并与下一个值相关联。
我的问题是,使用这种标准容器的样式是否提供了太多的开销?是否有一个更有效的选项,相对容易实现?
注意: 我发现T
的非整数值(即字符串)可能会导致许多重复内容被保存在内存中。对于直接存储密钥的整数/指针类型具有模板特化可能是明智的,但对于其他类型,将完整的未散列值和索引/计数器存储在另一个容器中。