图论之-Python NetworkX 入门

1:图论概述

1.1图论基本概念

1图

一个图G = (V, E)由一些点及点之间的连线(称为边)构成,V、E分别计G的点集合和边集合。在图的概念中,点的空间位置,边的区直长短都无关紧要,重要的是其中有几个点以及那些点之间有变相连。

图1:图示例

2有向图和无向图

最基本的图通常被定义为“无向图”,与之对应的则被称为“有向图”。两者唯一的区别在于,有向图中的边是有方向性的。

图2:有向图和无向图

注:上图左边为无向图,右边为有向图。黑色加粗部分表示边的方向。比如:1—>2便是边是1到2这个方向。

3图的度

度是相对于图中点的概念,图中任意一点v的度是指:与v相连的边的条数。在有向图中与顶点v出关联的边的数目称为出度,与顶点v入关联的边的数目称为入度。比如上图2:左边无向图顶点2的度是3.右边有向图点点2的出度是2,入度是1.

4图的连通性

在图G中,若顶点u,v之间有路(即找到有u到v之间相连的边)则称u,v连通。若G的任何两点之间有路,则称G是连通图。G的极大连通子图称为连通分支。如果连通图是有向图则称G是强连通的。

5图的最短路径

在图上任取两顶点,分别作为起点和终点,我们可以规划许多条由起点到终点的路线。不会来来回回绕圈子、不会重复经过同一个点和同一条边的路线,就是一条“路径”,这些路径中经过顶点最少的那个路径就是最短路径。

6图的简单路径

如果路径上的各顶点均不互相重复,称这样的路径为简单路径。如果路径上的第一个顶点与最后一个顶点重合,这样的路径称为回路(cycle)或环或圈。比如下图中:(1,2,3,4,5,1),(1,2,3,1),(1,3,4,5,1)等都是简单路径。

图3:简单路径

7图的偏心距(eccentricity)

一个节点的偏心距就是这个节点到其他节点的所有节点的最短路径的最大值。

8图的直径和半径

图的所有节点偏心距的最大值就是图的直径,最小值就是半径。

9图的紧密中心性(closeness)

在图论中,紧密度是图中一个节点的中心性度量。比其他节点更“浅”(也就是说,有更短的测地距离)的节点有更高的紧密度。在网络分析中,紧密度倾向于表示最短路径长度,因为这样会有更多的中心节点赋予更高的值,而且通常与其他度量(比如:度)相联系。紧密度是中心性的一种复杂度量。它被定义为节点v到其它可达节点的平均测地距离(比如:最短路径):

其中当n>=2是从v出发在网络中连通部分V的大小。接近中心性需要考量每个结点到其它结点的最短路的平均长度。也就是说,对于一个结点而言,它距离其它结点越近,那么它的中心度越高。一般来说,那种需要让尽可能多的人使用的设施,它的接近中心度一般是比较高的。

10图的介数中心性(Betweenness Centrality)

对于n各节点的图G=(V, E),节点v的介数CB(v)按如下方式计算:

对于每对节点(s, t),计算他们之间所有的最短路径;

对于每对节点(s, t),通过判断(here, 节点v)求出它在最短路径上的部分;

对每对节点(s, t)求出的部分进行累加

公式表示为:

其中:σst是s到t的最短路径数,σst()是s到t的最短路径中经过v的数量。它可以除以不包括节点v的节点数量(对于无向图是(n-1)(n-2)/2有向图是(n-1)(n-2)类归一化。)中介中心性指的是一个结点担任其它两个结点之间最短路的桥梁的次数。一个结点充当“中介”的次数越高,它的中介中心度就越大。

11图的度中心性

度中心性(Degree Centrality)是在网络分析中刻画节点中心性(Centrality)的最直接度量指标。一个节点的节点度越大就意味着这个节点的度中心性越高,该节点在网络中就越重要。

1.2图论基本算法

1图遍历之BFS算法(广度优先搜索)

算法步骤:

首先选择一个顶点作为起始节点,并将其染成灰色,其余结点为白色。

将起始结点放入队列中。

