Java中是否存在用于稀疏位向量的任何着名库?
(并且有关于稀疏对如何使用它们的指导原则吗? java.util.BitSet中?)
Java中是否存在用于稀疏位向量的任何着名库?
(并且有关于稀疏对如何使用它们的指导原则吗? java.util.BitSet中?)
该 柯尔特图书馆 具有稀疏矩阵(1D,2D和3D)。它还有一个高效的BitVector,每个值1位,而不是8位 boolean[]
确实。
但是,稀疏矩阵不直接支持位 - 只有双精度和对象。您可以通过将位索引maping到长索引来包装1D稀疏双矩阵 (bitIndex>>6)
因为每个长持有64位, 兑换 将检索到的double转换为原始long值,并使用位操作来访问检索到的long的位。一点工作,但远不及自己实现稀疏矢量那么多。一旦你的包装器工作,你可能会避免将双精度转换为long,并使用双重1D稀疏矩阵的可用Colt源代码作为起点实现一个真正的稀疏长1d矩阵。
编辑:更多信息。假设所有位(长)最初为0,Colt向量/矩阵最初不需要存储器用于存储。将值设置为非零会占用内存。将值设置回0会继续消耗内存,但会定期回收零值的内存。
如果这些位真正稀疏,使得每个后备长值仅设置一个位,则存储开销将非常差,需要存储每个实际位64位。但是当你提到典型的情况是20-40%稀疏时,那么开销将会低得多,如果比特在范围内聚集,可能没有浪费的存储,例如, 0-100,然后1000-1100和2000-2200(十六进制值)中的位。总的来说,只有1/16的区域被分配给位,但是聚类意味着存储的位没有浪费的空间。
TL; DR去这里 Java中的高效稀疏BitSet实现
我知道这是一个“老”的问题,但我遇到了同样的问题,我偶然发现了这篇文章。虽然答案很好,但我最终并不满意。在进一步挖掘之后,我想我已经遇到了Java中稀疏BitSets问题的“权威”答案。
在 这个演讲 作者Bruce Haddon博士讨论了他的研究人员为标准Java BitSet创建高内存效率和高性能替代品的努力。
他演示文稿的原始链接已经死了,但我联系了Haddon博士并保留了代码和演示文稿:
https://github.com/brettwooldridge/SparseBitSet
我不建议更高度地阅读此演示文稿。即使您对稀疏位集没有兴趣,它也是一个引人入胜的读物,更多的是解决问题的本质......
如果它真的稀疏(例如,小于1%的加载),那么使用由位索引索引的哈希表可能相当不错;如果该位分别为1或0,则只需要知道表中是否存在索引。
如果密度高达百分之几,则可以使用由位索引除以64的哈希表,并存储 长 哈希表中包含实际位的单词。位 ñ 如果哈希表包含值,则设置 V 对于 INT(N / 64) 和 (V >>(N mod 64))&1 是真的。
这两个答案都假设您希望优化对位的随机访问。如果要按索引优化对位的顺序(或其他访问),则可能需要稀疏矩阵结构,使用相同类型的低级位向量表示,具体取决于预期的密度。看到 稀疏矩阵
你可以试试 FastUtil的AVL树图。
CERN COLT广泛用于向量和矩阵计算,并且具有稀疏矩阵,但不是专门用于位向量。
http://acs.lbl.gov/software/colt/api/cern/colt/matrix/impl/SparseObjectMatrix1D.html
一个哈希表,仅仅存在或不存在密钥告诉你什么?那将是一个哈希集!我对BitSet上的一个集合(甚至是一个哈希值)的性能持怀疑态度。这实际上取决于速度或内存是否是主要驱动因素。