ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

networkx学习与使用——(6)图划分与介数计算

2021-01-25 19:32:50  阅读:294  来源: 互联网

标签:12 0.01098901098901099 0.13186813186813187 划分 介数 networkx path


networkx学习与使用——(5)图划分与介数计算

摘要

图划分按照一定规则将一个连通图划分成几个连通分量,看上去有点像聚类的感觉。从网络的角度,会根据一些重要的节点或边来进行划分,这里介绍划分图的指标——边介数。

图划分

图划分一般有两种方法,“删边法"和"聚集法”。删边法通过删除某条"重要"的边进行划分。聚集法通过将最"接近"的节点聚集起来构成不同的区域。这里介绍依据边介数进行删边的图划分方法。

例子生成

import networkx as nx               #载入networkx包
import matplotlib.pyplot as plt     #用于画图
#生成图
G = nx.Graph()                    #无向图
G_edges = [(1,2),(1,3),(2,3),(3,7),(4,5),
            (4,6),(5,6),(6,7),(7,8),(8,9),
            (8,12),(9,10),(9,11),(10,11),(12,13),
            (12,14),(13,14)]
G.add_edges_from(G_edges)
labels={}
for node in G.nodes():
    labels[node]=str(node)
#画图
pos = nx.kamada_kawai_layout(G)
plt.rcParams['figure.figsize']= (6, 4)      # 设置画布大小 
nx.draw_networkx_nodes(G,pos)               # 画节点
nx.draw_networkx_edges(G,pos)               # 画边
nx.draw_networkx_labels(G,pos,labels)       # 画标签 
plt.axis('off')                             # 去掉坐标刻度  
plt.show()

图划分实例
如果要将上图中的图用删边法将图一分为二,我们会删除哪条边呢?我们一从图中一眼就会选择删除7-8这条边,这是为什么呢?当然我们可以说是因为这条边是割边,但6-7,3-7,8-9和8-12这些边也是割边,为什么我们会更倾向于7-8这条边呢?介数通过某条边传递信息的数量来描述边的重要性给出了一种解释。

介数定义及计算

定义

百度百科:介数通常分为边介数和节点介数两种,其中节点介数定义为网络中所有最短路径中经过该节点的路径的数目占最短路径总数的比例,而边介数定义为网络中所有最短路径中经过该边的路径的数目最短路径总数比例

以上图为例,上图共有14个节点,因此存在1413/2=91条最短路径(上图不存在两个节点间存在多条最短路径的情况)。然后我们计算经过7-8边的最短路径的数量:可以这样考虑,只有上面的节点到达下面的节点需要经过7-8,因此经过7-8的最短路径为77=49条最短路径。所以7-8的边介数为 49 / 91 ≈ 0.5385 49/91\approx0.5385 49/91≈0.5385。

networkx计算边介数

通过networkx的最短路算法实现

通过定义我们发现可以通过最短路路径的算法来实现介数的计算,在networkx学习与使用——(3)路与圈中我们介绍了如何使用networkx对图的最短路进行计算。接下来我们根据最短路的一些函数来设计介数的函数:

def betweeness(G):
    all_shortest_path = []
    result_dict = {}
    node_list = list(G.nodes)
    for i in range(len(node_list)):
        for j in range(i+1,len(node_list)):
            u = node_list[i]
            v = node_list[j]
            all_shortest_path += list(nx.all_shortest_paths(G, u, v))
    all_shortest_path_num = len(all_shortest_path)
    for edge in G.edges:
        u, v = edge
        result_dict[(u,v)] = 0
        for path in all_shortest_path:
            if u in path and v in path:
                result_dict[(u,v)] += 1
        result_dict[(u,v)] /= all_shortest_path_num
    return result_dict
out:
{(1, 2): 0.01098901098901099,
 (1, 3): 0.13186813186813187,
 (2, 3): 0.13186813186813187,
 (3, 7): 0.3626373626373626,
 (4, 5): 0.01098901098901099,
 (4, 6): 0.13186813186813187,
 (5, 6): 0.13186813186813187,
 (7, 6): 0.3626373626373626,
 (7, 8): 0.5384615384615384,
 (8, 9): 0.3626373626373626,
 (8, 12): 0.3626373626373626,
 (9, 10): 0.13186813186813187,
 (9, 11): 0.13186813186813187,
 (10, 11): 0.01098901098901099,
 (12, 13): 0.13186813186813187,
 (12, 14): 0.13186813186813187,
 (13, 14): 0.01098901098901099}

使用networkx的内置函数计算

nx.edge_betweenness()
{(1, 2): 0.01098901098901099,
 (1, 3): 0.13186813186813187,
 (2, 3): 0.13186813186813187,
 (3, 7): 0.3626373626373627,
 (4, 5): 0.01098901098901099,
 (4, 6): 0.13186813186813187,
 (5, 6): 0.13186813186813187,
 (7, 6): 0.3626373626373627,
 (7, 8): 0.5384615384615385,
 (8, 9): 0.3626373626373627,
 (8, 12): 0.3626373626373627,
 (9, 10): 0.13186813186813187,
 (9, 11): 0.13186813186813187,
 (10, 11): 0.01098901098901099,
 (12, 13): 0.13186813186813187,
 (12, 14): 0.13186813186813187,
 (13, 14): 0.01098901098901099}

结果分析

恩,结果一样,没啥大bug,小bug出现了再说。所以我们可以看到7-8的介数最大,即通过7-8的信息是最多的;其次是6-7,3-7,8-9和8-12这些割边,即使都不是割边,我们也能发现1-3和2-3是比1-2重要的边。

参考

networkx官网地址:https://networkx.org/

标签:12,0.01098901098901099,0.13186813186813187,划分,介数,networkx,path
来源: https://blog.csdn.net/m0_37427515/article/details/113126173

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有