跳到主要内容

uShuffle:一种在保留k-let计数的同时对生物序列进行洗牌的有用工具

摘要

背景

随机洗牌序列通常用于序列分析,以评估生物序列的统计显著性。在许多情况下,生物学家需要复杂的洗牌工具,这些工具不仅要保存不同字母的计数,还要保存更高阶的统计数据,例如双重数、三重数,而且一般来说,k-算了吧。

结果

我们提出了一个序列分析工具(名为uShuffle),用于生成生物序列(如dna、rna和蛋白质)的均匀随机排列,以保持精确性k-算了吧。uShuffle工具实现了Euler算法的最新变体,并在树形图生成的关键步骤中使用Wilson算法。它经过精心设计,效率极高。uShuffle工具通过允许任意字母表大小和let大小来实现最大的灵活性。它可以用作命令行程序、web应用程序或实用程序库。提供了C、Java和C的源代码,以及Perl和Python的集成说明。

结论

uShuffle工具在性能和灵活性上都优于Euler算法的现有实现。它是生物信息学界的一个有用的工具。

背景

随机洗牌序列通常用于序列分析,以评估生物序列的统计显著性。例如,评估RNA序列热力学稳定性的一种常用方法是将其折叠自由能与大量随机序列的折叠自由能进行比较。众所周知,RNA二级结构的稳定性在很大程度上取决于相邻碱基对的堆积;因此,随机序列中不同双峰的频率是此类分析的重要考虑因素[4,25]. 此外,自然生物序列往往表现出某些最近邻模式:真核和原核核酸序列在双峰频率上表现出一致的层次结构;在编码区域,密码子的使用也可能明显不均匀。在许多情况下,生物学家需要复杂的洗牌工具,这些工具不仅要保存不同字母的计数,还要保存更高阶的统计数据,例如双重数、三重数,而且一般来说,k-算了吧。

随机序列生成方法

有几种方法常用于生成随机序列。这个基本排列法工作原理如下:对于一个序列S[1,n],选择一个随机数介于1和n,交换两个元素S[]以及S[n],然后在子序列上递归S[1,n-1]。由基本排列方法生成的随机序列保留了字母表中每个不同字母的精确计数,但不保留k-算了吧。这个马尔可夫方法[12],它基于马尔可夫链,生成的随机序列保持k-只允许平均计数:单个序列的计数可能偏离输入分布。这个交换法[15]这是一种流行的方法,现在已成为民间传说,它通过反复交换两侧不相交的子序列来生成随机序列(k-1)让;它确实保留了k-let精确计数,但产生的随机序列只能渐近一致,并且可能需要大量交换步骤。

欧拉算法保持精确k-算了吧

Euler算法是一种不太为人所知但非常有效的生成真正均匀随机数的算法k-let保持序列[2,12,15]. 我们简要回顾了它的历史。惠誉[12]首先注意到保二重点的置换与有向多重图的欧拉游走有关;然而,他提出的算法并不是以相等的概率生成所有的置换。阿尔特舒尔和埃里克森[2]提出了第一种算法(也基于有向多重图中的欧拉游动)来生成真正一致的随机序列,既保留了二重计数,也保留了三重态计数,或者同时保留了二者;然而,它们生成随机树状图的算法的一个关键步骤依赖于试错过程,这是一个潜在的性能瓶颈。这个瓶颈被Kandel等人消除了[15]他用一个简单有效的基于有向多重图随机游动的过程代替了试错过程。他们还推广了欧拉算法来保持k-任性算数k提出了一种简单的数据结构来实现。此数据结构基于查找表,需要O(σ2k-二)空间和时间;随着字母表的大小,它很快变得低效σ那么小尺寸呢k增加。自从Kandel等人的工作[15]Wilson提出了一种更好的算法[19,23]生成随机树状图,这是Kandel等人提出的Euler算法的关键步骤[15]改进了阿尔特舒尔和埃里克森[2]. Wilson树形图生成算法与Altschul和Erickson前两种算法相比的优越性[2]Kandel等人[15]都是威尔逊在理论意义上证明的[19,23],并通过将我们的实现与以前的实现(稍后讨论)进行比较来说明实际意义。

欧拉算法的实现

我们知道之前两个欧拉算法变体的实现。这个洗碗机Clote等人的程序[6]由Altschul和Erickson实现Euler算法的原始版本[2]. 这个洗牌科沃德的节目[11]实现了Kandel等人提出的Euler算法的改进版本[15]. 在这篇文章中,我们提出了一个序列分析工具(uShuffle),它可以在保存生物序列的同时对生物序列进行洗牌k-算了吧。uShuffle程序基于Euler算法的最新变体[2,15]使用威尔逊算法[19,23]在树木生长发育的关键阶段。我们的目标是提供尽可能高效和灵活的通用工具:

任意字母大小和let大小

