一种有向图中所有连通子图的快速生成方法与流程

文档序号:11286554阅读:1009来源:国知局
一种有向图中所有连通子图的快速生成方法与流程

本发明属于软件设计技术领域,尤其涉及一种有向图中所有连通子图的快速生成方法。



背景技术:

图作为一种非线性结构,应用非常广泛,不仅局限于数学和计算机学科,还涵盖了社会学、交通管理、系统工程、控制工程、通讯网络等领域。图的连通子图在一些领域也得到了广泛应用,例如,在面向对象软件测试中,为了确定类的测试次序,需要求出类图的所有连通子图(回路);利用信号流图或流图分析电子电路或反馈系统时,为了将电路、系统或计算机程序进行最优分解而寻找有向图的最小反馈点(边)集时,需要求出有向图的全部连通子图(回路)。图指的是一个二元组(v,e),其中v是图的顶点集,e是图的弧集,如果e∈e是有方向的,则称其为有向弧。每条弧都有方向的图称为有向图。图中从顶点v0到顶点vm的路径是一个有序顶点序列s={v0,...,vm},其中顶点序列应满足<vj-1,vj>∈e(1≤j≤m)。若且vi≠vj,则称此路径为简单路径;若<vm,v0>∈e,则称序列s为连通子图(回路);特别的,如果且vi≠vj,<vm,v0>∈e,称序列s是简单连通子图(简单回路)。

已有的涉及有向图的连通子图的生成方法分为两类,分别是求有向图的极大连通子图(强连通分量)和简单连通子图的。一种与本发明接近的求有向图简单连通子图的生成方法的基本思想是:将有向图中的n个顶点进行排序,例如n个顶点从小到大排序为1,…,n;然后,基于图的深度优先搜索,依次从顶点1,2,…,n出发,向顶点序号大于出发顶点的方向进行遍历,遍历过程中采用数组p存储简单路径,链表path[u]记录每个顶点u到出发顶点v的路径,通过判断当前访问顶点u是否是出发顶点v,或者u与v之间是否有路径的方法计算有向图的连通子图,但由于通过该方法获得的连通子图的顶点均不相同,并且需要进行n次深度优先遍历,故该方法只能计算出有向图的简单连通子图,并且计算效率不高。

在交通领域,可以通过计算有向图简单连通子图的方法查询哪些城市之间有往返路线,例如通过计算有向图简单连通子图的方法,可以知道北京到上海有往返路线,上海到天津有往返路线,但是没有直接计算出北京到天津是否有往返路线。

综上所述,现有技术存在的问题是:目前有向图所有连通子图的生成方法存在只能生成有向图的极大连通子图或者只能生成有向图的简单连通子图,没有生成有向图所有连通子图的方法。与本发明最接近的方法只能计算出有向图的所有简单连通子图,并且在计算有向图所有简单连通子图的过程中,需要进行n次深度优先遍历,在处理复杂有向图时算法效率低下。



技术实现要素:

针对现有技术存在的问题,本发明提供了一种有向图中所有连通子图的快速生成方法。

本发明是这样实现的,一种有向图中所有连通子图的快速生成方法,所述有向图中所有连通子图的快速生成方法基于图的深度优先遍历,遍历过程中,将未被访问的顶点压入栈s中即借助栈s存储有向图的简单路径,若当前顶点v已被访问,则判断v是否在栈中,若是,根据栈s中简单路径,计算有向图的简单连通子图;否则,若v在已获得的简单连通子图中,则通过判断栈中简单路径和已有简单连通子图是否有重合部分,计算可能存在的简单连通子图;根据所有简单连通子图,基于求集合幂集的方法,判断简单连通子图之间是否有重合部分,对有重合部分的简单连通子图进行合并,计算有向图的连通子图,最终生成有向图的所有连通子图。

进一步,所述有向图中所有连通子图的快速生成方法包括以下步骤:

步骤一,选择有向图中一个未被访问的顶点v;

