发明内容
本发明的目的在于针对现有技术的不足,提供一种拓扑网络的两级分块方法。
本发明解决其技术问题是采取以下技术方案实现的:
一种拓扑网络的两级分块方法,包括步骤如下:
(1)生成拓扑数据:遍历图形中的网络节点,获取节点之间的关联信息;
(2)执行分块操作:分块操作共分为一级分块和二级分块,一级分块是根据节点之间的连通性来划分,二级分块是根据设定的最大节点数来划分;
(3)拓扑块信息的更新与维护:在动态网络中,节点是允许发生改变的,因此在编辑网络时要保证相应拓扑块信息的同步更新;
(4)基于两级分块的拓扑分析。
而且,所述步骤(1)生成拓扑数据的具体步骤如下:
①遍历整个网络,获取节点之间的双向关联关系;
②将节点之间的所有关系存储到内存数据结构节点关系表中,另外,为每一个节点创建状态标识信息并存储到数据结构节点状态表中,并设定初始值为:未检测状态;
③创建执行分块操作所需要的变量:
一级块号,初始值为1,
二级块号,初始值为1,
二级块节点数目,
执行分块操作所需要的变量:
二级块信息存储二级块号与二级块所包含的节点数目的对应关系信息;块边界关系存放二级块与块之间的边界信息;邻接块信息存放与当前二级块相连的其他二级块的块号及节点数目的对应关系;
④设置每个二级块最多包含节点的数目为最大块节点数目;
⑤判断节点状态表中是否存在状态为未检测状态的节点,若存在则以此节点为起点开始探测并对探测到的节点执行分块操作,若不存在则表示所有的节点已经探测完成,此时将每个节点的块信息以及块与块之间的边界信息存储到数据库中。
而且,所述步骤(2)执行分块操作的具体步骤是:
①从节点状态表中获取到状态为未检测状态节点,然后将其加入到检测队列中,执行步骤②;
②判断检测队列是否为空,若不为空,执行步骤③,若为空,执行步骤④;
③取检测队列第一个元素,定为当前节点,并将其从队列中删除,执行步骤⑤;
④队列为空说明当前块划分完毕,比较二级块节点数目与最大块节点数目的一半的大小,若二级块节点数目小于最大块节点数目的一半,说明当前的二级块包含的节点的数目还不足设定的最大数量值的一半,为了防止产生零碎的小块,需要将当前的二级块与相邻的最小的二级块进行合并,然后使一、二级块号的值各自加1,此时保存当前二级块号及二级块节点数目到数据结构二级块信息中,返回继续判断节点状态表中是否有未检测状态的节点,若二级块节点数目大于最大块节点数目的一半,首先使一级块号,二级块号的值各自加1,此时保存当前二级块号及二级块节点数目到数据结构二级块信息,然后执行步骤①,继续判断节点状态表中是否有未检测状态的节点;
⑤在节点关系表中查找与当前节点直接相连节点数,执行步骤⑥;
⑥若直接相连节点数大于0,说明存在相连的节点,取出其中一个邻接节点并查看其状态,若为未检测状态,说明此节点尚未探测,执行步骤⑦;若为已检测状态,说明此节点已经被探测过,执行步骤⑧,若直接相连节点数等于0,说明当前节点的相连节点已经处理完成或者不存在相连节点,设置当前节点的状态为已检测状态,设置当前节点的一级块号和二级块号分别为当前一级块号和二级块号的值,执行步骤②;
⑦比较二级块节点数目与最大块节点数目的大小;
A.若二级块节点数目小于最大块节点数目,说明当前的二级块没有达到个数限制,使直接相连节点数减1,并将当前节点加入队列中,执行步骤⑥;
B.若二级块节点数目大于最大块节点数目,说明当前二级块已经饱和,不能再加入新的节点元素,执行步骤⑧;
⑧判断邻接节点的二级块号是否与当前二级块号的值一致;
A.若不一致,存储邻接节点的二级块号到数据结构邻接块信息中,并存储边界信息存储到数据结构块边界关系中,合并当前节点当前节点与邻接节点的一级块号,使直接相连节点数减1,执行步骤⑥;
B.若一致,使二级块号加1,直接相连节点数减1,执行步骤⑥。
而且,所述步骤(3)拓扑块信息的更新与维护的具体步骤是:
①读取数据库中一级分块和二级分块的最大值,分别赋值给变量最大一级块号、最大二级块号,执行步骤②;
②若执行添加操作,则执行步骤③;若执行删除操作,则执行步骤⑧;若执行修改操作,则先执行步骤⑧再执行步骤③;
③添加一个新节点,从网络中查找与其直接相连节点数并获取数据库中相连节点的拓扑块信息,执行步骤④;
④判断直接相连节点数的值,若直接相连节点数为1,说明在原有的拓扑网络中与新加的节点直接相连的节点只有一个,执行步骤⑤,若直接相连节点数为0,说明新节点为孤立节点,使最大一级块号、最大二级块号的值各自加1并分别赋值给新节点的一、二级块号,然后保存相关信息,退出;若邻接块信息大于1,说明相连节点数目有多个,执行步骤⑥;
⑤设置新节点的一级块号为邻接节点的一级块号,读取邻接节点的二级块节点数目;若二级块节点数目大于1.5×最大块节点数目,说明相连节点所在的二级块不能再添加新的节点,此时要重新创建一个新的二级块,使最大二级块号的值加1并设置其为新二级块的块号;若二级块节点数目小于1.5×最大块节点数目,说明相连节点所在的二级块还可以接受新的节点,设置新节点的二级块为邻接节点的二级块号,最后保存到数据库中,退出;
⑥首先,判断与新节点相连的每个节点所在的一级块是否相同,若不相同,则合并一级块并统一一级块号为之前最大的一级块的块号,然后进一步判断是否需要合并二级分块,若需要则直接合并,若不需要则存储两个二级块之间的边界信息到块边界关系,并将相关信息保存到数据库中;退出,若相同,则直接执行步骤⑦;
⑦判断与新节点相连的每个节点所在的二级块是否相同,若不相同,则获取所有相邻节点的二级块中最小块的二级块号,并将其设为新节点的二级块号,同时,增加若干条由于新节点导致的块与块之间的边界信息,最后保存到数据库中,退出;若相同,则执行步骤④;
⑧删除一个旧节点,首先,读取旧节点的拓扑信息,删除旧节点到其他相邻节点的单向关系信息,然后,查看与旧节点直接相连的所有节点邻接节点的直接相连节点数,并从数据库中读取每个相连节点的拓扑信息,若直接相连节点数为0,则直接退出;若直接相连节点数为1,则更新相邻节点到的单向关联关系,然后退出,若直接相连节点数大于1,执行步骤⑨;
⑨判断旧节点与所有直接相连的邻接节点是否处在相同二级块内,若是,由于删除掉节点可能导致原来的二级块不再是一个连通的整体,所以需要加载此二级块的数据进行重新进行探测,重新探测二级块,若原来的块仍然是一个连通的整体,则直接退出,若原来的块不再是一个连通的整体,则需要进一步探测所在的一级块是否是一个连通的整体,执行步骤⑩,若不是,则删除掉用旧节点来标识的二级块边界信息,执行步骤⑩;
⑩加载当前一级块数据,并重新探测当前一级块是否仍然是一个连通的整体,若是,则直接退出,若不是,则需要对当前一级块单独执行分块操作来重新划分块。
而且,所述步骤(4)基于两级分块的拓扑分析的具体步骤是:
①确定分析类型,若基于单节点分析,则执行步骤②;若基于多节点分析,则执行步骤③;
②输入待分析节点单节点的信息,查询数据库读取单节点的一级块号和二级块号,然后加载整个一级块或者二级块的数据进行分析;
③输入多个节点的信息,分别获取它们的一级块号和二级块号,首先,判断一级块号是否相同,若不相同,则节点之间肯定不存在拓扑关系,若相同,则继续判断一级块号是否相同,若相同,则加载二级块号的块数据进行分析或者直接加载一级块的数据进行分析,若不相同,则需要分别加载每个节点所在的二级块数据,以及当前一级块内的所有二级块之间的边界信息进行拓扑分析或者直接加载一级块的数据进行分析。
本发明的优点和积极效果是
本发明利用了两级分块的算法,通过连通性建立网络孤岛,对每个网络孤岛又执行了进一步的划分。该方法有效的控制了拓扑遍历的数据量,避免了拓扑分析时对整个拓扑网络的遍历,也能很好地解决整个网络都是一个连通整体时的情况。
具体实施方式
以下结合附图对本发明实施例做进一步详述,以下实施例只是描述性的,不是限定性的,不能以此限定本发明的保护范围。
一种拓扑网络的两级分块方法,如图1所示,包括步骤如下:
(1)生成拓扑数据:拓扑数据是根据图形数据来生成的,需要遍历图形中的网络节点来获取节点之间的关联信息,具体步骤如下:
①遍历整个网络,获取节点之间的双向关联关系;比如:节点A与节点B直接相连,关系表示为:A,B,info(A);B,A,info(B);
②将节点之间的所有关系存储到内存数据结构节点关系表RelationTable中,另外,为每一个节点创建状态标识信息并存储到数据结构节点状态表StateTable中,并设定初始值为:未检测状态Unchecked。
③创建执行分块操作所需要的变量:
一级块号SectionOneID,初始值为1
二级块号SectionTwoID,初始值为1,
二级块节点数目SectionTwoSize,
执行分块操作所需要的变量:
二级块信息SectionInfo存储二级块号与二级块所包含的节点数目的对应关系信息;块边界关系BoundaryRelation存放二级块与块之间的边界信息;邻接块信息AbutSection存放与当前二级块相连的其他二级块的块号及节点数目SectionTwoSize的对应关系;
④为了限制拓扑分析时加载的数据量,提高拓扑分析效率,设置每个二级块最多包含节点的数目为最大块节点数目MaxSectionSize。
⑤接下来判断节点状态表StateTable中是否存在状态为未检测状态Unchecked的节点,若存在则以此节点为起点开始探测并对探测到的节点执行分块操作,如图2所示,若不存在则表示所有的节点已经探测完成,此时将每个节点的块信息以及块与块之间的边界信息存储到数据库中;
(2)执行分块操作;分块操作共分为一级分块和二级分块,一级分块是根据节点之间的连通性来划分,二级分块是根据设定的最大节点数来划分,整个分块过程如图2所示,此部分承接自图1中的“执行拓扑分块操作”,具体步骤如下:
①从节点状态表StateTable中获取到状态为未检测状态Unchecked节点,然后将其加入到检测队列CheckingQueue中,等待进一步的处理,执行步骤②。
②判断检测队列CheckingQueue是否为空,若不为空,执行步骤③,若为空,执行步骤④;
③取检测队列CheckingQueue第一个元素,赋值给当前节点TempJoint,并将其从队列中删除,执行步骤⑤;
④队列为空说明当前块划分完毕,比较二级块节点数目SectionTwoSize与最大块节点数目的一半MaxSectionSize/2的大小,若二级块节点数目SectionTwoSize<最大块节点数目的一半MaxSectionSize/2,说明当前的二级块包含的节点的数目还不足设定的最大数量值的一半,为了防止产生零碎的小块,需要将当前的二级块与相邻的最小的二级块进行合并,然后使一级块号SectionOneID,二级块号SectionTwoID的值各自加1,此时保存当前二级块号SectionTwoID及二级块节点数目SectionTwoSize到数据结构二级块信息SectionInfo中,返回继续判断节点状态表StateTable中是否有未检测状态Unchecked的节点,如图1所示,若二级块节点数目SectionTwoSize>最大块节点数目的一半MaxSectionSize/2,首先使一级块号SectionOneID,二级块号SectionTwoID的值各自加1,此时保存当前二级块号SectionTwoID及二级块节点数目SectionTwoSize到数据结构二级块信息SectionInfo,然后执行步骤①,继续判断节点状态表StateTable中是否有未检测状态Unchecked的节点;
⑤在节点关系表RelationTable中查找与当前节点TempJoint直接相连节点数AbutJointNum,执行步骤⑥;
⑥若直接相连节点数AbutJointNum>0,说明存在相连的节点,取出其中一个邻接节点AbutJoint并查看其状态,若为未检测状态Unchecked,说明此节点尚未探测,执行步骤⑦;若为已检测状态Checked,说明此节点已经被探测过,执行步骤⑧,若直接相连节点数AbutJointNum=0,说明当前节点TempJoint的相连节点已经处理完成或者不存在相连节点,设置当前节点TempJoint的状态为已检测状态Checked,当前节点TempJoint的一级块号和二级块号分别为当前一级块号SectionOneID和二级块号SectionTwoID的值,执行步骤②;
⑦比较二级块节点数目SectionTwoSize与最大块节点数目MaxSectionSize的大小:
A.若二级块节点数目SectionTwoSize<最大块节点数目MaxSectionSize,说明当前的二级块没有达到个数限制,使直接相连节点数AbutJointNum-1,并将当前节点加入队列中,执行步骤⑥;
B.若二级块节点数目SectionTwoSize>最大块节点数目MaxSectionSize,说明当前二级块已经饱和,不能再加入新的节点元素,执行步骤⑧。
⑧判断邻接节点AbutJoint的二级块号是否与当前二级块号SectionTwoID的值一致;
A.若不一致,存储邻接节点AbutJoint的二级块号SectionTwoID到数据结构邻接块信息AbutSection中,并存储边界信息存储到数据结构块边界关系BoundaryRelation中,合并当前节点当前节点TempJoint与邻接节点AbutJoint的一级块号SectionOneID,使直接相连节点数AbutJointNum-1,执行步骤⑥;
B.若一致,使二级块号SectionTwoID+1,直接相连节点数AbutJointNum-1,执行步骤⑥;
(3)拓扑块信息的更新与维护;在动态网络中,节点是允许发生改变的,因此在编辑网络的时候要保证相应的拓扑块信息的同步更新,如图3所示,其中修改操作,相当于先执行删除,然后再执行添加;具体步骤如下:
①读取数据库中一级分块和二级分块的最大值,分别赋值给变量最大一级块号MaxSectionOneID、最大二级块号MaxSectionTwoID,执行步骤②;
②若执行“添加”操作,则执行步骤③;若执行“删除”操作,则执行步骤⑧;若执行“修改”操作,则先执行⑧再执行步骤③。
③添加一个新节点NewJoint,从网络中查找与其直接相连节点数AbutJointNum并获取数据库中相连节点的拓扑块信息,执行步骤④;
④判断直接相连节点数AbutJointNum的值,若直接相连节点数AbutJointNum=1,说明在原有的拓扑网络中与新加的节点直接相连的节点只有一个,执行步骤⑤,若直接相连节点数AbutJointNum=0,说明新节点NewJoint为孤立节点,使最大一级块号MaxSectionOneID、最大二级块号MaxSectionTwoID的值各自加1并分别赋值给新节点NewJoint的一二级块号,然后保存相关信息,退出,若邻接块信息AbutSectionNum>1,说明相连节点数目有多个,执行步骤⑥;
⑤设置新节点NewJoint的一级块号为邻接节点AbutJoint的一级块号SectionOneID,读取邻接节点AbutJoint的二级块节点数目SectionTwoSize;若二级块节点数目SectionTwoSize>1.5×最大块节点数目MaxSectionSize,说明相连节点所在的二级块不能再添加新的节点,此时要重新创建一个新的二级块,使最大二级块号MaxSectionTwoID的值加1并设置其为新二级块的块号;若二级块节点数目SectionTwoSize<1.5×最大块节点数目MaxSectionSize,说明相连节点所在的二级块还可以接受新的节点,设置新节点NewJoint的二级块ID为邻接节点AbutJoint的二级块ID,最后保存到数据库中,退出;
⑥首先,判断与新节点NewJoint相连的每个节点所在的一级块是否相同,若不相同,则合并一级块并统一一级块号为之前最大的一级块的块号,然后进一步判断是否需要合并二级分块,若需要则直接合并,若不需要则存储两个二级块之间的边界信息到块边界关系BoundaryRelation,并将相关信息保存到数据库中,退出,若相同,则直接执行步骤⑦。
⑦判断与新节点NewJoint相连的每个节点所在的二级块是否相同,若不相同,则获取所有相邻节点的二级块中最小块的二级块号SectionTwoID,并将其设为新节点NewJoint的二级块号,同时,增加若干条由于新节点NewJoint导致的块与块之间的边界信息,最后保存到数据库中,退出,若相同,则执行步骤④;
⑧删除一个旧节点OldJoint,首先,读取旧节点OldJoint的拓扑信息,删除旧节点OldJoint到其他相邻节点的单向关系信息,然后,查看与旧节点OldJoint直接相连的所有节点邻接节点AbutJoint的直接相连节点数AbutJointNum,并从数据库中读取每个相连节点的拓扑信息,若直接相连节点数AbutJointNum=0,则直接退出;若直接相连节点数AbutJointNum=1,则更新相邻节点到OldJoint的单向关联关系,然后退出,若直接相连节点数AbutJointNum>1,执行步骤⑨;
⑨判断旧节点OldJoint与所有直接相连的邻接节点AbutJoint是否处在相同二级块内,若是,由于删除掉节点可能导致原来的二级块不再是一个连通的整体,所以需要加载此二级块的数据进行重新进行探测,重新探测二级块,若原来的块仍然是一个连通的整体,则直接退出,若原来的块不再是一个连通的整体,则需要进一步探测所在的一级块是否是一个连通的整体,执行步骤⑩,若不是,则删除掉用旧节点OldJoint来标识的二级块边界信息,执行步骤⑩;
⑩加载当前一级块数据,并重新探测当前一级块是否仍然是一个连通的整体,若是,则直接退出,若不是,则需要对当前一级块单独执行分块操作来重新划分块;
(4)基于两级分块的拓扑分析;两级分块使得拓扑分析变得更加方便和快捷,在一定程度上,不仅节省了内存而且提高了分析效率,具体步骤为:
①确定分析类型,若基于单节点分析,则执行步骤②;若基于多节点分析,则执行步骤③;
②输入待分析节点单节点SingleJoint的信息,查询数据库读取单节点SingleJoint的一级块号SectionOneID和二级块号SectionTwoID,然后根据需求加载整个一级块或者二级块的数据进行分析;
③输入多个节点的信息,分别获取它们的一级块号SectionOneID和二级块号SectionTwoID,首先,判断一级块号SecionOneID是否相同,若不相同,则节点之间肯定不存在拓扑关系,若相同,则继续判断一级块号SectionTwoID是否相同,若相同,则加载二级块号SectionTwoID的块数据进行分析或者根据不同的需求直接加载一级块的数据进行分析,若不相同,则需要分别加载每个节点所在的二级块数据,以及当前一级块内的所有二级块之间的边界信息进行拓扑分析或者根据不同的需求直接加载一级块的数据进行分析。
实例
为了清晰描述本发明的内容,选取一个简单的拓扑网络来详细说明执行步骤,如图5所示,网络中总共有16个节点,
(1)生成拓扑数据;
①获取网络中节点之间的双向关联关系,假设从J1开始遍历,依次获取每个节点之间的双向关联关系,存储到节点关系表RelationTable中,如表1,同时为每一个节点创建状态信息存储到节点状态表StateTable;
表1从网络中获取的节点关系表RelationTable表
Joint |
AbutJoint |
SectionOneID |
SectionTwoID |
Info |
J1 |
J2 |
Null |
Null |
Info(J1) |
J2 |
J1 |
Null |
Null |
Info(J2) |
J2 |
J3 |
Null |
Null |
Info(J2) |
J2 |
J4 |
Null |
Null |
Info(J2) |
J3 |
J2 |
Null |
Null |
Info(J3) |
J4 |
J2 |
Null |
Null |
Info(J4) |
… |
… |
Null |
Null |
… |
②创建相关的数据结构和变量,并设置MaxSectionSize=6;
③依次检查StateTable中每个节点的状态,查找状态位Uncheced的节点,这里第一个节点为J1,从J1开始探测并执行分块操作;
(2)执行分块操作;
①创建队列CheckingQueue,并将J1入栈,然后,检查CheckingQueue当前状态发现有一个元素J1,将其赋值给TempJoint,并将其从队列中删除;
②在节点关系表RelationTable中查找与J1相邻的节点的个数AbutNum=1,且相邻的节点AbutJoint为J2,并且其状态为Unchecked,这时使AbutNum的值减1,将J2加入CheckingQueue中,此时AbutNum=0,设置J1的状态为Checked,SectionOneID=1,SectionTwoID=1,然后,继续判断队列是否为空,依次循环;
③当TempJoint=J4,AbutJoint=J7时,发现此时SectionTwoSize=6已经达到了设定的最大值,执行AbutNum-1后,AbutNum变为0,这时,设置J4的状态为Checked,SectionOneID=1,SectionTwoID=1;
④此时队列中只有J6,J6的相邻节点只有1个且为J4,而J4的状态为Checked,其二级块号与当前SectionTwoID的值一致,说明J4与J6在同一二级块内,使AbutNum的值减1,此时AbutNum的值变为了0,然后,设置J6的一二级块号为1,状态为Checked;
⑤再次判断队列,发现为空,而SectionTwoSize>MaxSectionSize/2,所以使SectionOneID与SectionTwoID的值加1,此时SectionTwoID=1,SectionTwoSize=6,将二者的对应关系存储到SectionInfo中,继续在StateTable中查找下一个状态为Unchecked的节点;
⑥读取StateTable表的,下一个Unchecked的节点为J7,从J7开始继续安装上述流程执行分块操作;
⑦当TempJoint=J7,AbutJoint=J4时,发现J4的状态为Checked,且其二级块号为1,而当前的SectionTwoID=2,说明J7与J4处于二级块1与块2的边界上,保存此边界信息到BoundaryRelation中,并将SectionTwoID=1保存到AbutSection中,将此时的SectionOneID由2改为1,表明二级块1和二级块2处在同一个一级块内,继续循环执行;
⑧当TempJoint=J11,AbutJoint=J13时,完成对二级块2的分块操作,此时StateTable中状态为Unchecked的节点为J13,对J13执行分块操作时,发现只有一个节点,此时SectionTwoSize=1,MaxSectionSize/2=6/2=3,所以将二级块3与二级块2实现合并,至此一块1划分完成,总共分了2个二级块;
⑨以同样的方式划分一块2,以及对应的二级块3,划分完的情况如图5所示;
(3)拓扑块信息的更新与维护;这一部分分为“添加”、“删除”和“修改”,修改是前两者的结合这里就不再赘述,“添加”和“删除”部分又分了3种情况:孤立点、一个相邻节点、多个相邻节点,这里就以最复杂的多个相邻节点为例来阐述,
①添加一个节点J17,其有两个邻接节点J5和J16,如图7所示;
A.判断J5的一级块号为1,J16的一级块号为2,所以需要合并一级块,由于一级块2只有3个节点,所以将块2合并到块1中;
B.然后判断是否需要合并二级块,J5和J16所在的二级块所包含的节点数都大于等于MaxSectionSize的一半,即3个,所以不需要合并二级块,只是将新产生的边界信息写入到BoundaryRelation;
C.最后产生的拓扑结构如图7所示,生成一个一级块,3个二级块,2条边界信息;
②删除节点J7,其有两个相邻节点J4和J8,如图6所示;
A.首先,删除数据库中J7的单向关系数据,这里是J7,J4,Info(J7);J7,J8,Info(J7);
B.读取J4和J8的拓扑信息。它们的一二级块号分别为(1,1)、(1,2);
C.相邻节点个数为AbutJointNum=2,由于J4与J7处于不同的二级块中,所以要删除掉包含J4和J7的边界信息;
D.由于删除了边界,可能导致原有的一级块不再是完整的连通体,所以对一级块1进行重新探测,发现二级块1和2之间只有J4和J7一条边界连接,删除以后导致一级块不再是一个整体;
E.重新对一级块1执行分块操作,获得如图6所示的结果,原来的一级块1,分成了两个一级块,块3和块4,每个块内部都有一个二级块,这里注意块号是在原有的基础上累加的;
(4)基于两级分块的拓扑分析操作;对于分析操作,这里就以连通性分析为例来阐述,连通性分析就是给定两个节点判断它们之间是否存在连通性,以图5为示例图来解释:
①分别输入J1和J7的ID。在数据库中查找两节点属于同一一级块1,所以两者之间存在连通性;
②分别数据J1和J16的ID,在数据库中查找,发现两节点属于不同的一级块,所以两者之间不存在连通性。