在特定应用中,字母表的大小σ那么小尺寸呢k通常是固定的:对于生物序列,典型的字母表大小是4(对于DNA或RNAs)和20(对于蛋白质),典型的let大小是2(对于二核苷酸)和3(对于密码子)。虽然只为固定的字母表和let大小实现Euler算法很诱人,但我们相信任意字母表和let大小的灵活性是有用的。Clote等人的洗碗机程序[6]例如,它是硬编码的,用于改组保留二核苷酸计数的RNA序列(具有字母表大小)σ=4,让尺寸k=2)。很明显,这样的实现在具有不同字母表和let大小的其他应用程序中不容易使用。

效率

当字母表大小和let大小都是小常数时,Euler算法的运行时间(树形图生成的三个变量中的任何一个)[2,15,23])在序列长度上是线性的。因此,洗牌程序的效率似乎不是问题,因为对随机数据的任何可想象的下游分析都比洗牌慢得多。然而,我们注意到,线性运行时间仅在字母表和let大小恒定的情况下被证明[15]. 对于任意字母表和let大小,Euler算法的线性性能是否可伸缩,目前还不清楚。如前所述,Kandel等人提出的“标准”数据结构[15]空间和时间的关系很复杂O(σ2k-二),当字母表大小σ那么小尺寸呢k变大,接近序列长度的顺序。事实上,正如我们稍后将要讨论的,我们有理由相信这个数据结构已经被Coward用于shufflet程序中[11].

此外,Euler算法(尤其是树形图生成的关键步骤)的实现是非常重要的,因为它大量使用图论概念,如有向多图和欧拉游动。虽然威尔逊著名的算法[19,23]追溯到1996年,并在计算机科学界颇有名气的理论界,科沃德在1999年实现了shufflet[11]仍然使用Kandel等人的旧树形算法[15]. 我们还不知道Wilson算法在生物信息学应用中的任何实现。通过对算法和数据结构的仔细选择,以及通过严谨的算法工程,我们努力实现最有效的实现。

多种形式和编程语言

Clote等人的洗碗机程序[6]是用Python编写的;由Coward编写的shufflet程序[11]是一个C语言的web应用程序。为了让最广泛的用户能够访问,我们已经以多种形式提供了uShuffle程序。它可以用作命令行程序、web应用程序或实用程序库。提供了C、Java和C的源代码,以及Perl和Python的集成说明。

实施

本节由四个小节组成。在前两部分中,我们在概念层面上讨论了Euler算法及其生成树形图的关键步骤,为讨论实现细节做准备。在第三小节中,我们将介绍我们实现的算法工程细节。在第四小节中,我们描述了uShuffle工具的软件组织和用户界面。为了证明我们的算法选择是正确的,并解释我们的优化技术,前三小节中的讨论必然是技术性的。对图算法的理论讨论或算法工程的技术细节不感兴趣的读者可以安全地跳到软件组织和用户界面的第四小节。

欧拉算法

在本小节中,我们将回顾欧拉算法的一些基本概念。

有向多重图

Ak-让是k序列中的连续元素。S是一个要排列的序列。T k 是一个统一的随机序列k-让数S. (例如,T1是一个简单的排列S,和T2是一个排列S用相同的二核苷酸计数)来产生T k 对于k≥2,欧拉算法[2,15]首先构造有向多重图G. 我们指的是1举个例子。为每一个不同的(k-1)-让进来S,G有一个顶点。为每一个k-让在里面S,其中包含两个(k-1)-让12就这样1先于2,G从顶点到1到顶点2. 副本k-我们可以存在于S,因此顶点之间可能有多条边。

图1
图1

序列AATAT的有向多重图。

排列与欧拉游动的对应关系

当我们扫描k-让我们进来S在多重图中,我们也一步一步地走G从一个顶点到另一个顶点。当所有的k-扫描每个边缘G只访问过一次:步行欧拉语. 另一方面,如果欧拉人走进来G,我们可以通过拼写出(k-1)-沿漫游放置顶点(并放弃重叠)。因为每个人k-让进来S对应于G,每一个欧拉人走进来G对应于具有相同k-算作S. Kandel等人[15]表明,只要欧拉行走的起点和终点在同一两个顶点st与开始和结束相对应(k-1)让S,的-让计数全部为1≤k被保存下来。因此,生成一个均匀的随机序列T k 简化为生成均匀的随机欧拉漫游Gst.

欧拉游动与树木景观的对应关系

为了欧拉式的走进来G,每个顶点属于G除了结束顶点t有一个最后边缘e 最后一次。所有顶点的最后一组边,除了t形成乔木扎根于t:所有顶点都可以到达的有向生成树t. 给予树形A扎根于t一次欧拉式的随机行走st最后边缘符合A很容易生成[2,15]:

  1. 1

    对于每个顶点,收集边列表E 退出. 置换每个边列表E 保存时分开e 名单上的最后一条边。

  2. 2

    浏览图表G根据边缘列表{E }:开始于s(套)美国s),取第一个未标记的边(u、 五)从列表中E 美国 ,标记边,然后移动到下一个顶点(套)美国);继续进行,直到所有边都标记好,并且漫游结束于t.