步骤二,将v压入栈s中;

步骤三,判断v是否有邻接顶点,若有,选择v的第一个邻接顶点w,否则,转向步骤七;

步骤四,判断w是否已经被访问过,若未被访问过,令v=w,转向步骤二;

步骤五,判断w是否在栈s=<v0,…,vm>中,若在,即s=<v0,…,w,…,vm>,根据栈s中简单路径,计算有向图的简单连通子图scc=<w,...,vm>,将scc无重复添加至sccset中,转向步骤八;

步骤六,判断栈s中简单路径和已获得的简单连通子图是否存在重合部分,计算可能存在的简单连通子图,将计算得到的所有简单连通子图依次无重复的添加至sccset中,转向步骤八;

步骤七,令w=top(s),s的栈顶顶点出栈,判断栈s是否为空,若是,转向步骤九;否则,令v=top(s);

步骤八,判断w是否是v的最后一个邻接顶点,若是,转向步骤七,否则,选择v的相对于w的下一个邻接顶点u,令w=u,转向步骤四;

步骤九,判断有向图所有顶点是否都被访问完,若没有,转向步骤一,否则,获得有向图所有简单连通子图,并且所有简单连通子图均存储在sccset中;

步骤十,判断sccset是否为空,若是,则有向图无简单连通子图,因此无连通子图,结束;否则,根据所有简单连通子图,生成有向图的所有连通子图,结束。

进一步所述有向图的简单连通子图用构成简单连通子图的有序顶点序列scc=<v0′,…,vm′>表示,其中对于所有1≤j≤m,<vj-1′,vj′>∈e,且<vm′,v0′>∈e。

进一步,所述步骤六中判断栈中简单路径和已获得的简单连通子图是否存在重合部分,计算可能存在的简单连通子图的具体步骤如下:

第一步,选择sccset中第一个简单连通子图scc=<v0′,…,vm′>;

第二步,判断当前访问顶点w是否在scc中,若在,scc=<v0′,…,w,…,vm′>,否则,转向第五步;

第三步,判断s中简单路径与scc是否有重合部分,若有,即s=<v0,…,vi,…,vj,…,vm>,scc=<v0′,…,vi,…,vj,…,w,…,vm′>,简单连通子图scc1=<v0′,…,vi,…,vj,…,vm,w,…,vm′>,将scc1无重复添加至sccset1中,清空scc1,执行第四步;否则,转向第四步;

第四步,通过判断栈s中简单路径和通过scc可以到达的已有简单连通子图scc2是否有重合部分,计算可能存在的简单连通子图,转向第五步;

第五步,判断scc是否是sccset中最后一个简单连通子图,若不是,选择sccset中相对于scc的下一个简单连通子图scc3,令scc=scc3,转向第二步;否则,结束。

进一步,所述第四步中通过判断栈中简单路径和通过scc可以到达的已有简单连通子图scc2是否有重合部分,计算可能存在的简单连通子图具体过程为:

(1)令scc2=scc,将二元组(scc2=<v0′,…,vk,w,…,vm′>,path=<w,…,vm′,v0′,…,vk>)压入栈s2中,其中path是由从scc的w顶点到另一个简单连通子图scc2的路径与scc2构成的;

(2)选择sccset中的第一个和scc有公共部分的简单连通子图scc2;

(3)判断scc2是否已被处理过,若不是,转向(6);

(4)判断scc2是否是sccset中最后一个和scc有公共部分的简单连通子图,若是,将s2中栈顶二元组的scc2赋值给scc2,s2的栈顶二元组出栈,转向(10);

(5)选择sccset中相对于scc2的下一个和scc有公共部分的简单连通子图scc3,scc2=scc3,转向(3);

(6)取栈s2栈顶二元组的path中离w最近的公共顶点u(scc和scc2的公共顶点),path=<w,…,u,…,vk>,scc2=<v0″,…,vu-1,u,…,vm″>,更新path=<w,...,u,...,vm″,v0″,…,vu-1>,将二元组(scc2,path)压入栈s2中;

