一种基于图挖掘的软件函数变更预测系统及方法与流程

文档序号:11154384阅读:255来源:国知局
一种基于图挖掘的软件函数变更预测系统及方法与制造工艺

本发明涉及一种基于图挖掘的软件函数变更预测系统及方法,属于复杂网络和数据分析及软件工程领域。



背景技术:

复杂网络经常伴随着信息、病毒、疾病等的传播,而一个网络的拓扑结构对于变更传播的程度有着显著的影响。在计算机科学领域,大型软件系统中的类图、依赖图、关系图、软件组件图、函数调用图都属于复杂网络。

当开发者为了加入一个新功能或者修复一个BUG的时,对软件系统一个部分作出修改后,其他的部分为了适应修改,常常也需要进行更新。量化一个软件网络的传播性有助于节省软件维护产生的开销。

在函数调用关系图中,变更传播通常都是单方向的,函数A调用函数B,当B发生修改时,A因为接口需要作出调整因此很可能需要相应作出修改,这叫B传播到A,但当A发生修改时,B一般就不需要作出修改了。

数据挖掘就是从大量的、不完全的、有噪声的、模糊的、随机的数据中,提取隐含在其中的、人们事先不知道的、但又是潜在有用的信息和知识的过程。这些数据可以是结构化的,如关系数据库中的数据,也可以是半结构化的,如文本、图形、图像数据,甚至是分布在网络上的异构型数据。针对半结构化数据的研究已经成为近年来国内外数据挖掘领域的研究热点,而目前国内的研究热点主要集中在文本数据挖掘等领域,针对图的数据挖掘研究才刚刚开始。与一般的数据比较,图能够表达更加丰富的语义,在科学研究和许多商业领域有着更为广泛的应用。同时,这种丰富的语义也增加了数据结构的复杂性和挖掘令人感兴趣的图的子结构的难度。因此,需要综合应用图论知识与数据挖掘的各种技术。图的数据挖掘主要是从图的数据库中找到大于最小支持度的频繁子图。

基于贪心策略的频繁子图挖掘是频繁子图挖掘领域最先发展起来的技术之一,其中最著名的是SUBDUE算法。SUBDUE算法基于最小描述长度原则(minimum description length,MDL)来发现子结构。严格来说,其所谓的频繁与之后我们介绍的频繁子图的概念有所不同。其所指的某个子结构“频繁”是用MDL原则评定的,而不是单纯指其出现的频率高。

对于许多挖掘和学习问题来说,描述关系通常比描述属性更能得出简洁且精确的规则。与之相对应的,一阶谓词逻辑在很多情况下的表现也优于命题逻辑。而且,图可以比较容易的使用一阶逻辑来表示。对基于ILP的方法而言,其优点不局限于发现知识,还可以在知识归纳中运用正反例。或者说,其目标是归纳出一个可正确分类的正样本集和负样本集的规则集。是故,归纳逻辑编程(Inductive Logic Programming,ILP)被提出而应用在频繁子图的搜索上。其优点在于大多算法能找出出现频率高的子图,且能作为交好的类识别器。但其缺点在于不能保证发现所有的频繁子图。1998年Dehaspe基于ILP提出可对频繁子图进行完全挖掘的WARMR算法,其算法核心思想与Apriori算法类似。

比较遗憾的是,基于ILP的算法由于需要图结构对一些特别的特征和谓词实例进行预特征化,故仅能发现有限特征的子结构,无法发现所有的频繁子图。而且虽然其在后续发展中结合了分层搜索以最小化对数据库的访问,效率有了极大的提升,但是,其搜索所需空间仍就很大。由此A.Inokuchi等人最先提出了基于Apriori思想的频繁子结构挖掘算法。(AGM算法)

FSG是AGM算法的一种改进。同基于Apriori的方法一样,其采用了分级扩展的方法。但优化之处在于:其采用了相对稀疏的图表示方法,来最小化存储空间和计算开销。每次添加一条边来扩大频繁子图的大小,由此使得生成候选集更有效。采用了对小图更有效的规范标签和图同构算法。其对生成候选集进行了各种优化并统计了能适用于大规模的图数据库的优化措施。

AGM和FSG算法都采用了基于Apriori逐层推进的方法。而这种Apriori模式的算法会遇到两个瓶颈:从k阶频繁子图构造k+1阶频繁子图相当复杂且代价昂贵,同时子图同构测试是一个NPC问题,所以处理误报的代价也是极其昂贵。为了解决这些问题,Xifeng Yan提出了gSpan(graph-based Substructure pattern mining)算法,通过对图进行深度优先搜索遍历来发现频繁子图。gSpan算法由于解决了模式的算法所遇到的两个瓶颈,大幅提高了效率并降低了空间消耗,同时避免发生产生冗余候选频繁子图的情况。

