在通信网络理论中,常用以下几个参数来描述一个无向图或有向图的连通性和可靠性等特性:
端连通度α:指无向图中任意两个顶点之间互相到达的路径数,或有向图中以某个顶点为源点和汇点的最大流量。端连通度越高,说明图中的节点连接越紧密,信息传输的可靠性也就越高。
边连通度β:指无向图中删除一些边后,其仍然保持连通的最小边数;或有向图中从某个节点出发和到达的边集合中的最小割大小。边连通度越高,说明图中的边连接越紧密,信息传输的可靠性也就越高。
混合连通度γ:指端连通度和边连通度中的较大者,即γ=max{α, β},或者可以直接γ=α这样近似计算。混合连通度反映了整个图的整体连通性,它越高,说明图中节点和边都连接得非常紧密,信息传输的可靠性也就越高。
最小割端集的数目Cα:指从一个无向图中去掉α个端点后,该图不再连通,且α的取值最小。Cα越小,表示故障或攻击后该图仍然保持连通的能力越高。
最小割边集的数目Bβ:指从一个无向图中去掉β条边后,该图不再连通,且β的取值最小。Bβ越小,表示故障或攻击后该图仍然保持连通的能力越高。
混合割集的数目Aγ:指在整个图中删除多少个节点和边,才能将该图分割成若干个不连通的部分,且删除的节点和边数最小。Aγ越小,表示故障或攻击后该图仍然保持连通的能力越高。
这些参数是分析、设计和优化通信网络的重要工具,可以帮助工程师们评估网络的性能和可靠性,并采取相应的措施来提高网络的运行效率和安全性。
那么如何利用python来计算一个无向图中的这些指标呢?
要计算无向图的这些指标,可以使用Python中的networkx库。networkx是一个用于创建、操作和研究复杂网络的Python库,提供了丰富的图论算法和可视化工具,非常适合用于计算无向图的各种特征参数。
然而,官方给的文档实在是晦涩难懂,不同版本的networkx传参各不相同,搞的头昏脑涨。而且,网上一大堆的文章也都没有可以完整的算出这些所有参数的。
经过本人狂肝两天,终于逐个搞清楚了这些参数的具体算法,并且成功将所有的数值都算了出来。以下记录一下艰辛历程:
这三个数不难算,也没什么争议,networkx包中有对应的方法,直接调用即可。(下图代码示例一个简单的无对角线的四边形)
import networkx as nx
# 生成一个无向图
G = nx.Graph()
G.add_edges_from([(1, 2), (1, 0), (2, 3), (3, 0)])
# 计算端连通度
a = nx.node_connectivity(G)
print("端连通度α =", a)
# 计算边连通度
b = nx.edge_connectivity(G)
print("边连通度β =", b)
# 计算混合连通度
gamma = max(a, b)
print("混合连通度γ =", gamma)
经过研究发现,是不能直接获取到的,需要先找出来最小割端集,这个是有现成方法可以直接调用的,然后这个最小割端集的长度就是Cα了:
# 计算最小割边集
Cα_list=list(nx.all_node_cuts(G))
# 计算最小割边集的数目
Cα=len(Cα_list)
print("最小割端集的数目Cα =",Cα)
这个找了一圈都没有发现有方法可以调用,我心想着有nx.all_node_cuts(G)方法,应该也就会有nx.all_edge_cuts(G)方法吧。
然而,并没有,看了很多文章和文档,要么就是说的不靠谱,一怒之下,自己写吧,反正原理也很简单:
最小割边集就是要算:
1.最小去掉几条边,图像就不连通了。
2.然后把所有的情况都汇总到一起,就是最小割边集,
3.然后这个集合的长度(集合中元素的个数)就是Bβ的值。
经过本人研究发现,边连通度β就是最小割边集中每个元素的长度(请原谅我不是通信专业的,基础不扎实,此处不确定是否是巧合),
通俗点讲就是:
比如有4条边 a b c d
β的值是2,那就是说每一个边割集至少都是2条边的组合,现在所以需要计算这2条边的组合共有哪些组合方式,那组合出来就是 ab ac ad bc bd cd 这几种情况。
然后把所有组合方式逐个去验证,验证方法就是:在原图上去掉其中一种组合,看剩下的图是否还连同,如果不连同,那就说明符合要求,反之,不符合要求抛弃掉。
根据这个思路写出来的算法:
def compute_edge_cuts(G,beta):
#计算beta长度的线的组合集合
edges_combinations = set(itertools.combinations(G.edges(), beta))
edge_cuts=[]
for comb in edges_combinations:
# 创建子图,以便在子图上执行操作,不影响 G
subG = G.copy()
# 从子图中删除对应的边
subG.remove_edges_from(comb)
# 检查子图是否连通,如果不连通,则将对应的组合添加到 edge_cuts 中
if not nx.is_connected(subG):
edge_cuts.append(comb)
return edge_cuts
由此,算出了最小割边集,然后取它的长度,就可以轻易的得到最小割边集的数目Bβ的值了。
这个我花费的时间最多(当然也是网上各种资料都找了,没有可用的方法,然后自己开始写具体实现)。
其实理论上讲和计算最小割边集的实现思路是一样的:
混合集的话,就是至少有一个点或者一条边
1.要根据伽马的长度 算出各种组合
2.比如伽马是3,那就有两种情况,1个点2条边,或者2个点一条边
3.然后再根据图形具体的点和边,算出来所有可能的组合方式。注意:这里算组合方式的时候,会遇到一个问题,如果组合中已经存在点A了,那么这个组合中的线段中就不能有由A组成的线段。(因为去掉A点之后,A相关的线段本来就已经去掉了,所以这种组合方式不成立,直接抛弃)
4.然后把所有组合方式逐个去验证,验证方法就是,在原图上去掉其中一种组合,看剩下的图是否还连同,如果不连同,那就说明符合要求,反之,不符合要求抛弃掉。下面是实现代码,写的很不优雅(行家轻喷)
def compute_mix_cuts(G,gamma):
list1=G.nodes()
list2=G.edges()
mix=gamma
mix_list = []
for i in range(1, mix):
for j in range(1, mix):
if i + j == mix:
mix_list.append([i, j])
comb_reulst = []
for data in mix_list:
i,v=data
comb_list1 = list(itertools.combinations(list1, i))
comb_list2 = list(itertools.combinations(list2, v))
for x in comb_list1:
a_concat=''
for y in comb_list2:
for num in x:
b_concat = ''
for tup in y:
for i in tup:
b_concat += str(i)
if str(num) in b_concat:
break
else:
comb_reulst.append(x + y)
s =