(7)判断s中简单路径和scc2是否有重合部分,若没有,转向(9);

(8)判断s中简单路径和scc与scc2的公共部分是否包含公共顶点,若没有,s=<v0,…,vi,…,vj,…,vm>,scc2=<v0″,…,vi,…,vj,…,vm″>,path=<w,...,u,...,vi-1,vi,…,vj,…,vu-1>,计算简单连通子图scc1=<vi,…,vj,…,vm,w,...,u,...,vi-1>,将scc1不重复添加至sccset1中,否则,转向(9);

(9)令scc=scc2,转向(2);

(10)判断栈s2是否为空,若不是,将栈s2栈顶二元组的scc2赋值给scc,转向(4);否则,返回sccset1,结束。

进一步,所述步骤十中根据所有简单连通子图,生成有向图的所有连通子图的具体步骤如下:

(1)选择sccset中的第一个简单连通子图cc,令scc=cc;

(2)将二元组(scc,cc)压入栈s1中,并将cc无重复的添加至ccset中;

(3)判断栈s1是否为空,若为空,删除sccset的第一个简单连通子图,转向(9);

(4)判断scc是否为sccset的最后一个简单连通子图,若是,转向(8);

(5)选择scc的下一个简单连通子图scc1,令scc=scc1;

(6)判断栈s1中栈顶二元组(scc,cc)的元素cc=<v0,…,vn>和scc=<v0′,...,vm′>是否有重合部分,若没有,转向(4);

(7)计算有向图的连通子图cc=scc∪top(s1).cc,转向(2);

(8)将栈s1栈顶二元组(scc,cc)的scc赋值给scc,即scc=top(s1).scc,s1的栈顶二元组出栈,转向(3);

(9)判断sccset是否为空,若不是,转向(1);否则,生成有向图的所有连通子图,并存放在ccset中,结束。

进一步,所述(6)具体包括:

1)判断cc=<v0,…,vn>和scc=<v0′,...,vm′>是否有公共部分;

2)若cc和scc包含共同的顶点,则cc和scc有重合部分,结束,否则cc和scc没有重合部分,结束。

本发明的另一目的在于提供一种应用所述有向图中所有连通子图的快速生成方法的交通管理系统。

本发明的另一目的在于提供一种应用所述有向图中所有连通子图的快速生成方法的通讯网络系统。

本发明的另一目的在于提供一种应用所述有向图中所有连通子图的快速生成方法的电子电路或反馈系统。

本发明的优点及积极效果为:本发明一种有向图中所有连通子图的快速生成方法,与目前已存在的方法的比较如表1所示。有向图的简单连通子图用构成简单连通子图的有序顶点序列表示,遍历过程中,对每个顶点只处理一次,遍历结束后,可以生成有向图的所有简单连通子图,从而提高了计算效率,同时根据所有简单连通子图可以生成有向图的所有连通子图。

表1本发明与现有技术的比较

附图说明

图1是本发明实施例提供的有向图中所有连通子图的快速生成方法流程图。

图2是本发明实施例提供的有向图中所有连通子图的快速生成方法实现流程图。

图3是本发明实施例提供的根据栈中简单路径和已获得的简单连通子图,计算有向图的简单连通子图的流程图。

图4是本发明实施例提供的根据所有简单连通子图,生成有向图的所有连通子图的流程图。

图5是本发明实施例提供的有向图。

具体实施方式

为了使本发明的目的、技术方案及优点更加清楚明白,以下结合实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。

下面结合附图对本发明的应用原理作详细的描述。

如图1所示,本发明实施例提供的有向图中所有连通子图的快速生成方法包括以下步骤:

s101:基于深度优先遍历,遍历过程中,借助栈存储有向图的简单路径;

s102:根据简单路径,计算有向图的简单连通子图,或者通过判断简单路径和已有简单连通子图是否有重合部分,计算可能存在的简单连通子图;

s103:根据所获得的所有简单连通子图,基于求集合幂集的方法,对有重合部分的简单连通子图进行合并,计算有向图的连通子图,最终生成有向图的所有连通子图。

连通子图由构成连通子图的顶点表示,由于构成连通子图的顶点包含重复顶点,对于重复顶点,表示方法中只给出重复顶点中的一个,例如,若<1,2,3,2,1>是一个连通子图,则该连通子图表示为<1,2,3>。

下面结合附图对本发明的应用原理作进一步的描述。

如图2,本发明实施例提供的有向图中所有连通子图的快速生成方法基于图的深度优先遍历,遍历过程中,将未被访问的顶点压入栈s中即借助栈s存储有向图的简单路径,若当前顶点v已被访问,则判断v是否在栈中,若是,根据栈s中简单路径,计算有向图的简单连通子图;否则,若v在已获得的简单连通子图中,则通过判断栈中简单路径和已有简单连通子图是否有重合部分,计算可能存在的简单连通子图;根据所有简单连通子图,基于求集合幂集的方法,判断简单连通子图之间是否有重合部分,对有重合部分的简单连通子图进行合并,计算有向图的连通子图,最终生成有向图的所有连通子图。

本发明实施例提供的有向图中所有连通子图的快速生成方法的具体步骤如下:

步骤一,选择有向图中一个未被访问的顶点v;

步骤二,将v压入栈s中;

步骤三,判断v是否有邻接顶点,若有,选择v的第一个邻接顶点w,否则,转向步骤七;

步骤四,判断w是否已经被访问过,若未被访问过,令v=w,转向步骤二;

步骤五,判断w是否在栈s=<v0,…,vm>中,若在,即s=<v0,…,w,…,vm>,根据栈s中简单路径,计算有向图的简单连通子图scc=<w,...,vm>,将scc无重复添加至sccset中,转向步骤八;

步骤六,判断栈s中简单路径和已获得的简单连通子图是否存在重合部分,计算可能存在的简单连通子图,将计算得到的所有简单连通子图依次无重复的添加至sccset中,转向步骤八;

步骤七,令w=top(s),s的栈顶顶点出栈,判断栈s是否为空,若是,转向步骤九;否则,令v=top(s);

步骤八,判断w是否是v的最后一个邻接顶点,若是,转向步骤七,否则,选择v的相对于w的下一个邻接顶点u,令w=u,转向步骤四;

步骤九,判断有向图所有顶点是否都被访问完,若没有,转向步骤一,否则,获得有向图所有简单连通子图,并且所有简单连通子图均存储在sccset中;

步骤十,判断sccset是否为空,若是,则有向图无简单连通子图,因此无连通子图,结束;否则,根据所有简单连通子图,生成有向图的所有连通子图,结束。

进一步,所述有向图的简单连通子图用构成简单连通子图的有序顶点序列scc=<v0′,…,vm′>表示,其中对于所有1≤j≤m,<vj-1′,vj′>∈e,且<vm′,v0′>∈e。

进一步,如图3,所述步骤六中判断栈中简单路径和已获得的简单连通子图是否存在重合部分,计算可能存在的简单连通子图的具体步骤如下:

第一步,选择sccset中第一个简单连通子图scc=<v0′,…,vm′>;

第二步,判断当前访问顶点w是否在scc中,若在,scc=<v0′,…,w,…,vm′>,否则,转向第五步;

第三步,判断s中简单路径与scc是否有重合部分,若有,即s=<v0,…,vi,…,vj,…,vm>,scc=<v0′,…,vi,…,vj,…,w,…,vm′>,简单连通子图scc1=<v0′,…,vi,…,vj,…,vm,w,…,vm′>,将scc1无重复添加至sccset1中,清空scc1,执行第四步;否则,转向第四步;