在图数据集中进行模式挖掘的过程中,实际上会遇到诸多相当棘手的问题,诸如子图同构检测。这些问题在图数据中通常意味着远超于其他数据结构的昂贵的时间代价。由此,一种新的频繁子图挖掘算法算法快速频繁子图挖掘(Fast Frequent Subgraph Mining,FFSM)被提出。FFSM采用了垂直搜索模式,最终能减少产生的冗余候选子图。

频繁子图挖掘技术在发展过程中,由基于贪心策略的SUBDUE算法到基于ILP的方法,再到A.Inokuchi等人提出了基于Apriori思想的AGM算法,频繁子图的效率逐步提升。FSG算法对AGM算法作出了图的表示形式以及生成候选频繁子图过程的优化,提升了效率并降低了开销,但是其效果并不十分明显。直到基于模式增长的方法——gSpan算法被提出,开创性的结合了DFS搜索,并定义了DFS序列来减少冗余频繁子图的生成,大幅提高了效率并降低了空间消耗。而FFSM算法为了解决基于Apriori思想的算法会面临的两个挑战做出了相应的对策,通过解决潜在的子图同构问题并减少冗余候选子图的生成,也大大提升了效率。

综上,现有的图挖掘技术存在如睛问题:(1)现有图挖掘技术主要还是集中在物理、化学、网络领域。没有涉及到函数变更预测上。(2)现有的图挖掘技术由于要找出所有频繁子图,所以时间开销特别大。(3)由于图挖掘技术找出所有频繁子图,所以数据量特别大,对于后续处理也带来很大麻烦。



技术实现要素:

本发明的技术解决问题:克服现有技术的不足,提供一种基于图挖掘的软件函数变更预测系统及方法,具有时间开销低、数据量小的特点,并且挖掘效果很好,挖掘出的预测函数在下个版本发生变更的数目与总数的比值大于80%。

本发明技术解决方案:

一种基于图挖掘的软件函数变更预测系统,包括函数调用关系图生成模块、变更函数调用关系图获取模块、图挖掘及变更函数预测模块,其中:

函数调用关系图生成模块:根据需要处理相应的软件网络,生成相应软件网络的函数调用关系图;

变更函数调用关系图获取模块:对相邻版本的函数源码比较,得到变更函数,在已生成的函数调用关系图中,去掉没有变更的函数,得到每个相邻版本源代码的变更函数调用关系图;

图挖掘及变更函数预测模块:利用得到的变更函数调用关系图,通过图挖掘算法,输入参数,再得到挖掘结果,并输出预测函数。

所述函数调用关系图生成模块实现过程如下:

(1)选择需要处理相应的软件网络,包括操作系统软件源代码,然后调用外部工具cdepn,对于所有.c文件,生成相应的cdepn文件;

(2)对于生成的.cdepn文件,逐行读取文件,当每一行第一个字符为F时,表示该行函数为call函数,之后的所有开头第一个字符为C的行的直到文件尾或者下一个开头第一个字符为F的行为止,包含在里面的函数都被该函数调用,按照此方法则生成相应整个软件网络的函数调用关系图。

所述变更函数调用关系图获取模块实现过程如下:

(1)利用ctags获取每个函数在相邻版本中的被定义位置,函数定义总是以‘{’开始,最终以‘}’结束,利用此原理,从函数开始行开始,利用栈的数据结构,去掉注释语句,每读到‘{’入栈,读到‘}’出栈,直到栈为空,这时候的行数为该函数的结束行。按照此方法得到函数被定义的结束行,然后提取各函数在相邻版本的源代码,利用diff命令,比较代码是否发生改变,如果是则是变更函数;

(2)得到变更函数后,利用变更函数,对源代码的函数调用关系图进行筛选,去掉没有变更过的函数,剩下的就是变更函数调用关系图。

所述图挖掘及变更函数预测模块实现过程如下:

(1)设定参数,包括最小支持度,以及单次挖掘的相邻版本子图数,即跨度,利用修改过的gspan算法进行挖掘,如下:

1)首先逐条边读取一定数量的连续版本变更函数子图,对于每条边,记录出现次数,读取完毕后,去掉出现次数低于支持度的边;

2)剩余边具有以下属性:(x,x1,y,y1,e),x为调用函数的编号,x1是该函数的权值,y是被调用函数的编号,y1是该函数权值,e是该条边的编号,以上五个属性都是数字,按照从左到右优先级顺序对所有边按照属性值比较从低到高进行排序,得到最小DFS编码,从记录的第一个函数开始,按照最小DFS编码的边的顺序,从小到大进行扩展,不断加入新的边,直到得到完整的频繁变更子图;