从队列首部选出一个顶点,并找出所有与之邻接的结点,将找到的邻接结点放入队列尾部,将已访问过结点涂成黑色,没访问过的结点是白色。如果顶点的颜色是灰色,表示已经发现并且放入了队列,如果顶点的颜色是白色,表示还没有发现 。

按照同样的方法处理队列中的下一个结点。

例如:下图

图:BFS搜索

从上图节点1开始搜索,染成灰色,其余白色。此时队列中只有节点{1}

搜索1的邻居节点2, 3,此时1出队染成黑色表示已经访问,23入队{2, 3}

搜索2的邻居节点3, 4,节点3已经在队列所以2出队染成黑色添加4进入队列{3, 4}

搜索3的邻居节点2,4,节点2已经变黑表示已经访问,节点3出队变成黑色4此时就在队列{4}

搜索4的邻居节点1,节点1已变成黑色。所以4出队变成黑色。队列为空。

此时1, 2, 3, 4, 都已经变成黑色。还剩节点5,再从5开始搜索,结束。

2图遍历之DFS算法(深度优先搜索)

算法步骤:

选择起始顶点涂成灰色,表示还未访问;

从该顶点的邻接顶点中选择一个,继续这个过程(即再寻找邻接结点的邻接结点),一直深入下去,直到一个顶点没有邻接结点了,涂黑它,表示访问过了;

回溯到这个涂黑顶点的上一层顶点,再找这个上一层顶点的其余邻接结点,继续如上操作,如果所有邻接结点往下都访问过了,就把自己涂黑,再回溯到更上一层;

上一层继续做如上操作,知道所有顶点都访问过。

实例:用下图作为说明

图:DFS搜索

从节点1开始依次访问1à2à 3之后终止于节点3;

从节点3回溯到节点2,从2à5终止于节点5;

从节点5回溯到2终止于2;

从节点2回溯到1并终止于1;

从顶点4开始访问终止于4.

3Python实现BFS和DFS(基于无向图)。

class Mygraph(object):

def __init__(self, *args, **kwargs):

self.node_neighbors = {}

self.visited = {}

def nodes(self):

return self.node_neighbors

def add_node(self, node):

if not node in self.nodes():

self.node_neighbors = []

def add_nodes(self, nodelist):

for node in nodelist:

self.add_node(node)

def add_edge(self, edge):

u, v = edge

if  u not in self.nodes():

self.node_neighbors[u] = []

if  v not in self.nodes():

self.node_neighbors[v] = []

if (v not in self.node_neighbors[u]) and (u not in self.node_neighbors[v]):

self.node_neighbors[u].append(v)

if u != v:

self.node_neighbors[v].append(u)

def add_edges(self, edges):

for edge in edges:

self.add_edge(edge)

def depth_first_search(self, root=None):

order = []

def dfs(node):

self.visited[node] = True

order.append(node)

for n in self.node_neighbors[node]:

if not n in self.visited:

dfs(n)

if root:

dfs(root)

for node in self.nodes():

if not node in self.visited:

dfs(node)

return order

def breath_first_search(self, root=None):

queue = []

order = []

def bfs():

while len(queue)>0:

node = queue.pop(0)

self.visited[node] = True

for n in self.node_neighbors[node]:

if (not n in self.visited) and (not n in queue):

queue.append(n)

order.append(n)

if root:

queue.append(root)

order.append(root)

bfs()

for node in self.nodes():

if not node in self.visited:

queue.append(node)

order.append(node)

bfs()

return order

if __name__=='__main__':

edges = [(1, 2), (1, 3), (2, 3),

(2, 5), (3, 4), (4, 2),

(4, 5), (5, 3)]

G = Mygraph()

G.add_edges(edges)

print(G.nodes())

print("广度优先遍历:")

bfs_order = G.breath_first_search(1)

print(bfs_order)

G = Mygraph()

G.add_edges(edges)

dfs_order = G.depth_first_search(1)

print("深度优先遍历:")

print(dfs_order)

注:为什么创建图写了两遍,因为只写一次,进行广度优先访问之后,有些会被标记为TRUE,会影响后面深度访问结果。

2:NetworkX入门

2.1Networkx概述与安装

1概述