在有向多重图中,欧拉游动和树状图之间有一个很好的对应关系:每一个树形图都根于t与欧拉行走的次数完全相同[,15]. 因此,生成一个均匀的随机欧拉行走Gst简化为在G扎根于t. 在下一小节中,我们将讨论生成随机树状图的算法,其中一些算法是基于非常有趣的随机游动。

生成随机树状图

在对Wilson算法进行回顾的基础上,对我们现有的树形图生成算法进行了评述[19,23]. 生成随机树状图和生成树的主要方法有两种:行列式算法和随机游走算法。

行列式算法

行列式算法基于矩阵树定理[3,第二章,定理14]。对于图形G,特定边缘的概率e在均匀随机生成树中出现的是两个数字的比率:包含边的生成树的数目e,以及生成树的总数。矩阵树定理允许通过计算图的组合拉普拉斯(或基尔霍夫矩阵)的行列式来计算图的生成树的确切数目。随机生成树可以根据边的概率反复收缩或删除。

第一个行列式算法是由Guénoche给出的[14]还有库尔卡尼[16]:对于n顶点和边,可以生成一个随机生成树O(n)时间。这个运行时间后来改进为O(n) [7]. 科尔伯恩、迈尔沃德和纽菲尔德[8]简化了O(n)时间算法并表明运行时间可以进一步缩短到O(n2.376),乘以2的最佳上界n×n矩阵[9].

随机行走算法

随机行走算法使用完全不同的方法来生成随机生成树。阿尔杜斯[1]还有布罗德[5](在与Diaconis讨论了矩阵树定理后)独立地发现了随机生成树和随机游动之间的一个有趣的联系:

在图中模拟均匀随机行走G从任意顶点开始s直到访问所有顶点。对于每个顶点s,收集边缘{u、 五}对应的第一个入口. 收藏T边的均匀随机生成树G.

对于图形G还有一个顶点在其中,定义覆盖时间C (G)作为随机行走开始的预期步数访问的所有顶点G. Aldous-Broder算法的运行时间[1,5]显然是线性的。在改变生物序列的背景下,Kandel等人[15]扩展的Aldous-Broder算法[1,5]生成均匀时间上有向树覆盖的欧拉图。威尔逊和普洛普[24]在此基础上,提出了一种在18个覆盖时间内生成一般有向图的均匀随机树状图的算法。

威尔逊算法

威尔逊[19,23]结果表明,采用循环弹出算法模拟循环消除随机游动,可以比覆盖时间更快地生成随机树状图和生成树。对于图形G和两个顶点美国在其中,定义命中时间h美国,(G)作为随机行走的预期步数美国. Wilson算法的运行时间[19,23]在相应随机图的最大或平均命中次数上是线性的。作为威尔逊[19,23]值得注意的是,平均和最大命中时间总是小于覆盖时间,并且在某些图中差异可能非常显著。因此,对于生成均匀随机树状图,Wilson算法[19,23]优于Kandel等人的算法[15].

为了表示的完整性,我们在下面包含Wilson算法的伪代码[19,23]:

随机化树(r)

1个用于←1至n

InTree公司[]←错误

下一个[r]←无

InTree公司[r]←正确

5个←1至n

美国

7而不是InTree公司[美国]

下一个[美国]←随机化继任者(美国)

美国下一个[美国]

10个美国

11而不是InTree公司[美国]

十二InTree公司[美国]←正确

十三美国下一个[美国]

14返回下一个

E 美国 是从顶点退出的有向边的集合美国. 随机继承函数(美国)选择均匀随机边(u、 五)从E 美国 ,然后返回顶点.

不像Aldous Broder算法[1,5],它模拟从根到访问所有顶点的单个随机行走[19,23]模拟多个随机漫游:从每个未访问的顶点开始,一个随机漫游一直持续到它加入一个最初只包含根的生长树状图。随机漫步下一个[·]指针;每当再次遇到以前访问过的顶点时,就会形成一个循环并立即删除,因为下一个[·]指针被覆盖(在第一个while循环中)。一旦漫游到达正在生长的树状图,则漫游中的所有顶点都将作为一个多分支加入到树形图中。

两种方法的比较

现在我们比较两种生成随机树状图的方法。Kandel等人[15]证明了欧拉有向多重图的覆盖时间n顶点和边缘是O(n2). 根据前面对覆盖时间和命中时间的讨论,可以得出Wilson算法的预期运行时间[19,23]在同一个多重图上最多O(n2)同样,忽略了对数n因素。

对于多重图,数字边的数目可以任意大于n顶点数。因此,Colbourn等人的行列式算法[8],以确定性方式运行O(n)时间甚至是O(n2.376)时间,将是一个比随机游走算法更好的选择[15,19,23]. 但是,我们注意到行列式计算的中间值也可以很大。在当今典型的计算机系统中,浮点数的运算精度不足以保证行列式算法数值计算的精度和稳定性。随机行走算法[15,19,23]另一方面,只需要对小整数进行基本运算,而不存在这些数值问题。因此,我们决定实现Wilson的随机游走算法[19,23]用于树木生长。

实施细节

