深圳杯B题DNA序列论文.docx
- 文档编号:10522197
- 上传时间:2023-02-17
- 格式:DOCX
- 页数:25
- 大小:244.14KB
深圳杯B题DNA序列论文.docx
《深圳杯B题DNA序列论文.docx》由会员分享,可在线阅读,更多相关《深圳杯B题DNA序列论文.docx(25页珍藏版)》请在冰豆网上搜索。
深圳杯B题DNA序列论文
封一
答卷编号(参赛学校填写):
答卷编号(竞赛组委会填写):
论文题目:
B题
组别:
本科生
参赛队员信息(必填):
姓名
年级专业
学号
联系电话
参赛队员1
邓鑫
14机制二班
参赛队员2
徐晓睿
14机制二班
参赛队员3
陈杰
14机制二班
指导教师:
____刘宪敏_
参赛学校:
沈阳农业大学
封二
答卷编号(参赛学校填写):
答卷编号(竞赛组委会填写):
评阅情况(学校评阅专家填写):
学校评阅1.
学校评阅2.
学校评阅3
____
评阅情况(联赛评阅专家填写):
联赛评阅1.
联赛评阅2.
联赛评阅3.
DNA序列的k-merindex问题
摘要:
随着生物技术和计算机技术交叉,合作的范围不断地扩大,深度不断地加深,字符串匹配在生物科学的信息检索领域有着广泛的应用,生物研究对DNA序列的碱基信息快速搜索的要求也与日俱增,DNA序列的k-merindex问题研究日益突出。
本文在查阅了相关文献资料后,基于“数据结构”中的“Sunday算法[7]”,我们给出了一种函数覆盖优化Sunday算法,对DNA序列的k-merindex问题中给出固定值k,进行碱基片段查找。
函数覆盖优化Sunday算法对所给出的大量数据的碱基序列先运用函数覆盖,同时把DNA序列进行分组预处理。
当数据链接时用函数覆盖,将整个DNA序列数据划分成若干个小的区域,然后再针对若干个小区域进行碱基片段的匹配。
在划分小区域时,首先将每个小区域的末端多划分四个属于下个区域的碱基,其次在匹配的过程中需要按给定k值对小区域进行分组,之后再用算法对碱基片段进行匹配,最后再统计所有小区域与所要查找的碱基片段的匹配信息。
匹配时经过优化后的算法能够实现同时对划分的所有区域进行查找,直到与所有DNA序列都进行了匹配。
当匹配成功时,首先会自动将char*格式强制转换成void*格式,然后通过DNA碱基片段中第一个字符的指针访问DNA序列,最后输出DNA碱基片段中第一个字符的(常量)地址。
函数覆盖优化Sunday算法后的主要特点:
查找速度简洁、高效、执行速度快。
函数覆盖优化Sunday算法,因为快速跳跃匹配和多区域同步搜索的特征使它可以快速的生成数据和信息。
实现了对DNA序列数据库的查找,在DNA序列中可以得到固定k长度的碱基片段的位置。
关键词:
Sunday算法,函数覆盖,字符串匹配,碱基序列,数据库。
1问题重述
给定一个DNA序列,这个系列只含有4个字母ATCG,如S=“CTGTACTGTAT”。
给定一个整数值k,从S的第一个位置开始,取一连续k个字母的短串,称之为k-mer(如k=5,则此短串为CTGTA),然后从S的第二个位置,取另一k-mer(如k=5,则此短串为TGTAC),这样直至S的末端,就得一个集合,包含全部k-mer。
如对序列S来说,所有5-mer为
{CTGTA,TGTAC,GTACT,TACTG,ACTGT,TGTAT}
通常这些k-mer需一种数据索引方法,可被后面的操作快速访问。
例如,对5-mer来说,当查询CTGTA,通过这种数据索引方法,可返回其在DNA序列S中的位置为{1,6}。
解决以下问题:
现在以文件形式给定100万个DNA序列,序列编号为1-1000000,每个基因序列长度为100。
(1)要求对给定k,给出并实现一种数据索引方法,可返回任意一个k-mer所在的DNA序列编号和相应序列中出现的位置。
每次建立索引,只需支持一个k值即可,不需要支持全部k值。
(2)要求索引一旦建立,查询速度尽量快,所用内存尽量小。
(3)给出建立索引所用的计算复杂度,和空间复杂度分析。
(4)给出使用索引查询的计算复杂度,和空间复杂度分析。
(5)假设内存限制为8G,分析所设计索引方法所能支持的最大k值和相应数据
查询效率。
(6)评价索引方法性能。
包括:
索引查询速度,索引内存使用,8G内存下,
所能支持的k值范围,建立索引时间。
2符号说明
iostream类(文件输入流和输出流类)[2]
a:
构造方法:
#include
创建文件输入流类对象和已存在的文件相关联。
文件不存在的话,并创建。
如:
#include
\Users\dengxin\Desktop\DNA);
b:
#include
创建文件输出流类对象和已存在的文件相关联,并设置该该流对文件的操
作是否为续写。
如:
#include
\Users\dengxin\Desktop\DNA,at+);
c:
表示在#include
主要方法:
#include
当执行完此方法后,字符数据还并没有写入到目的文件中去。
此时字符数据会保存在缓冲区中。
此时在使用memcpy函数就可以使数据将目标数组地址增加到要追加数据的地址,从而保存到目的文件中去。
d:
定义函数:
voidexit(intstatus)
exit()用来正常终结目前进程的执行,并把参数status返回给父进程,而进程所有的缓冲区数据会自动写回并关闭未关闭的文件.。
在关闭后,再写入或者刷新
的话,会显示EOF异常。
字符串读写函数
a:
定义一个头文件,此文件是输入类对象,头文件是关联于源文件。
#include
b:
主要方法
读字符函数fgets(字符数组名,n,文件指针);
其中的n是一个正整数。
表示从文件中读出的字符串不超过n-1个字符。
在读入的最后一个字符后加上串结束标志'\0'。
例如:
fgets(str,n,fp);的意义是从fp所指的文件中读出n-1个字符送入字符数组str中。
写字符函数fputc(字符量,文件指针);
fputc函数的功能是把一个字符写入指定的文件中。
其中,待写入的字符量可以是字符常量或变量。
例如:
fputc('a',fp);其意义是把字符a写入fp所指向的文件中。
exit()用来正常终结目前进程的执行,释放与之关联的所有资源。
数据块读写函数fread和fwrite;
C语言还提供了用于整块数据的读写函数。
可用来读写一组数据,如一个数组元素,一个结构变量的值等。
读数据块函数fread(buffer,size,count,fp);[6]
写数据块函数fwrite(buffer,size,count,fp);
其中:
•buffer:
是一个指针,在fread函数中,它表示存放输入数据的首地址。
在fwrite函数中,它表示存放输出数据的首地址。
•size:
表示数据块的字节数。
•count:
表示要读写的数据块块数。
•fp:
表示文件指针。
假设在发生碱基不匹配时S[i]≠T[j],1≤i≤N,1≤j≤M。
此时已经匹配的碱基片段为u,并假设字符串u的长度为k,如图1。
[8]明显的,S[L+i+1]肯定要参加下一轮的匹配,并且T[M]至少要移动到这个位置(即模式串T至少向右移动一个字符的位置)。
每组DNA碱基序列中,当第一个K长度中没有子串(碱基片段)出现时,这个时候碱基片段的第一个碱基移动到k长度碱基之后的碱基的位置。
图1Sunday算法不匹配的情况
分如下两种情况:
(1)S[L+i+1]在模式串T中没有出现。
这个时候模式串T[0]移动到S[L+i+1]之后的字符的位置,如图2。
图2Sunday算法移动的第1种情况
(2)S[L+i+1]在模式串中出现。
这里S[L+i+1]从模式串T的右侧,即按T[M-1]、T[M-2]、…T[0]的次序查找。
如果发现S[L+i+1]和T中的某个碱基相同,则记下这个位置,记为k,1≤k≤M,且T[k]=S[L+i+1]。
此时,应该把模式串T向右移动M-k个字符的位置,即移动到T[k]和S[L+i+1]对齐的位置,如图3。
图3Sunday算法移动的第2种情况
依次类推,如果碱基完全匹配了,则碱基片段匹配成功;否则,再进行下一轮的移动,直到主串S的最右端结束。
对于碱基片段的匹配问题,该算法执行速度较快。
3模型建立与求解
3.1函数覆盖分组
首先根据题目所给的文件中有100万行的碱基序列,[1]其中每行序列的长度为100,我们用二维数组a[1000000][100]存储所给的碱基序列,函数覆盖对DNA序列进行分组,用指针数组将整个DNA序列分成若干小区域,我们要做的就是取定一个固定的k值,将每行序列分成100-k+1个长度为k的序列,查询某序列在DNA碱基序列中的编号和位置。
3.2算法匹配
Sunday算法是从前往后匹配,[4]在匹配失败时关注的是碱基片段中参加匹配的最末位碱基的下一位碱基,如果该碱基没有在匹配串中出现则直接跳过,即移动步长=匹配串长度+1,如果DNA序列中匹配字符串的右侧一个碱基没在子串中,碱基片段移动步长=整个k长度碱基的距离+1,如果DNA序列中匹配范围内的右侧一个字符在子串中,碱基片段移动距离=子串长度-这个字符在子串中的位置。
3.3输入k,s
将输入的特定的k个碱基片段在100万行分成不同几个小序组中,[5]以跳跃匹配的形式进行匹配。
3.4位置输出
从左向右匹配过程中,当遇到不匹配的时候,看DAN序列中匹配范围之外的右侧第一个字符在子串中的最右位置,根据事先计算好的移动步长移动DAN序列指针,直到匹配,程序会输出所有要查找碱基片段的位置。
(如果遇到重复的碱基片段和查找的k长度碱基片段相同的情况,我们在文章后面进行了分析和处理。
)
3.5程序流程
建立索引(数据流图):
匹配完所有DNA序列后,对匹配成功的碱基片段输出相应地址。
3.6模型模拟
3.61 用函数覆盖优化Sunday算法对数据进行检验,先在100行序列DNA序列中试运行此算法,当k=5,序列s是AACAG时。
3.62用优化后的算法对所有DNA进行检索,在100wDNA序列划分成的若干个小区域同时搜索,当k=10时,程序运行后的结果和生成的文件。
3.63给出固定值k,序列s后,对所有DNA序列数据进行匹配后,运行出的文件。
由于k-mer【10】长度如果过长,导致字符串没有被分配的空间,会造成内存不够溢出的现象。
3.64 复杂度分析
索引的时间复杂为:
O(N*M)
索引时,需要将准备搜索的k长度碱基片段与所有的DNA序列进行匹配,所以该算法最坏情况下的时间复杂度为O(N*M)。
4模型检验
4.1贪婪算法的概念
贪婪算法是一种对某些求最优解问题的更简单、更迅速的设计技术。
[3]用贪婪法设计算法的特点是一步步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,它省去了为找最优解要穷尽所有可能而必须消耗的大量时间,它采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解。
4.2贪婪算法的求解
先把碱基片段(子串)与DNA序列(字符串)左边对齐,当在第二个碱基处发现不匹配,要把子串往后移动,第二个碱基是必定要参加下一步的比较的,需要移动子串,使子串中的最右边的这个碱基与字符串对齐。
现在k长度的子串不存在,则说明可以直接跳过一大片,从与第二个碱基一样的碱基之后的那个碱基开始作下一步的比较,直到第k个碱基匹配成功。
查找出这组中完全匹配成功的碱基片段,如果没有则继续向下一组中循环查找,直到查找到它的位置,再用强制转换输出它的地址。
流程图如下:
5模型评价
5.1模型的优缺点
5.1.1优点
1.函数覆盖优化Sunday算法后的方法通过对数据先进行划分,划分成若干个小区域后再进行同步搜索,查询速度远快于Sunday算法并且简洁有效。
2.函数覆盖使用时,因为DNA序列地址在基类中被说明为虚函数,[11]那么我们所查找的碱基片段也自动成为虚函数,查找时函数覆盖会根据指针所指向的碱基调用对应的虚函数.实现动态联编。
3.使用函数覆盖时指针的类型是可以强行转换的,便于输出匹配碱基的地址。
5.1.2缺点
虽然对Sunday算法用函数覆盖进行了优化,但是当查找模式串越长时,此算法的下一个字符在模式串中出现的概率就越大,无效匹配的次数就越多,导致内存的浪费。
6参考文献
1.严蔚敏,吴伟民;《数据结构[M]》;清华大学出版社;1998.
2.谭浩强;《c程序设计[M]》;清华大学出版社;1991.
3.白其峥;《数据建模案例分析》;高等教育出版社;2000.
4.朱永强,秦志光,江雪;基于Sunday算法的改良单模式匹配算法[J].[H]计算机应用,2014,34
(1);doi:
10.11772/j.issn.1001-9081.2014.01.0208.
5.巫喜红;分块法的模式匹配算法的研究[J];重庆邮电大学学报(自然科学版);2014,26(4);doi:
10.3979/j.issn.1673-825X.2014.04.022.
6.袁晓洲;C语言中函数之间地址传递方式浅析[J];2014,(20);Journal:
ComputerCDSoftwareandApplications.
7.潘冠桦,张兴忠;Sunday算法效率分析[J];计算机应用;2012,32(11);doi:
10.3724/SP.J.1087.2012.03082.
8.鲁宏伟,魏凯,孔华锋;一种改进的KMP高效模式匹配算法[J];华中科技大学学报(自然科学版);2006,34(10);di10.3321/j.issn:
1671-4512.2006.10.013.
9.吴孟达,成礼智;《数据建模的理论与实践》;北京出版社1999年8月.
10.张鑫鑫,陈波,何继凌,徐云;生物序列数据K-mer频次统计问题的算法[J];计算机系统应用;2014,(4);doi:
10.3969/j.issn.1003-3254.2014.04.024.
11.夏承遗,董玉涛,赵德新,唐树刚,陈国章,张桦;C++中虚函数的实现机制[J];天津理工学院学报;2004,20(3);doi:
10.3969/j.issn.1673-095X.2004.03.017.
7附录
源代码:
#include
#include
#include
#include"CSpreadSheet.h"
usingstd:
:
string;
#pragmawarning(disable:
4146)
#pragmawarning(disable:
4786)
#import"C:
\Users\dengxin\Desktop\DNA("EOF","adoEOF")
//插入到数据库
boolInsertExcel(CStringstr1,CStringstr2)
{
try
{
CDatabasem_db;
if(!
m_db.IsOpen())
{
m_db.OpenEx("C:
\Users\dengxin\Desktop\DNA\新建文件夹",0);
}
CStringsql("insertintoStudents(myname,age)values('"+str1+"','"+str2+"')");
m_db.ExecuteSQL(sql);
if(m_db.IsOpen())
{
m_db.Close();
}
returntrue;
}
catch(_com_errore)
{
stringErrorMessage("数据库连接关闭失败:
"),Description,Source;
Description=e.Description();
Source=e.Source();
ErrorMessage+=e.ErrorMessage();
ErrorMessage=ErrorMessage+"\r\n"+Source+"\r\n"+Description;
:
:
MessageBox(NULL,ErrorMessage.c_str(),"错误",MB_OK);
returnfalse;
}
}
//获取路径
CStringGetAddr()
{
CStringsFile,sPath;
//获取主程序所在路径,存在sPath中
//检索已安装的驱动是否有Excel...
do
{
if(strstr(pszBuf,"Excel")!
=0)
{
//发现!
sDriver=CString(pszBuf);
break;
}
pszBuf=strchr(pszBuf,'\0')+1;
}
while(pszBuf[1]!
='\0');
returnsDriver;
}
//读取Excel
voidReadFromExcel()
{
TRY
{
CStringstr=GetAddr();
if(str.IsEmpty())
:
:
MessageBox(NULL,"无法获取当前路径",NULL,MB_OK);
else
{
CSpreadSheetSS(str,"Students");
CStringArrayRows,Column;
CStringstrContents="";
CStringsItem[3]={"0"};
for(inti=2;i { //读取一行 SS.ReadRow(Rows,i); strContents.Empty(); for(intj=0;j { strContents=Rows.GetAt(j); sItem[j]=strContents; printf("%s\t",sItem[j]); } printf("\n"); if(! InsertExcel(sItem[1],sItem[2])) { : : MessageBox(NULL,"导入数据出错","错误",MB_OK); return; } } } } CATCH(CDBException,e) { //数据库操作产生异常时... AfxMessageBox("数据库错误: "+e->m_strError); } END_CATCH; } //写Excel voidWriteFromExcel(intnum,CStringstr1,CStringstr2,CStringstr3) { CStringpath=GetAddr(); if(path.IsEmpty()) : : MessageBox(NULL,"获取路径错误",NULL,MB_OK); else { //新建Excel文件名及路径,TestSheet为内部表名 boolselectExcel() { _ConnectionPtrm_pConnection;//connectionobject'spointer _CommandPtrm_pCommand;//commandobject'spointer _ParameterPtrm_pParameter;//Parameterobject'spointer _RecordsetPtrm_pRecordset; HRESULThr; try { //创建连接对象 hr=m_pConnection.CreateInstance(__uuidof(Connection)); m_pRecordset.CreateInstance(__uuidof(Recordset)); if(! SUCCEEDED(hr))returnFALSE; //连接数据库 while(! m_pRecordset->adoEOF) { #include #include #include //预处理子串 voidkmp_Prepare(char*target,char*pattern,int*overlay) { memset(overlay,0,sizeof(overlay)); inti=-1,j=0,preOverlay; overlay[0]=-1; for(i=1;i preOverlay=overlay[i-1]; while(preOverlay>=0&&pattern[i]! =pattern[preOverlay+1]){ preOverlay=overlay[preOverlay]; } if(pattern[i]==pattern[preOverlay+1]){ overlay[i]=preOverlay+1; } Else { overlay[i]=-1; } } for(i=0;i printf("overlay[%d]: %d\n",i,overlay[i]); } } //查询子串 publicclassSUNDAY { publicSUNDAY() { // //TODO: 在此处添加构造函数逻辑 // } publicintQfindChr(st
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 深圳 DNA 序列 论文
![提示](https://static.bdocx.com/images/bang_tan.gif)