本发明的方法是基于有向图的深度优先遍历的,即若从某顶点开始有一条以上分支,则必须遍历完从该顶点开始的一条路径,再遍历从该顶点开始的另一条路径,以此类推,直到遍历完所有路径为止。并且利用栈s存放简单路径,只要当前被选择的顶点v已被访问,顶点v便不再被压入栈s,而已有的简单连通子图scc是根据栈s中简单路径获得的或者通过判断栈中简单路径和已有简单连通子图是否有重合部分,获得可能存在简单连通子图scc;若当前选择的栈顶顶点的邻接顶点w已被访问且w在scc中,那么若scc和栈s中简单路径有重合部分或者scc可到达的简单连通子图scc2和栈s中简单路径有重合部分,则记录简单连通子图的顶点序列是由栈s中重合路径至栈顶顶点的简单路径以及顶点w共同构成的简单路径开始,后面接剩下的路径构成,所以scc中与栈s中简单路径的重合部分必在顶点w的左侧。

第四步,通过判断栈s中简单路径和通过scc可以到达的已有简单连通子图scc2是否有重合部分,计算可能存在的简单连通子图,转向第五步;

第五步,判断scc是否是sccset中最后一个简单连通子图,若不是,选择sccset中相对于scc的下一个简单连通子图scc3,令scc=scc3,转向第二步;否则,结束。

进一步,所述第四步中通过判断栈中简单路径和通过scc可以到达的已有简单连通子图scc2是否有重合部分,计算可能存在的简单连通子图具体过程为:

(1)令scc2=scc,将二元组(scc2=<v0′,…,vk,w,…,vm′>,path=<w,…,vm′,v0′,…,vk>)压入栈s2中,其中path是由从scc的w顶点到另一个简单连通子图scc2的路径与scc2构成的;

(2)选择sccset中的第一个和scc有公共部分的简单连通子图scc2;

(3)判断scc2是否已被处理过,若不是,转向(6);

(4)判断scc2是否是sccset中最后一个和scc有公共部分的简单连通子图,若是,将s2中栈顶二元组的scc2赋值给scc2,s2的栈顶二元组出栈,转向(10);

(5)选择sccset中相对于scc2的下一个和scc有公共部分的简单连通子图scc3,scc2=scc3,转向(3);

(6)取栈s2栈顶二元组的path中离w最近的公共顶点u(scc和scc2的公共顶点),path=<w,…,u,…,vk>,scc2=<v0″,…,vu-1,u,…,vm″>,更新path=<w,...,u,...,vm″,v0″,…,vu-1>,将二元组(scc2,path)压入栈s2中;

(7)判断s中简单路径和scc2是否有重合部分,若没有,转向(9);

(8)判断s中简单路径和scc与scc2的公共部分是否包含公共顶点,若没有,s=<v0,…,vi,…,vj,…,vm>,scc2=<v0″,…,vi,…,vj,…,vm″>,path=<w,...,u,...,vi-1,vi,…,vj,…,vu-1>,计算简单连通子图scc1=<vi,…,vj,…,vm,w,...,u,...,vi-1>,将scc1不重复添加至sccset1中,否则,转向(9);

(9)令scc=scc2,转向(2);

(10)判断栈s2是否为空,若不是,将栈s2栈顶二元组的scc2赋值给scc,转向(4);否则,返回sccset1,结束。

进一步,如图4,所述步骤十中根据所有简单连通子图,生成有向图的所有连通子图的具体步骤如下:

(1)选择sccset中的第一个简单连通子图cc,令scc=cc;

(2)将二元组(scc,cc)压入栈s1中,并将cc无重复的添加至ccset中;

(3)判断栈s1是否为空,若为空,删除sccset的第一个简单连通子图,转向(9);

(4)判断scc是否为sccset的最后一个简单连通子图,若是,转向(8);

(5)选择scc的下一个简单连通子图scc1,令scc=scc1;