在本小节中,我们将详细描述我们实现Euler算法的细节[2,15,19,23]用于生成k-让我们保留随机序列。

Kandel等人的数据结构

正如Kandel等人所建议的那样[15],Euler算法的一个简单实现[2,15]可以使用一个大小的查找表σk-1尽一切可能(k-1)-让作为有向多重图中的顶点G,然后构造一个大小为的邻接矩阵σk-1×σk-1对于边缘G. 当两者都σk都是小常数,这个简单方法的空间要求,σ2k-二,可能看起来不严重。然而,计算表明,即使σ=20(蛋白质的字母表大小)和k=3(典型的选择k),所需空间相当于

σ2k-二=20个4=16万。

另一方面,蛋白质序列的典型长度低于1000。即使序列本身可能只存储在1KB字节中,但是置换算法仍然需要数百倍的空间。k进一步增加了:即使是看起来很无辜的参数σ=20和k=5,空间要求

σ2k-二=20个8>168=2个32

超过了32位计算机所能容纳的4GB内存!我们注意到这两组参数[11]用于他的shufflet程序的实验只有

σ=4,k=6,σ2k-二=1048576

σ=20,k=3,σ2k-二=16万。

在结果和讨论部分,我们将在uShuffle和shufflet的比较中对此进行更多讨论。

线性空间中有向多重图的表示

为了使uShuffle程序具有可伸缩性,很明显在实现过程中需要仔细的算法工程。正如我们在上一节讨论的Euler算法,有向多重图G包含每个不同的顶点(k-1)-让进来S. 因为(k-1)-进入S是的-k+2个,G最多有-k+2个顶点,因此-k+1个连续边之间的定向边(k-1)让我们。这意味着G实际上长度是线性的序列的S被置换。使用合适的数据结构,uShuffle只需要线性空间。

在下面,我们首先解释有向多重图的构造和表示G然后对图构造后的随机序列生成进行了说明。图的构造包括两个步骤:确定顶点集,然后添加有向边。

确定顶点

我们使用哈希表来确定顶点集。哈希表由一个大小为的bucket数组组成b=-k+2,数量(k-1)进入S并在每个链表上链接以避免碰撞[10]. 每个(k-1)-让=12k-1有一个多项式散列码

h ( ) = 1 k 1 + 2 k 2 + + k 2 2 + k 1 = ( ( ( 1 + 2 ) + + k 2 ) + k 1 ) , 5@5@5@5@5@5@5@5@5@5@5@5@5@5@5年来,一年四季如一年一次地将一年四季如一次、九年如一次、一次八年七夕五年如一年一次的七八年如一年一次的八年七八年一年八年的九年七八年七八年七八年前九年是八年七五五五五五@五年五五五五@五年五年五五五年五年五年五年五年五年五年五年五年五年五年五年五年五年五年五年五年一年七八年七八年七八年七八年七八年七八年七八年的五年Aoabdiha4jabcmcpaqaaiabg2da9aqaaabdih4naabaaleaacqaiqaqaaaogaemyyae2aa又比如说,又是一个什么样的问题,没有一个整体的问题,这个问题,这个问题,这个问题,这个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一个问题,一岩井Ikagiaemiag3aasbaasqaabaigdaxaqbagcqwghbqycqrawkcqwg4baedawgaawgawcbagaaegomaidabeakiabccmcapiabdgahjabgucariabl+uimjabgucariababdiha4naabaaleacqwgrbwacqsislcqiyagmaeqaaaogaeiykakakiaemay4kaiamey4kaiameag3aasbasqaaasbagsbagkitiabgkitiabigdaxaqqqgqggaqgqgqgkabaqgkabaqwgkabaqwgqyqygzalaaaaaaaaa@762E@

哪里= ( 5 1 ) 5@5@5@5@5@5@5@5@5@5@5@5@5@5@5年多的PBIQV92AA一方面又将一批又一批巴博布布布布告的HHfHyFGAsaac6xni=x8vivivi8gi=heeu0xxxDbA9fFfj0xb9QQQgDXD99亚斯皮I8K8FII+fsY==RQGQVePaE9PG9VQAVQVQGFR0xFR=xfr=xfr=xfr=XC9dBAQaegagagaga因加加加加亚加加加加亚加加加加加加加亚加亚加亚加亚加亚加亚加亚电话:3081@ /2是黄金比率的倒数;指数到桶阵列是

