我有一个巨大的列表(N = ~1百万)字符串长100个字符,我正试图找到它们之间的重叠。例如,一个字符串可能是
XXXXXXXXXXXXXXXXXXAACTGCXAACTGGAAXA (and so on)
我需要构建一个N×N矩阵,其中包含每个字符串与每个其他字符串的最长重叠值。我目前的方法是(伪代码)
将所有字符串读入数组
创建空的NxN矩阵
将每个字符串与具有更高数组索引的每个字符串进行比较(以避免重做比较)
将最长重叠写入矩阵
还有很多其他的东西在继续,但我真的需要一种更有效的方法来构建矩阵。即使拥有最强大的计算集群,我也能掌握这种方法需要几天时间。
如果您没猜到,这些是DNA片段。 X表示“通配符”(探针低于阈值质量得分),所有其他选项是基础(A,C,T或G)。我尝试编写一个四元树算法,但这种方法太过密集了。
我喜欢你能提出的更有效方法的建议;我正在使用C ++,但伪代码/想法或其他语言代码也非常有用。
编辑:一些代码摘录,说明了我当前的方法。任何与概念无关的内容都已被删除
//part that compares them all to each other
for (int j=0; j<counter; j++) //counter holds # of DNA
for (int k=j+1; k<counter; k++)
int test = determineBestOverlap(DNArray[j],DNArray[k]);
//boring stuff
//part that compares strings. Definitely very inefficient,
//although I think the sheer number of comparisons is the main problem
int determineBestOverlap(string str1, string str2)
{
int maxCounter = 0, bestOffset = 0;
//basically just tries overlapping the strings every possible way
for (int j=0; j<str2.length(); j++)
{
int counter = 0, offset = 0;
while (str1[offset] == str2[j+offset] && str1[offset] != 'X')
{
counter++;
offset++;
}
if (counter > maxCounter)
{
maxCounter = counter;
bestOffset = j;
}
}
return maxCounter;
} //this simplified version doesn't account for flipped strings
答案 0 :(得分:1)
你真的需要知道所有字符串对之间的匹配吗?如果是,那么你必须将每个字符串与每个其他字符串进行比较,这意味着你需要进行n ^ 2/2比较,即使每个字符串对只存储一个字节,你也需要一个半TB的内存。
但是,我假设你真正感兴趣的是长字符串,那些有超过20或30或甚至超过80个字符的字符串,你可能真的不想知道是否有两个字符串对有3个共同字符,而其他50个是X,其余47个不匹配。
如果我是你,我会尝试 - 仍然不知道这是否适合您的申请 - 是:
1)从每个字符串中提取出有意义的最大子字符串。我想你想在开始和结束时完全忽略'X',如果一些“可读”的部分被大量的'X'破坏,那么单独处理可读部分而不是使用更长的字符串很多这个“哪个子串是相关的?”取决于你真正不知道的数据和应用程序。
2)列出这些最长的子串,以及每个子串的出现次数。按字符串长度排序此列表。您可以(但实际上不必)将每个原始字符串的索引与子字符串一起存储。你会得到像(例子)
这样的东西AGCGCTXATCG 1
GAGXTGACCTG 2
.....
CGCXTATC 1
......
3)现在,从列表的顶部到底部:
a)将“当前字符串”设置为列表中最顶层的字符串。
b)如果当前字符串旁边的出现次数是> 1,你找到了一个匹配。如果您没有记住索引,请在原始字符串中搜索子字符串,并标记匹配。
c)将当前字符串与相同长度的所有字符串进行比较,以找到某些字符为X的匹配项。
d)从当前字符串中删除第一个字符。如果结果字符串已经在您的表中,请将其出现的计数器增加1,否则将其输入表中。
e)重复3b,使用从当前字符串中删除的最后一个字符而不是第一个字符。
f)从列表中删除当前字符串。
g)从3a)重复,直到你的计算时间用完为止,或者你剩下的字符串变得太短而不感兴趣。
如果这是一个更好的算法,很大程度上取决于你的数据和你真正感兴趣的比较。如果你的数据非常随机/你的匹配很少,它可能需要比你原来的想法更长的时间。但它可能允许您首先找到有趣的部分并跳过不太有趣的部分。
答案 1 :(得分:0)
我没有看到很多方法来改善你需要将每个字符串相互比较的事实,包括移动它们,这本身就是超长的,计算集群似乎是最好的方法。
我唯一看到如何改进的是字符串比较:用二进制模式替换A,C,T,G和X: