1.一种基于图形处理器并行计算的频繁子图挖掘方法,通过GPU划分出各个线程块block,将频繁边均匀分配给不同的线程进行并行处理,通过最右扩展rightmost得到不同的扩展子图,进行频繁子图挖掘,将最后各个线程得到的图挖掘数据集返回给每个线程块block;最后,通过GPU与内存进行数据通信,将结果返回给CPU进行处理,其特征在于:所述的通过最右扩展rightmost得到不同的扩展子图的并行过程如下:
步骤1:计算图集中所有标号图的边的支持度,根据最小支持度min_sup确定频繁图的片段,将输入图集合中所有的频繁边加入集合rank_edge[]中,并以rank_edge[]中的频繁边作为初始子图;
步骤2:根据集合rank_edge[],GPU同时开辟sum_count个线程,并标号t0,t1...tn,平均每512个线程组成一个block;由各个初始子图做最右扩展,得到的频繁子图;如对k阶频繁子图的最小DFS编码进行最右扩展,每次向最右路添加一条边,得到k+1阶候选子图;其中每一阶候选子图都是其父母节点的超图;
步骤3:重新计算k+1阶候选子图的支持度;对通过最右扩展得到的k+1阶子图计算支持度,如果大于最小支持度min_sup则保存,否则将其删除;
步骤4:剪枝冗余编码;比较第k+1阶候选频繁子图的DFS编码,如果扩展得到的k+1阶频繁子图不是最小DFS编码,则认为该图是冗余的,可从候选子图中删除;
步骤5:缩减图集合;当一条频繁边的所有最右扩展全部完成后,可将该频繁边从输入图集合中删除,以缩小输入图集合,
所述的频繁子图挖掘具体执行以下步骤:
(1)首先读取图数据库中数据集data_node[10000]到CPU内存单元graphdata[num]中去,其中graphdata为结构体数组,其结构体成员为一五元组(node_msg,node_lable,edge_x,edge_y,edge_weight),分别表示图中结点信息,结点标号,一条边的两个顶点x、y以及边的权值,num表示图数据库的图数量;
(2)定义两个数组rank_node[lable-max],rank_edge[lable-max]用于对图数据库中不同标号的点和边进行排序,分别存储在rank_node[]和rank_edge[]中;label-max代表每个图集的节点最大的个数,初始化label-max为500;排序后,能够快速找到满足min_sup最小支持度的点边集合;
(3)初始化min_sup的值,对图数据集进行遍历,将所有满足条件min_sup的边存入数组rank_edge[],并对其进行排序和计数,用字典顺序进行排序,用sum_count计数;
(4)在GPU端,根据sum_count频繁边总数,决定开辟线程数目的多少,将数据从CPU端传输到GPU端;
(5)在GPU开辟的两个内存块:stacksource[]和ksource[],其大小均为sum_count*sizeof(Graphdata)*100;两块内存分别用来存储不同数据,stacksource[]用于返回频繁子图结果集,ksource[]则用于进行最右扩展的迭代运算;定义graphdata型变量source,用于存放扩展得到的中间结果,初始化计数变量next的值为source中频繁边的个数,令p=next-1,其值为频繁边在stacksource中的计数并初始化p1=p=0;
(6)在GPU中分配内存后,开始对于每个线程进行并行,tid用于标记线程号,令ksource[tid*100+0]等于每个线程的初始source;
(7)将ksource[]遍历循环,将每个值赋给source使其做接下来的工作;对source中的图数据进行最小DFS编码,将bool dfs(source)这个类型的函数设置为GPU端的一个设备状态函数bool_device_dfs(source);
bool_device_dfs(source)函数可初始化为bool f[countnode][countedge]=true,conutedge为source的频繁边总个数,同时定义一个栈edge stack[maxlen],maxlen=10;
(8)如果bool_device_dfs(source)返回值是ture,则把source插入到stacksource[tid*100+k],k代表当前线程中第k个插入到数组中去的,也即对一个结果集计数的过程,同时,p1++;
(9)利用最右扩展,对k阶频繁图而言,任意从一条频繁边开始,判断并比较该边两端x,y的值,若其y值比rm数组中的x值大,则将该y值写入数组rm中,作为最右扩展的扩展边,即找到k阶频繁子图的第k+1条边,然后将找到的所有的结果集用map容器存数方式进行存储,并将此函数定义为func;
(10)在这个流程中,核心程序开始在func函数按顺序查找,如果edge{node_msg,node_lable,edge_x,edge_weight,edge_y}中的edge_y>next,next=next+1;这样可以知道扩展是内扩展还是外扩展,内扩展是指扩展的边两端的节点都在原来的图中;外扩展是指扩展的边两端的节点有一端是在图中,另一端是在扩展外部而来;
(11)将GPU端的stacksoruce传递给CPU端的内存,内存大小是:sum_count*sizeof(Graphdata)*100;
(12)对stacksoruce[]进行遍历,将结果集输出到txt文档中,最后得到结果频繁子项集。
2.如权利要求1所述的一种基于图形处理器并行计算的频繁子图挖掘方法,其特征在于所述的频繁子图挖掘具体执行的步骤(3)中,其排序方法如下:有结构体变量edge1、edge2定义为graphdata{node_msg,node_lable,edge_x,edge_y,edge_weight}型变量,其值为egde1{0,4,0,8,7},edge2{2,9,1,6,8};首先比较edge_x,此时(edge1→edge_x)<(edge2→edge_x),则edge1
3.如权利要求1所述的一种基于图形处理器并行计算的频繁子图挖掘方法,其特征在于所述的频繁子图挖掘具体执行的步骤(4)中,将排好序的频繁边传输到GPU端,在GPU端开辟sum_count*sizeof(edge)大小的显卡内存。
4.如权利要求1所述的一种基于图形处理器并行计算的频繁子图挖掘方法,其特征在于所述的频繁子图挖掘具体执行的步骤(7)中对频繁边的遍历包括以下步骤:
7.1)步骤为先取出遍历的第一条边,进行DFS编码,利用DFS编码进行字典顺序排序;
7.2)若在DFS编码中,存在边edge_x{node_msg,node_msgv,edge_x,edge_y,edge_weight},则标记f[x][y]=false,f[y][x]=false,表明该边已经遍历,无需重复遍历;利用IF(stack[p])来判断stack[p]里面是否是空集,如果是,则DFS遍历完成,返回true值;如果不是,则继续遍历,直到stack[p]为空;
7.3)最后通过while(satck[p])循环进行判断该编码是否为最小的DFS编码,令w=stack[p--];if(w