NetworkX是一款Python的软件包,用于创造、操作复杂网络,以及学习复杂网络的结构、动力学及其功能。 有了NetworkX你就可以用标准或者不标准的数据格式加载或者存储网络,它可以产生许多种类的随机网络或经典网络,也可以分析网络结构,建立网络模型,设计新的网络算法,绘制网络等等

2安装

方式一:pip install networkx就行

方式二:安装Anaconda,本身已经集成了这个包,十分方便。

2.2Networkx使用

1创建图添加节点和边

G = nx.Graph() # 创建无向图(nx.DiGraph() 创建有向图)

G.add_node(0) # 添加一个节点

G.add_nodes_from([1, 2])# 一次添加多个节点

G.add_edge(0, 1) # 添加一条边

G.add_edge(2, 3) # 如果边的节点已经存在,直接覆盖

G.add_edge(4, 5) # 如果边的节点不存在,则添加新节点

G.add_edges_from([(2, 1), (5, 1), (0, 4), (3, 4)]) #添加多条边基于上面添加的节点和边绘制有向图和无向图如下:

注:左图表示有向图,黑色加粗部分表示边的方向。右图表示无向图没有方向之分。图的显示还有两个比较好用的工具就是Cytoscape和Gephi也比较好用,显示图像方便又美观,其中Cytoscape可以读取CSV文件,可以对图进行拖拽。感兴趣的朋友可以研究一下。

2求图的常用属性

读取CSV文件获取图的边集合列表

部分原始数据如图:

计算图的各种属性

整体图,看到所有人都是有联系的,由于人物比较多,所以图显示不出具体的效果。

图:整体关系图

各个节点的度,也就是和其他节点连接的数量,越多表示人物在剧中的重要程度。从列表看出度数大的就是剧中的主角了。

图:各个节点的度

节点的偏心距:任意一个节点到其他节点的最短路径的最大值,可以看到基本上任意两个人通过两个三个人就能找到连通路径,所以居中人物的关系还是比较密的。

图:各个节点的偏心距

查看节点到另一节点或其他节点的最短路径

查看节点到另一节点或其他节点的最短路径的长度

紧密中心性:越大说明中心越强。

介数中心性:

上代码:

import re

import networkx as nx

import matplotlib.pyplot as plt

def create_graph():

G = nx.Graph()

# G = nx.DiGraph()

G.add_node(0) # 添加一个节点

G.add_nodes_from([1, 2])# 一次添加多个节点

G.add_edge(0, 1) # 添加一条边

G.add_edge(2, 3) # 如果边的节点已经存在,直接覆盖

G.add_edge(4, 5) # 如果边的节点不存在,则添加新节点

G.add_edges_from([(2, 1), (5, 1), (0, 4), (3, 4)]) #添加多条边

nx.draw(G, pos=nx.spring_layout(G), with_labels=True)

plt.show()

def read_nodes(filename):

'''读取文件,获取边列表'''

edges_list = []

with open(filename, 'r') as f:

while True:

line = f.readline()

if line:

line = re.sub('\r\n', '', line)

lines = line.split(',')

edges_list.append((lines[0], lines[1]))

edges_list.append((lines[1], lines[0]))

else:

break

return edges_list

‘’’注:因为networkx中求最大连通子图的实现都是基于有向图的,所以在读取数据的时候,添加边的时候都是双向的,这样保证求出来的最大连通子图和无向图是一样的。’’’

def get_graph_attr(edges):

# 1根据边的列表创建无向图

G = nx.DiGraph()

G.add_edges_from(edges)

# 2 查看图中的节点有多少个

nodes = G.nodes()

print(len(nodes)) # 107

# 2 求无向图的最大连通子图

max_component = max(nx.strongly_connected_component_subgraphs(G), key=len)# 最大连通子图

print(len(max_component.nodes())) # 107最大连通子图就是本身

# 3 将图转换为无向图

G = nx.to_undirected(max_component)

# 4 计算图中节点的度,按大小排序

degrees = G.degree() # 所有节点的度

print(sorted(degrees, key=lambda x:x[1], reverse=True))

# 5 计算图的偏心距和直径以及半径

eccdis = nx.eccentricity(G) # 偏心距

print(eccdis)