(6)判断栈s1中栈顶二元组(scc,cc)的元素cc=<v0,…,vn>和scc=<v0′,...,vm′>是否有重合部分,若没有,转向(4);

(7)计算有向图的连通子图cc=scc∪top(s1).cc,转向(2);

(8)将栈s1栈顶二元组(scc,cc)的scc赋值给scc,即scc=top(s1).scc,s1的栈顶二元组出栈,转向(3);

(9)判断sccset是否为空,若不是,转向(1);否则,生成有向图的所有连通子图,并存放在ccset中,结束。

进一步,所述(6)具体包括:

1)判断cc=<v0,…,vn>和scc=<v0′,...,vm′>是否有公共部分;

2)若cc和scc包含共同的顶点,则cc和scc有重合部分,结束,否则cc和scc没有重合部分,结束。

步骤一至步骤四是基于有向图的深度优先遍历,从有向图一个未被访问的顶点出发,重复步骤二至步骤四,将每一个首次被访问的顶点压入栈s中(即栈s中存储的是有向图的简单路径),然后访问栈顶顶点的邻接顶点,直至该顶点不是被首次访问时,执行步骤五。

图5是一个有向图,从有向图一个未被访问的顶点1出发,重复步骤二至步骤四后栈s=<1,2,3>,执行步骤三;由于顶点3没有邻接顶点,转向步骤七;w=3,栈顶顶点出栈,s=<1,2>,v=2;执行步骤八;选择顶点2相对于3的下一个邻接顶点5,w=5,转向步骤四;顶点5未被访问;将顶点5压入栈中,s=<1,2,5>,执行步骤三至步骤四;选择顶点5的第一个邻接顶点4,转向步骤二、三、四;顶点4入栈,s=<1,2,5,4>;选择顶点4的第一个邻接顶点5,顶点5已经被访问过,执行步骤五;

步骤五:顶点5在栈s=<1,2,5,4>中,计算有向图的简单连通子图scc1=<5,4>,将scc1不重复的添加至sccset中,此时,sccset={<5,4>},转向步骤八;顶点5是顶点4的最后一个邻接顶点,转向步骤七;w=4,栈顶顶点出栈,s=<1,2,5>,v=5,执行步骤八;顶点4不是顶点5的最后一个顶点,选择顶点5的相对于顶点4下一个邻接顶点6,转向步骤四;

步骤四:顶点6未被访问,转向步骤二;将顶点6压入栈s中,s=<1,2,5,6>,执行步骤三;顶点6没有邻接顶点,转向步骤七;w=6,栈顶顶点出栈,s=<1,2,5>,v=5,转向步骤八;顶点6不是顶点5的最后一个顶点,取顶点5相对于顶点6的下一个顶点1,w=1,转向步骤四;

步骤四、五:顶点1已被访问过,并且在栈s中,计算简单连通子图scc1=<1,2,5>,将scc1不重复的添加至sccset中,sccset={<5,4>,<1,2,5>},转向步骤八;

重复步骤八和步骤七,得到栈s=<1>,访问顶点1相对于顶点2的下一个邻接顶点5,转向步骤四;

步骤四、五:顶点5已被访问且不在s中,转向步骤六;将计算得到的所有简单连通子图sccset1={<1,5>}无重复添加至sccset中,sccset={<5,4>,<1,2,5>,<1,5>},转向步骤八,具体计算步骤如下:

第一步:选择sccset中第一个简单连通子图scc=<5,4>,执行第二步;

第二步:w=5在scc=<5,4>中,执行第三步;

第三步:s=<1>与scc=<5,4>无重合部分,执行第四步;

第四步:计算简单连通子图的步骤如下:

(1)令scc2=scc,将二元组(scc2=<5,4>,path=<5,4>)压入栈s2中;

(2)-(3)选择sccset中第一个和scc=<5,4>有公共部分的简单连通子图scc2=<1,2,5>,scc2没被处理过,转向(6);