() =h(b国防部b.

将哈希表初始化为空,然后尝试插入(k-1)让我们逐个进入哈希表。如果(k-1)let是第一个,它被分配一个新的顶点编号,然后插入哈希表;它的起始索引是序列S也被记录下来了。如果(k-1)-let之前已经插入过,它没有插入到哈希表中:它的顶点编号和索引指向序列S是从第一个复制的(k-1)就这样吧。在插入之后,我们可以从指定的最大顶点数中推断出有向多重图的顶点总数。然后为顶点分配内存。

添加定向边

为了增加有向边,我们使用邻接列表表示来避免邻接矩阵对内存的过度需求。在邻接列表表示法中,每个顶点需要维护两个边列表:一个是传入边的列表,一个是传出边的列表。输出边列表是生成欧拉行走所必需的[2]. 当Kandel等人的算法生成树状图时,引入的边列表是必要的[15]被使用(如在coverd的实现中[11]). 我们用威尔逊算法[19,23]产生树状景观。正如我们在上一节讨论的,Wilson算法[19,23]比Kandel等人的算法快[15]. 此外,我们注意到Wilson的算法[19,23]与Kandel等人的算法相比有另一个优势[15]在易于实施方面。而不是一个向后的从结束顶点随机行走t达到所有其他顶点,如Kandel等人的算法[15]威尔逊算法[19,23]使用多个向前地从每个未访问的顶点随机行走以加入根在的树状图t:仅输出边缘列表就足以生成欧拉行走和树状图。

表示边缘列表和管理内存

为了获得最大的效率,我们将每个边列表实现为一个顶点数组。输出边的数量因顶点而异;如果我们为每个顶点分配一个固定大小的数组,那么在最坏的情况下,我们必须使每个数组足够大,以容纳所有边,由此产生的空间需求将成为长度的二次方序列的S. 当然,我们可以先计算每个顶点的输出边数,然后为每个顶点分配一个足够大的单独数组。然而,这需要我们为每个顶点调用一次相对昂贵的内存分配函数。

在我们的实现中,我们为所有边分配一个大数组(边的总数是-k+1),然后将块分割到各个顶点。为了达到这个目的,我们首先扫描序列S要计算每个顶点的传出边数,请将每个顶点的数组(传出边列表)指向大数组的连续偏移量。通过这种优化,内存分配的数量减少到只有4个:一个用于hashtable bucket数组,一个用于(k-1)-将其中一个顶点数组和一个边数组作为哈希表条目。一旦构造了有向多重图,就可以释放bucket数组和哈希表项的内存。

图构造后的序列生成

在构造有向多重图之后,我们可以分三步生成一个随机序列。如前一节所讨论的,我们需要首先模拟循环擦除的随机游动[19,23]为了生成一个树形图,接下来在保持最后一条边的同时置换各个边列表,然后模拟由边列表引导的欧拉漫游,并沿行走输出序列。由于每个边列表都被实现为一个数组,所以可以非常高效地执行置换。沿着行走输出随机序列也很容易,因为每个顶点都保持其在输入序列中第一次出现的起始索引。

uShuffle工具的软件组织和用户界面

在本小节中,我们将描述uShuffle工具的软件组织和用户界面。

C库和命令行工具

uShuffle的最初实现是用C编程语言实现的。uShuffle的C版本包含两个组件:uShuffle库(uShuffle.C和uShuffle.h)和命令行工具(main.C)。

在典型的场景中,多个k-为每个输入序列生成保持随机序列。对于多个输出序列,uShuffle程序的图形构造阶段只需要完成一次。为了给用户一个优化的选择,我们在uShuffle库中导出了三个接口函数:

void shuffle(const char*s,char*t,int l,int k);

void shufflue1(const char*s,int l,int k);

无效洗牌2(char*t);

函数shuffle接受四个参数:s是要置换的序列,t是输出随机序列,l是s的长度,k是let大小k. shuffle函数只需先调用shuffle 1,然后调用shuffle 2:shuffle1实现有向多图的构造;shuffle 2实现有向多图中循环消除的随机游动和随机序列的生成。随机排列的统计行为很大程度上依赖于随机数发生器。

懦夫[11]注意到随机数生成器在各种平台上的默认实现通常不令人满意,因此他使用一种可以证明更好的算法实现了自己的生成器。我们注意到随机数生成有很多算法,并且不断有新的算法被提出:一个算法是否优于另一个算法可能是相当主观的。我们没有将用户限制在特定的实现中,而是将默认生成器设置为标准C库中的random函数,然后导出一个接口函数以允许高级用户自定义生成器:

typedef long(*randfunc_t)();

空集合_randfunc(randfunc_t randfunc);

命令行uShuffle工具是uShuffle库的最小前端,它演示了该库的典型用法。它有以下四个选项:

  • s<string>指定输入序列,

  • n<number>指定要生成的随机序列的数量,

  • k<number>指定let大小,

  • seed<number>指定随机数生成器的种子。

Java小程序

uShuffle程序被移植到Java编程语言中。除了有一个库和一个命令行工具外,uShuffle程序的Java版本还可以作为web浏览器中的applet运行。我们指的是2获取uShuffle Java applet的屏幕截图1:小程序的界面很小,由三部分组成:顶部是输入文本区域,底部是输出文本区域,中间是控制面板。控制面板包含两个文本字段和一个按钮。最大let大小k号码呢n可以在两个文本字段中设置输出序列。当点击“Shuffle”按钮时,applet从输入文本字段中获取输入序列,去掉空白,生成n保留k-输出区域,然后计算输出序列。n>1:每个输出序列前面都有一个注释行,其中包含从1到的序列号n.

图2
图2

uShuffle Java小程序的屏幕截图。

uShuffle Java小程序将所有输出序列保存在内存中,以便在输出文本区域中显示。当号码n输出序列和输入序列长度大得惊人,例如,n=10000万=100时,保存输出序列所需的总内存可能超过Java虚拟机(JVM)的最大堆大小,小程序可能挂起。这不是我们程序中的错误,而是由于JVM的限制;尽管如此,我们准备了一个网页来指导用户如何增加JVM的最大堆大小。

C#/Perl/Python版本

uShuffle程序也被移植到C语言中。Perl和Python是生物信息学的流行编程语言;它们允许与用C编写的程序轻松集成。我们没有在源代码级别将uShuffle程序移植到Perl和Python上,而是准备了两个网页来指导用户如何使用uShuffle库扩展Perl和Python环境。

结果与讨论

为了测试uShuffle工具的两种主要形式的性能,我们进行了两组实验:首先对uShuffle C库的性能进行了基准测试,然后将uShuffle Java applet的性能与Coward的shufflet程序进行了比较[11].

uShuffle C库的性能

我们在台式机上测试了uShuffle C库2测试数据包括真实生物序列和人工生成的随机序列。

真实生物序列实验

从两个方面获得了真实的生物序列:首先,从人类蛋白质参考数据库中提取了152个蛋白质序列(共91262个氨基酸)从152个分子类中各提取一个序列;第二,从补充数据中提取出家鼠(Mus.musculus)69个微RNA前体序列(共4773个核苷酸)4Bonnet等人[4].

我们对这些真实生物序列的实验表明,uShuffle库是非常有效的:在一秒钟内,它可以生成(i)152个蛋白质序列中每一个的700个双峰保留随机序列,或者(ii)69个RNA序列中的每个序列生成12000个双重保留随机序列。

人工生成随机序列的实验研究

为了分析uShuffle在各种参数下的性能,我们还对人工生成的随机序列进行了uShuffle的系统测试。为了简单起见,序列长度是2的幂次方12到224也就是说,从4000到16000000。这些数字多少有点武断;只要计算机有足够的内存来存储输入序列,并且有我们实现所需的一些额外的(非常小的,如实现部分所述)内存,没有什么可以阻止用户在非常长的序列上运行uShuffle,即使在基因组规模上也是如此。

对于每个序列长度,生成英语字母[a-z]上的64个均匀随机序列作为测试序列;对于每个测试序列,64个k-然后由uShuffle生成保持随机序列。uShuffle生成64×64=4096的总运行时间k-对每个序列长度记录保持随机序列。在测试程序中放置了两个getrusage系统调用,以将被基准测试的代码区域夹在一起;这两个时间戳的差异用于计算运行时间。

我们指的是的uShuffle程序总运行时间的日志图k=2和k=3,不同序列长度。该图显示,uShuffle程序的运行时间在要洗牌的序列长度上基本上是线性的。

图3
图3

uShuffle的运行时间 k =2和 k =3. uShuffle在不同序列长度下的运行时间(毫秒)k=2和k=3。

绝对运行时间并不能很有效地证明uShuffle程序的极端效率。我们指的是4对于一个更具说明性的比率图。k=2和k=3,对于每个序列长度,曲线图显示的不是uShuffle程序的绝对运行时间,而是两个运行时间的比率:

图4
图4

运行时间比率 k =2和 k =3. 不同序列长度下uShuffle的运行时间比和简单置换法k=2和k=3。

  1. 1

    uShuffle程序生成k-保留序列,并且

  2. 2

    简单排列法的运行时间[10](在背景部分中回顾)洗牌相同数量的随机序列没有保存k-算了吧。

比率图表明,uShuffle程序的运行时间平均只有简单排列法的1.5倍k=2,且仅2次k=3。对于一个简单的置换函数,它只执行一个简单的置换函数。另一方面,uShuffle程序执行更多的工作;尽管64k-让每个测试序列的保留随机序列由一个shuffle1和64个shuffle2函数调用生成,以避免冗余的多图构造,每个shuffle2函数调用仍然包括通过循环删除的随机游动生成树形图[19,23]以及一个欧拉行走的生成由简单排列的单个边缘列表引导。考虑到uShuffle程序和简单排列方法的复杂性,它们的运行时间比例很小。细心的读者会从图中注意到一个有趣的事实4,当序列长度增加到2时24(大约1600万),uShuffle程序的运行时间k=2是偶数少于简单的排列方法!这个“奇怪”的现象让我们困惑了很久,直到我们最终确信这不是一个bug而是一个特性。我们注意到,在每一步中,简单置换方法随机交换分散在2个大数组中的两个元素24元素。另一方面,uShuffle程序在小的多重图中执行随机游动(对于k=2且在[a-z]字母表上)并排列各个边列表(每个列表大约有2个)24/26个元素)。uShuffle程序的内存引用要多得多地方的而不是简单的排列法。具有现代内存体系结构的计算机通过复杂的缓存方案积极地优化具有本地内存引用的代码,从而提高了uShuffle程序的性能。

