我有一个涉及生物学领域的问题。现在我有4个非常大的文件(每个有1亿行),但结构相当简单,这些文件的每一行只有2个字段,都代表一种基因。
我的目标是:设计一种可以实现以下目标的高效算法: 在这4个文件的内容中找到一个圆圈。圆圈定义为:
field #1 in a line in file 1 == field #1 in a line in file 2 and
field #2 in a line in file 2 == field #1 in a line in file 3 and
field #2 in a line in file 3 == field #1 in a line in file 4 and
field #2 in a line in file 4 == field #2 in a line in file 1
我想不出一个解决这个问题的好方法,所以我刚才写了一个暴力 - 愚蠢的 - 4层嵌套循环。我正在考虑将它们按字母顺序排序,即使这可能有点帮助,但是很明显计算机内存不允许我一次加载所有内容。有人能告诉我一个以时间和空间有效的方式解决这个问题的好方法吗?谢谢!
答案 0 :(得分:1)
首先,我注意到你可以在不保存内存的情况下对文件进行排序,并且大多数操作系统都有一些程序执行此操作,通常称为“排序”。通常你可以让它对文件中的一个字段进行排序,但如果没有,你可以重写每一行,让它按你想要的方式排序。
鉴于此,您可以通过对两个文件进行排序来连接它们,以便第一个文件在字段#1上排序,第二个文件在字段#2上排序。然后,您可以为每个匹配创建一个记录,组合所有字段,并且仅在内存中保存每个文件中的一个块,其中您排序的所有字段具有相同的值。这将允许您将结果与另一个文件连接 - 四个这样的连接可以解决您的问题。
根据您的数据,解决问题所需的时间可能取决于您建立连接的顺序。一个相当天真的方法是,在每个阶段,从每个文件中取一个小的随机样本,并使用它来查看每个可能的连接将跟随多少结果,并选择产生最少结果的连接。从大文件中随机抽取N个项目的一种方法是取文件中的前N行,然后,当你读到m行时,读取下一行,然后以概率N /(m + 1)交换为其保留的N条线中的一条,否则扔掉它。继续阅读,直到你读完整个文件。
答案 1 :(得分:0)
这是一种算法:
这种复杂性取决于查找结构的实现。对于位字段,它将是O(1),对于集合或字典,它将是O(lg(n)),因为它们通常被实现为平衡搜索树。完整的复杂性将是O(n)或O(n lg(n));您在问题中的解决方案具有O(n ^ 4)
的复杂性您可以从here
获取位字段的代码和解决方案HTH
答案 2 :(得分:0)
这是一种方法:
我们将使用符号Fxy,其中x =字段编号,y = file_no
对第一个字段中的每个文件进行排序。
对于每个字段F11,在文件2中找到匹配。这将是线性的。将包含所有四个字段的这些匹配项保存到新文件中。现在,使用此文件并使用此文件中的相应字段并从file3获取所有匹配项。继续file4并返回file1。
通过这种方式,当您进入每个新文件时,您处理的行数较少。由于您已对文件进行了排序,因此可以通过从磁盘读取来进行线性搜索。
这里假设m<<<<<<<<<<<<<<<<<<<< Ñ
答案 3 :(得分:0)
更容易解释一下你的文件1是否相反(所以每个第二个元素指向下一个文件中的第一个元素)。
从文件1开始,将其复制到一个新文件,将每个A,B对写为B,A,'REV'
将文件2的内容附加到其中,将每个A,B对写为A,B,'FWD'
对文件进行排序
以具有相同初始值的块的形式处理文件
将下一个文件附加到此新输出文件中(向每行添加“FWD”)
从第3步开始重复
实际上,您正在以相反的顺序构建链,并使用基于文件的排序算法将序列放在一起,可以组合。
当然,将这些文件读入数据库并让它完成工作会更容易......