(6)将二元组(scc2=<1,2,5>,path=<5,1,2>)压入栈s2中,s2=<(<5,4>,<5,4>),(<1,2,5>,<5,1,2>)>,执行(7);

(7)-(9)s=<1>与scc2=<1,2,5>有重合部分<1>;s=<1>与scc和scc2的公共部分<5>没有公共顶点;所以简单连通子图scc1=<1,5>,将scc1无重复的添加至sccset1中,sccset1={<1,5>},scc=scc2,执行(2);

(2)-(4)选择sccset中第一个和scc=<1,2,5>有公共部分的简单连通子图scc2=<5,4>;scc2已被处理过;scc2=<5,4>是最后一个和scc=<1,2,5>有公共部分的简单连通子图,将s2的栈顶二元组的scc2赋值给scc2,scc2=<1,2,5>,s2的栈顶二元组出栈,s2=<(<5,4>,<5,4>)>,执行(10);

(10)s2不为空,将s2栈顶二元组的scc2赋值给scc,scc=<5,4>,执行(4);

(4)scc2=<1,2,5>是最后一个和scc=<5,4>有公共部分的简单连通子图,将s2的栈顶二元组的scc2赋值给scc2,scc2=<5,4>,s2的栈顶二元组出栈,s2=<>,执行(10);

(10)栈s2为空,返回sccset1={<1,5>},结束。

第五步:scc=<5,4>不是sccset中的最后一个简单连通子图,选择sccset中相对于<5,4>的下一个简单连通子图<1,2,5>,scc=<1,2,5>,转向第二步;

第二步:当前访问顶点5在scc=<1,2,5>中,执行第三步;

第三步:由于s=<1>与scc=<1,2,5>有重合部分<1>,则scc1=<1,5>,将scc1无重复的添加至sccset1中,sccset1={<1,5>},执行第四步;

第四步:计算简单连通子图的步骤如下:

(1)令scc2=scc,将二元组(scc2=<1,2,5>,path=<5,1,2>)压入栈s2中;

(2)-(3)选择sccset中第一个和scc=<1,2,5>有公共部分的简单连通子图scc2=<5,4>,scc2没被处理过,转向(6);

(6)将二元组(scc2=<5,4>,path=<5,4>)压入栈s2中,s2=<(<1,2,5>,<5,1,2>),(<5,4>,<5,4>)>,执行(7);

(7)和(9)s=<1>与scc2=<5,4>没有重合部分,scc=scc2,执行(2);

(2)-(4)选择sccset中第一个和scc=<5,4>有公共部分的简单连通子图scc2=<1,2,5>;scc2已被处理过;scc2=<1,2,5>是最后一个和scc=<5,4>有公共部分的简单连通子图,将s2的栈顶二元组的scc2赋值给scc2,scc2=<5,4>,s2的栈顶二元组出栈,s2=<(<1,2,5>,<5,1,2>)>,执行(10);

(10)s2不为空,将s2的栈顶二元组的scc2赋值给scc,scc=<1,2,5>,执行(4);

(4)scc2=<5,4>是最后一个和scc=<1,2,5>有公共部分的简单连通子图,将s2的栈顶二元组的scc2赋值给scc2,scc2=<1,2,5>,s2的栈顶二元组出栈,s2=<>,执行(10);

(10)栈s2为空,返回sccset1={<1,5>},结束。

从步骤六转向步骤八:顶点5是顶点1的最后一个邻接顶点,转向步骤七;w=1,栈顶顶点出栈,s=<>,栈s为空,转向步骤九;有向图的所有顶点全部被访问,获得有向图的所有简单连通子图sccset={<5,4>,<1,2,5>,<1,5>},转向步骤十;

步骤十:根据步骤一至步骤九,生成有向图的所有简单连通子图sccset={<5,4>,<1,2,5>,<1,5>},进而生成有向图的所有连通子图的过程如下:

(1)至(2):选择sccset中的第一个简单连通子图cc=<5,4>,scc=cc=<5,4>,将二元组(<5,4>,<5,4>)压入栈s1中,s1=<(<5,4>,<5,4>)>,并将cc无重复的添加至ccset中,ccset={<5,4>},执行(3);

(3)至(5):s1不为空,<5,4>不是sccset的最后一个简单连通子图,选择scc=<5,4>的下一个简单连通子图scc1=<1,2,5>,scc=scc1=<1,2,5>,执行(6);

(6)至(7)和(2):top(s1).cc=<5,4>与scc=<1,2,5>有重合部分<5>,计算有向图的连通子图cc=<5,4>∪<1,2,5>=<1,2,4,5>,将(<1,2,5>,<1,2,4,5>)压入栈s1中,s1=<(<5,4>,<5,4>),(<1,2,5>,<1,2,4,5>)>,将cc无重复添加至ccset中,ccset={<5,4>,<1,2,4,5>},执行(3);

(3)至(5):s1不为空,<1,2,5>不是sccset的最后一个简单连通子图,取scc=<1,2,5>的下一个简单连通子图scc1=<1,5>,scc=scc1=<1,5>,执行(6);

(6)至(7)和(2):top(s1).cc=<1,2,4,5>与scc=<1,5>的重合部分为<1,5>,计算有向图的连通子图cc=<1,5>∪<1,2,4,5>=<1,2,4,5>,将(<1,5>,<1,2,4,5>)压入栈s1中,s1=<(<5,4>,<5,4>),(<1,2,5>,<1,2,4,5>),(<1,5>,<1,2,4,5>)>,将cc无重复添加至ccset中,ccset={<5,4>,<1,2,4,5>},执行(3);

重复两次(3)至(4)和(8):scc=<1,5>是sccset的最后一个元素,scc=top(s1).scc=<1,5>,s1的栈顶二元组出栈,s1=<(<5,4>,<5,4>),(<1,2,5>,<1,2,4,5>)>,s1不为空,scc=<1,5>是sccset的最后一个元素,scc=top(s1).scc=<1,2,5>,s1的栈顶二元组出栈,s1=<(<5,4>,<5,4>)>,转向(3);

(3)至(5):取scc=<1,2,5>的下一个简单连通子图scc1=<1,5>,scc=scc1=<1,5>,执行(6);

(6)至(7)和(2):top(s1).cc=<5,4>与scc=<1,5>的重合部分为<5>,故cc=<1,5>∪<5,4>=<1,4,5>,将(<1,5>,<1,4,5>)压入栈s1中,s1=<(<5,4>,<5,4>),(<1,5>,<1,4,5>)>,将cc无重复添加至ccset中,ccset={<5,4>,<1,2,4,5>,<1,4,5>},执行(3);

重复两次(3)至(4)和(8):scc=<1,5>是sccset的最后一个元素,scc=top(s1).scc=<1,5>,s1的栈顶二元组出栈,s1=<(<5,4>,<5,4>)>;scc=<1,5>是sccset的最后一个元素,scc=top(s1).scc=<5,4>,s1的栈顶二元组出栈,s1=<>,转向(3);

(3)和(9):栈s1为空,删除sccset的第一个简单连通子图,sccset={<1,2,5>,<1,5>},转向(1);

执行(1)至(9),直至sccset为空为止,最后生成有向图的所有连通子图为ccset={<5,4>,<1,2,4,5>,<1,4,5>,<1,2,5>,<1,5>}。

本发明一种有向图中所有连通子图的快速生成方法,与目前已存在的方法的比较如表1所示。有向图的简单连通子图用构成简单连通子图的有序顶点序列表示,遍历过程中,对每个顶点只处理一次,遍历结束后,可以生成有向图的所有简单连通子图,从而提高了计算效率,同时根据所有简单连通子图可以生成有向图的所有连通子图。

以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。

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