我们指的是5对于uShuffle程序在不同参数值下的运行时间k,其中测试序列长度固定为1024。uShuffle程序的运行时间在k=4,大约是其运行时间的三倍k=2,然后随着k增加,最后在k=1024,因为序列长度为1024,唯一保留随机序列的1024 let是输入序列本身。此图显示uShuffle程序对所有可能的值都是有效的k.

图5
图5

uShuffle在不同尺寸下的运行时间 k. 对于不同的let大小,在固定序列长度下uShuffle的运行时间(毫秒)k.

uShuffle Java Applet与shufflet的比较

欧拉算法还有另外两种实现。Clote等人的洗碗机程序[6]由Altschul和Erickson实现Euler算法的原始版本[2]. dishuffle是一种硬编码的用于乱排保留二核苷酸计数的RNA序列,它不是任意字母表和let大小的通用工具。另一个节目,被懦夫洗牌[11],实现了Kandel等人提出的Euler算法的改进版本[15]对于任意的let大小k. 正如我们在实现部分所解释的,Kandel等人的树形图生成算法[15]优于Altschul和Erickson的算法[2],仍然不如Wilson算法[19,23]此外,它的查找表数据结构对于大型字母表和let大小来说效率低下。

在功能方面,shufflet实现[11]更接近于我们的uShuffle实现。Shufflet是用C编程语言编写的,曾作为一个web应用程序托管(但是已经离线)。我们无法对uShuffle和shufflet进行全面的比较。但是,懦夫[11]在DEC/2100数字服务器上进行了两个实验:

  1. 1

    对10000个核苷酸的DNA序列进行100次洗牌k=6约2.5秒;

  2. 2

    1000个氨基酸组成的蛋白质序列k=3不到1秒。