(2)利用挖掘出的频繁变更子图,得到频繁变更函数即挖掘结果,并作为输出的预测函数。

一种基于图挖掘的软件函数变更预测方法,实现步骤如下:

第一步,生成函数调用关系图,根据需要处理相应的软件网络,生成相应软件网络的函数调用关系图;

第二步,获取变更函数,根据已生成的函数调用关系图,去掉图中所有没有发生变更的函数,得到每个相邻版本源代码的变更函数调用关系图;

第三步,图挖掘及变更函数预测,利用得到的变更函数调用关系图,通过图挖掘算法,输入参数,得到挖掘结果,并输出预测函数。

所述第一步,具体如下:

在Linux下配置工具生成cdepn图,并通过脚本处理进而生成callpah,具体如下:(1)配置Codeviz工具;(2)编写脚本遍历目录为所有.c文件生成cdepn文件;(3)编写代码,利用cdepn文件生成该软件网络的函数调用关系图。

所述第二步,具体过程如下:

步骤2.1、利用ctags可以对某个.c文件下所有的函数进行检索,并输出该函数的起始行,编写脚本,递归遍历Linux内核代码下所有.c文件生成相应的.c文件;

步骤2.2、函数定义总是以‘{’开始,最终以‘}’结束,利用此原理,从函数开始行开始,利用栈的数据结构,去掉注释语句,每读到‘{’入栈,读到‘}’出栈,直到栈为空,这时候的行数为该函数的结束行;

步骤2.3、得到起始行后,利用shell命令,sed可以读取指定行之间的内容,通过diff命令,比较相邻版本间同名函数,可以知道该函数是被修改、被增加或者被删除;

步骤2.4、在得到相邻版本间的变更函数后,在之前生成的函数调用关系图中,去掉没有发生变更的函数,得到相邻版本变更函数调用关系图。

所述第三步,具体过程如下:

步骤3.1、设定参数,包括最小支持度及单次挖掘的相邻版本子图数,即跨度,所述跨度是单次挖掘的相邻版本子图数,本发明主要采用了跨度为3、5、7、10四个值作为参数,每次选取N个相邻版本子图作为挖掘数据源;所述最小支持度是指设定最小支持度a,表示选取N个版本时,挖掘出的子图在这N个版本中出现次数S比上N,S/N>=a,本发明采用支持度0.4、0.6、0.8、1作为候选参数;

步骤3.2、利用编写的gspan算法代码,进行挖掘,得到频繁子图,其中支持度大于设定值的函数即为下个版本的预测结果。

本发明的优点与积极效果在于:本发明利用图挖掘进行变更函数预测属于领域内创新,并且挖掘效果很好。

本发明与现有技术相比的优点在于:

(1)本发明首次将图挖掘技术用在函数变更预测领域,属于领域创新,具有时间开销低、数据量小的特点,并且挖掘效果很好,挖掘出的预测函数在下个版本发生变更的数目与总数的比值大于80%。

(2)本发明采用gspan算法,并根据软件网络没有同名结点的特点,对gspan算法进行优化,统计的是最大频繁变更子图,原gspan算法不仅统计最大频繁变更子图,也统计了子图的子图,因此时间复杂度从2^n降低到了n^2。

(3)本发明优化了gspan算法,挖掘结果只会输出最大频繁变更子图,而不是现有的算法将最大频繁变更子图所有子集输出,对于后续处理更加容易。

附图说明

图1为本发明系统的结构框图;

图2为图1中函数调用关系图生成模块的实现流程图;

图3为图1中变更函数调用关系图获取模块的实现流程图;

图4为图1中图挖掘及变更函数预测模块的实现流程图;

图5为cdepn文件格式。

具体实施方式

下面将结合附图和实施例对本发明作进一步的详细说明。

在叙述之前,要对本发明涉及的技术和术语进行一下说明。

Codeviz,graphviz,ctags,sed是Linux下的第三方工具,在命令行输入sudo apt-get install工具名命令可以直接安装。

cdepn文件是利用安装好的codeviz和graphviz后,针对待处理源代码文件下的.c文件生成的相应的名字为*.cdepn文件,文件格式如图5所示。

Shell命令是Linux自带的命令行编辑器,用于处理各种常用操作。

如图1所示,本发明包括函数调用关系图生成模块、变更函数调用关系图获取模块和图挖掘及变更函数预测模块。

如图2所示,本发明中函数调用关系图生成模块具体实现如下:

(1)扫描源代码下未处理过的源代码文件,生成对应的cdepn文件;

