我正在研究计算生物学项目,我需要存储许多序列之间不同的基因座索引。现在,我正在使用B +树来实现这个目的,但我想使用位图索引对于这样一个用例来说会更快:两个序列之间只有少量基因座不同,平均为1%,并且它们沿序列分布几乎相等;所以似乎有很大的位图索引压缩空间。
我的问题是我无法找到一种可以有效的压缩方法:
提前获取您的建议。
答案 0 :(得分:2)
查看FastBit:
答案 1 :(得分:0)
您可以使用这样的简单树数据结构:
struct node {
node * leftChild;
node * rightChild;
long mask;
};
struct tree {
int exponent; // the size of the tree is 2^exponent
node rootNode;
};
每个节点表示大位阵列的子阵列,其为(2 ^ n)* sizeof(长)位,n> = 0。如果叶子节点位于树的底部,则它们会在“掩码”中存储原始位掩码,否则它们会在“掩码”中存储0。这样,“掩码”值为0的叶节点可以表示位数组中的(2 ^ n)* sizeof(长)大小的空区域,因此可以有效地存储稀疏位数组。
leftChild和rightChild在所有叶节点中当然都是null。每个其他节点都有一个leftChild和rightChild指针,并且每个不是叶子节点的节点都至少有一个带有掩码的子节点,其中的掩码设置在其中。
要找到给定索引的位:
bool find_bit_at_index(tree t, long ind) {
long divider = 1 << (t.exponent - 1);
node *n = &t.rootNode;
node *lastNode;
while (n)
{
lastNode = n;
if (ind >= divider) {
n = n->rightChild;
ind -= divider;
}
else {
n = n->leftChild;
}
divider >>= 1;
}
return lastNode->mask & (1 << ind);
}
一旦理解了这个想法,构建树和开发其余算法应该很容易。我实际上没有测试过代码,因为这不是一个完整的解决方案,可能会留下一些拼写错误。而且我不是位图索引专家,可能(可能是)现成的包可以做得更好,但这个解决方案很简单,应该相对有效。与仅仅一个普通的位数组相比,1%可能还不够稀疏以使其更好(假设longs每个存储64位,平均多于一个位设置不超过2个长度),但是如果稀疏度增加超出节省的空间和时间。