我们在苹果iMac电脑(运行MacOS 10.4.9、Firefox 2.0.0.3和Java 1.5.0的2GHz PowerPC G5)上对uShuffle Java applet进行了类似的实验:

  1. 1

    10000个核苷酸序列的1000次洗牌k=6约1.5秒;

  2. 2

    1000个氨基酸组成的蛋白质序列k=3不到1秒。

假设这两台计算机的性能相当,我们估计在核苷酸实验中,uShuffle-javaapplet的速度大约是shuffle的15-20倍(k=4),在氨基酸实验中比shufflet快40倍(k=20)。

我们当然理解这种比较的困难:1999年的web服务器与2005年的台式机;本机中的C程序与虚拟机中的javaapplet。然而,比较说明了我们的ushufflejavaapplet对于大的let大小具有更好的可伸缩性。这两个性能比率(15–20与40)之间的差异表明,uShuffle即使在较大的let大小下也仍然有效,而shuffle随着let大小的增加而变得更加低效,这是由于(很可能)使用了Kandel等人的低效查找表数据结构[15].

结论

uShuffle工具基于高级图形算法,经过精心设计,非常高效。它通过允许任意字母表大小和let大小来实现最大的灵活性,并且有多种形式可供不同类型的用户使用。我们相信uShuffle是生物信息学界的一个有用的工具。

可用性和要求

项目名称:uShuffle。

项目主页:http://www.cs.usu.edu/~mjiang/ushuffle/

操作系统:独立于平台。

编程语言:C、Java、C#、Perl、Python。

其他要求:无。

许可证:FreeBSD。

非学术人士使用的任何限制:无。

注意

1MacOS 10.4.9、Firefox 2.0.0.3、Java 1.5.0。

2Dell XPS M1710:2.1 GHz Intel双核2处理器,2 GB双列直插式RAM;Microsoft Windows Vista商务版,Cygwin 1.5.24,gcc 3.4.4,带-O3选项。

http://www.hprd.org/molecleClass.

4http://bioinformatics.psb.ugent.be/supplementary_data/erbon/nov2003/.