(2)所有源代码处理完毕后,逐行读取所有cdepn文件,逐行读取文件,当读到开头为F时,表示该行函数为call函数,之后的所有开头为C的行的直到文件尾或者下一个F开头行为止,包含在里面的函数都被该函数调用,按照此方法生成整个软件网络的调用关系图。

如图3所示,本发明中变更函数调用关系图获取模块具体实现如下:

(1)利用Linux工具ctags,输入源代码下的源文件,得到该文件下所有函数被定义的起始行以及所在文件路径。

(2)函数定义总是以‘{’开始,最终以‘}’结束,利用此原理,从函数开始行开始,利用栈的数据结构,去掉注释语句,每读到‘{’入栈,读到‘}’出栈,直到栈为空,这时候的行数为该函数的结束行。

(3)使用Linux的diff命令,比较相邻版本函数源代码是否发生变更。

(4)去掉函数调用关系图中没有发生变更的函数,剩下的图就是变更函数调用关系图。并作为结果输出。

如图4所示,本发明中图挖掘及变更函数预测模块具体实现如下:

(1)设定挖掘参数,最小支持度和跨度。

最小支持度:设定最小支持度a,表示选取N个版本时,挖掘出的子图在这N个版本中出现次数S比上N,S/N>=a。本发明采用支持度0.4、0.6、0.8、1作为候选参数。

跨度:单次挖掘的相邻版本子图数,本发明主要采用了跨度为3、5、7、10四个值作为参数,每次选取N个相邻版本子图作为挖掘数据源。

(2)利用gspan算法进行挖掘,输出结果是挖掘出的频繁变更子图。

(3)提取挖掘出的频繁变更子图中的所有函数,作为结果输出。

本发明方法,具体为如下步骤。

第一步、获得函数调用图:

在Linux下配置工具生成cdepn图,并通过脚本处理进而生成callpah。基本的思路如下:(1)配置Codeviz等工具;(2)编写脚本遍历目录为所有.c文件生成cdepn文件;(3)编写代码,利用cdepn文件生成该网络的函数调用关系图。

步骤1.1、配置工具。

首先安装graphviz和CodeViz

使用配置好的工具递归编译待处理源代码下所有*.c文件,会相应地生成一个*.c.cdepn文件。

步骤1.2、执行脚本生成函数调用关系图。

利用编写的代码生成函数调用关系图,对于生成的.cdepn文件,逐行读取文件,当读到开头为F时,表示该行函数为call函数,之后的所有开头为C的行的直到文件尾或者下一个F开头行为止,包含在里面的函数都被该函数调用,按照此方法生成整个软件网络的调用关系图。

第二步、通过相邻版本函数调用图获得变更函数,包括:

步骤2.1、部署ctags,利用ctags得到每个函数在源代码中定义的起始行;

利用sudo apt-get install ctags安装ctags;

ctags可以对某个.c文件下所有的函数进行检索,并输出该函数被定义的起始行。编写脚本,递归遍历Linux内核代码下所有.c文件生成相应的.c文件。

步骤2.2、利用模式匹配,得到每个函数的结束行;

函数定义总是以‘{’开始,最终以‘}’结束,利用此原理,从函数开始行开始,利用栈的数据结构,去掉注释语句,每读到‘{’入栈,读到‘}’出栈,知道栈为空,这时候的行数为该函数的结束行。

步骤2.3、利用相邻版本函数的起始行,结束行,提取出源代码,进行比较,得到修改、增加、删除的函数。

得到起始行后,利用shell命令,sed可以读取指定行之间的内容,通过diff命令,比较相邻版本间同名函数,可以知道该函数是被修改、被增加或者被删除。

步骤2.4、得到发生修改函数的子图,及变更函数子图;

通过变更函数集合,在原内核生成的call graph上进行筛选,得到的子图即为变更函数的子图。

第三步、利用图挖掘算法gspan,设定参数,得到频繁子图,输出结果;

步骤3.1、设定参数,主要有最小支持度,还有单次挖掘的相邻版本子图数,即跨度。

跨度,单次挖掘的相邻版本子图数,本发明主要采用了跨度为3、5、7、10四个值作为参数,每次选取N个相邻版本子图作为挖掘数据源。

最小支持度,设定最小支持度a,表示选取N个版本时,挖掘出的子图在这N个版本中出现次数S比上N,S/N>=a。本发明采用支持度0.4、0.6、0.8、1作为候选参数。

步骤3.2、利用编写的代码,进行挖掘,得到频繁子图。其中支持度大于设定值的函数即为下个版本的预测结果。

提供以上实施例仅仅是为了描述本发明的目的,而并非要限制本发明的范围。本发明的范围由所附权利要求限定。不脱离本发明的精神和原理而做出的各种等同替换和修改,均应涵盖在本发明的范围之内。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1