diamter = max(eccdis.values()) # 直径

radius = min(eccdis.values()) # 半径

print(diamter, radius) # 6, 3

#5 计算图中节点的最短路径

path = nx.shortest_path(G, source='Jon')# 查看谁到谁的最短路径

print(path)

path_length = nx.shortest_path_length(G, source='Jon')# 查看最短路径的长度

print(path_length)

#6 计算图中节点的紧密中心性

close = nx.closeness_centrality(G)#紧密中心性

print(close)

# 7 介数中心性

jie = nx.betweenness_centrality(G)

print(jie)

if __name__=='__main__':

filename = './inputdata/stormofswords.csv'

edges = read_nodes(filename)

get_graph_attr(edges)

3:Louvain算法+NetworkX之社团划分实例

3.1Louvain算法原理

Louvain算法是基于模块度的社区发现算法,该算法在效率和效果上都表现较好,并且能够发现层次性的社区结构,其优化目标是最大化整个社区网络的模块度。

模块度:

模块度是评估一个社区网络划分好坏的度量方法,它的物理含义是社区内节点的连边数与随机情况下的边数只差,它的取值范围是 [−1/2,1)其公式如下:

其中,Aij节点i和节点j之间边的权重,网络不是带权图时,所有边的权重可以看做是1;ki=∑jAij表示所有与节点i相连的边的权重之和(度数);ci表示节点i所属的社区;m=12∑ijAij表示所有边的权重之和(边的数目)。公式中Aij−kikj2m=Aij−kikj2m,节点j连接到任意一个节点的概率是kj2m,现在节点i有ki的度数,因此在随机情况下节点i与j的边为kikj2m.

算法步骤:

1)将图中的每个节点看成一个独立的社区,次数社区的数目与节点个数相同;

2)对每个节点i,依次尝试把节点i分配到其每个邻居节点所在的社区,计算分配前与分配后的模块度变化ΔQ,并记录ΔQ最大的那个邻居节点,如果maxΔQ>0,则把节点i分配ΔQ最大的那个邻居节点所在的社区,否则保持不变;

3)重复2),直到所有节点的所属社区不再变化;

4)对图进行压缩,将所有在同一个社区的节点压缩成一个新节点,社区内节点之间的边的权重转化为新节点的环的权重,社区间的边权重转化为新节点间的边权重;

5)重复1)直到整个图的模块度不再发生变化。

图:算法过程图

3.2社团划分实践

基于2.2权利的游戏的任务关系网络进行Louvain算法社团划分。算法源码参考2可以找到。这里就直接用了看下效果。

总共107个角色,划分了6个社团。

参考:

https://blog..net/wizard_wsq/article/details/50628009

https://www..com/fengfenggirl/p/louvain.html

https://www.quora.com/Is-there-a-simple-explanation-of-the-Louvain-Method-of-community-detectio

https://blog..net/xuanyuansen/article/details/68941507

https://www..com/allanspark/p/4197980.html

