提高字符串重叠矩阵构建效率
Increase string overlap matrix building efficiency
我有一个由100个字符长的字符串组成的庞大列表(N=~100000),我正在努力寻找它们之间的重叠。例如,一个字符串可能是
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
您真的需要知道所有字符串对之间的匹配吗?如果是,则必须将每个字符串与其他字符串进行比较,这意味着需要n^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) 从当前字符串中删除第一个字符。如果生成的字符串已经在表中,则将其出现次数计数器增加一,否则将其输入表中。
e) 重复3b,从当前字符串中删除最后一个字符,而不是第一个字符。
f) 从列表中删除当前字符串。
g) 从3a)开始重复,直到计算时间用完,或者剩下的字符串太短而不感兴趣。
如果这是一个更好的算法,这在很大程度上取决于你的数据以及你真正感兴趣的比较。如果你的数据非常随机/匹配的次数很少,这可能需要比你最初的想法更长的时间。但它可能会让你先找到有趣的部分,然后跳过不太有趣的部分。
我看不出有多少方法可以改进这样一个事实,即需要将每个字符串相互比较,包括对它们进行移位,而这本身就是超长的,计算集群似乎是最好的方法
我唯一看到的改进是字符串比较本身:用二进制模式替换A、C、T、G和X:
- A=0x01
- C=0x02
- T=0x04
- G=0x08
- X=0x0F
- C++为构建时间获取QDateTime的可靠方法
- 无法在 CLion 中构建 C++ 项目
- 函数向量_指针有不同的原型,我可以构建一个吗
- 如何使用ndk-build.cmd构建Android.so文件
- libssh 的函数在构建 libssh 时无法在 Qt 和 cmake 错误中找到
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- VSCode-有一个红色下划线,但程序构建和运行正确,并且出现配音错误
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 无法使用Qt Creator在Windows中构建yaml-cpp
- 构建一个由C和C++文件组成的库
- llvm构建器向基本块添加终止符
- 为什么当我解模块化时,这个C++代代码"效率较低"?
- FLTK 2.0构建和演示,适用于VS2019的2011年左右的代码库
- 如何跨平台将二进制资源构建到程序中?
- 将 OpenCV 与 CMAKE 中的项目一起构建为第三方库的正确方法
- 如何解决 Ninja c++ 构建和执行问题
- 使用 cmake 的 LLVM 构建在 tsan_libdispatch_mac.cc 期间失败; "Error: conflicting types for ..."
- CMake WxWidgets项目成功地在Linux上构建,但没有在Windows上构建
- 更改命令行 qt5 源代码构建配置的正确/快速方法
- 提高字符串重叠矩阵构建效率