工具书类

  1. 1

    均匀生成树和均匀标记树的随机游走构造。暹罗离散数学杂志1990年,3(4):450–465。

    文章 谷歌学者 

  2. 2

    Altschul SF,Erickson BW:核苷酸序列比对的意义:一种保留二核苷酸和密码子使用的随机序列排列方法。分子生物学与进化1985年,2(6):526–538。

    中情局 公共医疗 谷歌学者 

  3. 三。

    博洛巴斯B:现代图论。斯普林格;2002年。

    谷歌学者 

  4. 4

    Bonnet E,Wuyts J,RouzéP,van de Peer Y:有证据表明,与其他非编码RNA不同,microRNA前体比随机序列具有更低的折叠自由能。生物信息学2004年,20(17):2911–2917。

    中情局 文章 公共医疗 谷歌学者 

  5. 5

    布罗德A:生成随机生成树。第三十届计算机科学基础年会论文集(FOCS's89)1989年,442–447年。

    谷歌学者 

  6. 6

    clotep,Ferr'ef,Kranakis e,krizancd:结构RNA的折叠能量比相同二核苷酸频率的随机RNA低。核糖核酸2005年,11:578–591。

    公共医学中心 中情局 文章 公共医疗 谷歌学者 

  7. 7

    Colbourn CJ,Day RPJ,Nel LD:图的生成树的解列和排序。算法杂志1989年,10:271-286。

    文章 谷歌学者 

  8. 8

    Colbourn CJ,Myrvold WJ,Neufeld E:两种解列树状图的算法。算法杂志1996年,20(2):268–281。

    文章 谷歌学者 

  9. 9

    Coppersmith D,Winograd S:通过算术级数的矩阵乘法。符号计算杂志1990年,9:251-280。

    文章 谷歌学者 

  10. 10

    Cormen TH、Leiserson CE、Rivest RL、Stein C:算法概论. 第二版。麻省理工学院出版社;2001年。

    谷歌学者 

  11. 11

    懦夫E:洗牌:洗牌序列的同时保留k-let计数。生物信息学1999,15(2):1058-1059。

    中情局 文章 公共医疗 谷歌学者 

  12. 12

    惠誉WM:随机序列。分子生物学杂志1983年,163:171-176。

    中情局 文章 公共医疗 谷歌学者 

  13. 13

    Freyhult E,Gardner PP,Moulton V:RNA折叠测量的比较。BMC生物信息学2005年6:241。

    公共医学中心 文章 公共医疗 谷歌学者 

  14. 14

    随机生成的树:诺卡树。算法杂志1983年,4:214-220。

    文章 谷歌学者 

  15. 15

    Kandel D,Matias Y,Unger R,Winker P:混乱的生物序列。离散应用数学1996,71(1-3):171-185。

    文章 谷歌学者 

  16. 16

    Kulkarni VG:生成随机组合对象。算法杂志1990,11(2):185–207。

    文章 谷歌学者 

  17. 17

    Le S-Y,Chen J-H,Currey KM,Maizel JV Jr:一个预测重要RNA二级结构的程序。计算机在生物科学中的应用1988年,4(1):153-159。

    中情局 公共医疗 谷歌学者 

  18. 18

    Nussinov R:DNA中核苷酸顺序的一个规则。核酸研究1980年,8(19):4545–4562。

    公共医学中心 中情局 文章 公共医疗 谷歌学者 

  19. 19

    Propp JG,Wilson DB:如何从一般马尔可夫链中获得完全随机样本并生成有向图的随机生成树。算法杂志1998,27(2):170–217。

    文章 谷歌学者 

  20. 20

    Rivas E,Eddy SR:仅二级结构对于检测非编码RNA通常没有统计学意义。生物信息学2000年,16(7):583–605。

    中情局 文章 公共医疗 谷歌学者 

  21. 21

    Seffens W,Digby D:mrna的负折叠自由能比随机序列或密码子选择随机序列大。核酸研究1999,27(7):1578-1584。

    公共医学中心 中情局 文章 公共医疗 谷歌学者 

  22. 22

    Smith TF,Waterman MS,Sadler JR:核酸序列功能域的统计特征。核酸研究1983年,11(7):2205-2220。

    公共医学中心 中情局 文章 公共医疗 谷歌学者 

  23. 23

    Wilson DB:比覆盖时间更快地生成随机生成树。第28届ACM计算理论年会论文集(STOC'96)1996年,296-303。

    谷歌学者 

  24. 24

    Wilson DB,Propp JG:如何在覆盖时间内从一般Markov链中获取精确样本,并从有向图中抽取随机生成树。第七届ACM-SIAM离散算法年会论文集(SODA'96)1996年,448-457。

    谷歌学者 

  25. 25

    Workman C,Krogh A:没有证据表明mRNAs比具有相同二核苷酸分布的随机序列具有更低的折叠自由能。核酸研究1999年,27(24):4816–4822。

    公共医学中心 中情局 文章 公共医疗 谷歌学者 

下载参考资料

致谢

我们感谢匿名评论者的宝贵意见。这项研究得到了国家科学基金会DBI-0743670和犹他州立大学A13501的部分资助。

作者信息

隶属关系

作者

通讯作者

通信对象蒋明辉.

附加信息

作者的贡献

MJ设计了软件和实验,实现了uShuffle程序的C和Java版本,并编写了技术报告。JA将Java程序移植到C#,调查软件许可证,并设计uShuffle徽标。JG编写了测试程序,进行了实验,并编写了Perl集成的指令。MM编写了javaapplet接口和Python集成说明。所有作者都回顾了源代码,并对主页的构建做出了贡献。

作者提交的原始图像文件

权利和权限

本文以BioMed Central Ltd.的授权发布。这是一篇开放获取的文章,根据Creative Commons归属许可的条款分发(http://creativecommons.org/licenses/by/2.0),允许在任何媒介中不受限制地使用、分发和复制,前提是原著被正确引用。

转载和许可

关于这篇文章

引用这篇文章

江,M.,安德森,J.,吉莱斯皮,J。等等。uShuffle:一个有用的工具,可以在保持k-let计数的同时洗牌生物序列。BMC生物信息学 9个,192(2008年)。https://doi.org/10.1186/1471-2105-9-192

下载引文

关键词

  • 跨度树
  • 掩护时间
  • 字母表大小
  • 边缘列表
  • 欧拉算法
\