networkx 有向图强连通_基于networkx分析Louvain算法的社团网络划分相关推荐

  1. networkx 有向图强连通_有向图的强连通分支

    在有向图G中,如果任意两个不同的顶点相互可达,则称该有向图是强连通的.有向图G的极大强连通子图称为G的强连通分支. 把有向图分解为强连通分支是的一个经典应用实例.下面介绍如何使用两个深度优先搜索过程来 ...

  2. networkx 有向图强连通_有向图的强连通分量求法

    https://byvoid.com/zhs/blog/scc-tarjan/,这里讲的tarjan已经很好了. 对于一个图,说他是连通的当且仅当从该图的任何一个顶点到该图的另一个顶点都走得通,强连通 ...

  3. 【优化覆盖】基于matlab人工蜂群算法求解无线网络传感覆盖优化问题【含Matlab源码 1097期】

    ⛄一.人工蜂群算法求解无线网络传感覆盖优化问题简介 1 WSN覆盖模型 1.1 问题描述 在WSN中, 要实现较高的无线网络传感器节点覆盖率从而减少监测盲点的出现, 就必须加大无线网络传感器节点的分布 ...

  4. python爬小红书_基于文本分析和SEM模型的小红书用户粘性研究

    基于文本分析和 SEM 模型的小红书用户粘性研究 文/曹增栋 罗迪维 杨炳新 王心贝 [摘 要] 摘要:本文利用 Python 软件爬取小红书用户评论的 27900 条数据, 通过 jieba 分词提 ...

  5. 在envi做随机森林_基于模糊孤立森林算法的多维数据异常检测方法

    引用:李倩, 韩斌, 汪旭祥. 基于模糊孤立森林算法的多维数据异常检测方法[J]. 计算机与数字工程, 2020, 48(4): 862-866. 摘要:针对孤立森林算法在进行异常检测时,忽略了每一条 ...

  6. lms算法的verilog实现_基于FPGA和LMS算法的系统建模

    © 1994-2010 China Academic Journal Electronic Publishing House. All rights reserved.    http://www.c ...

  7. mser python车牌识别_基于MSER与SVM算法的车牌定位识别方法

    基于 MSER 与 SVM 算法的车牌定位识别方法 胡成伟 ; 袁明辉 [期刊名称] <软件> [年 ( 卷 ), 期] 2020(041)002 [摘要] 针对实际车牌识别系统中车牌位置 ...

  8. retrofit 会请求两次_基于RxJava2+Retrofit2简单易用的网络请求实现

    简介 基于RxJava2+Retrofit2实现简单易用的网络请求,结合android平台特性的网络封装库,采用api链式调用一点到底,集成cookie管理,多种缓存模式,极简https配置,上传下载 ...

  9. kcf算法流程_基于运动检测与KCF算法的目标跟踪方法

    基于运动检测与 KCF 算法的目标跟踪方法 易 诗,唐 文 [摘 要] 摘要:近年来机器视觉技术广泛采用于各个领域,本文设计实现了一 种基于运动检测与 KCF 算法的目标跟踪方法,该方法相对于传统单一 ...

  10. elm分类器功能_基于ELM的图像分类算法研究

    基于ELM的图像分类算法研究 摘要:近年来,机器人科技应用越来越广泛,其核心原理就是利用计算器对外界传感器得到的图像进行内容分析.在获得相应的信息后,对数字化后的有用信息进行处理.根据处理结果,作出决 ...

最新文章

  1. php 创建文件编码,php fopen创建utf8编码文件例子
  2. zcmu-1643 报数游戏
  3. 字节流读数据(一次读一个字节数据)
  4. CCS的一些问题(转帖)
  5. (转)基于MVC4+EasyUI的Web开发框架形成之旅--MVC控制器的设计
  6. C++ 一定要使用strcpy_s()函数 等来操作方法c_str()返回的指针
  7. C语言:从键盘中输入字符串,追加填写到指定文件中
  8. Android Media Playback 中的MediaPlayer的用法及注意事项(一)
  9. Erlang进程堆垃圾回收机制
  10. opencv-python版本问题
  11. 【Java基础笔记】ASCll码表
  12. 技巧 | 如何设计实用易读的图表(毕设用by wys)
  13. 微信小程序设置底部导航栏
  14. wps序号打乱重新排序_wps表格序号自动排列
  15. python 实现大鱼吃小鱼小游戏(课程作业)
  16. 微信公众号开发--公众号关注推送配置与菜单配置
  17. 逊哥dp专题 总结(普通dp,斜率优化dp,数位dp)
  18. 关于Pycharm主题Darcula下使用jupyter显示图片的颜色错误
  19. 使用WHM重新编译Apache+PHP环境
  20. GetTickCount 得到时间进行比较计算遇到的异常

热门文章

  1. matlab求出拟合曲线的方程,已知数据点,拟合曲线并得到曲线方程。谢谢
  2. Speed/accuracy trade-offs for modern convolutional object detectors
  3. Flutter 长截屏适配 Miui 系统,一点都不难
  4. 【数学建模】评价类算法
  5. jeDate日期控件 时间最大值最小值禁用的bug修改
  6. 复变函数 —— 4. 什么是调和函数
  7. 大数据技能练习之爬虫
  8. ndk编译libiconv
  9. ios 热更新可行性分析
  10. 合并排序时间复杂度推导