(3-3)networkx之绘制复杂图

networkx 画图参数:

  • node_size: 指定节点的尺寸大小(默认是300,单位未知
  • node_color: 指定节点的颜色 (默认是红色,可以用字符串简单标识颜色,例如’r’为红色,'b’为绿色等,具体可查看手册),用“数据字典”赋值的时候必须对字典取值(.values())后再赋值
  • node_shape: 节点的形状(默认是圆形,用字符串’o’标识,具体可查看手册)
  • alpha: 透明度 (默认是1.0,不透明,0为完全透明)
  • width: 边的宽度 (默认为1.0)
  • edge_color: 边的颜色(默认为黑色)
  • style: 边的样式(默认为实现,可选: solid|dashed|dotted,dashdot)(实线|虚线|点线,dashdot)
  • with_labels: 节点是否带标签(默认为True)
  • font_size: 节点标签字体大小 (默认为12)
  • font_color: 节点标签字体颜色(默认为黑色)
  • nodelist:只绘制指定的nodelistl里的节点(默认G.nodes())
  • edgelist:只绘制指定的edgelistl里的边(默认= G.edges())
  • arrows:bool,optional(default = True) 对于有向图,如果为真,则绘制箭头。
  • pos:dictionary 将节点作为键和位置作为值的字典。 位置应该是长度为2的序列。
  • ax:Matplotlib Axes对象,可选 在指定的Matplotlib轴中绘制图形。

networkx 提供的布局方式有:
layout=[
nx.layout.circular_layout:节点在一个圆环上均匀分布
nx.layout.spring_layout: 用Fruchterman-Reingold算法排列节点
nx.layout.random_layout:节点随机分布
nx.layout.shell_layout:节点在同心圆上分布
nx.layout.spectral_layout:根据图的拉普拉斯特征向量排列节
nx.layout.fruchterman_reingold_layout
nx.layout.kamada_kawai_layout
]
在这里插入图片描述
在这里插入图片描述

import networkx as nx             #导入networkx包
import matplotlib.pyplot as plt 
G = nx.random_graphs.barabasi_albert_graph(50,1)   #生成一个BA无标度网络G
pos=nx.layout.circular_layout(G)#节点在一个圆环上均匀分布
print(pos) #pos:dictionary 将节点作为键和位置作为值的字典。 位置应该是长度为2的序列。
nx.draw(G,pos=pos,node_size=20)

在这里插入图片描述
在这里插入图片描述

import networkx as nx
import matplotlib.pyplot as plt
g=nx.karate_club_graph()
nx.draw(g)
fig,ax=plt.subplots(figsize=(8,6))
pos=nx.layout.spring_layout(g) #布局
NodeId=list(g.nodes())
node_size=[g.degree(i)**1.2*90 for i in NodeId]
options={
    'node_size':node_size,
    'lone_color':'grey',
    'linewidths':0.1,
    'width':0.4,
    'style':'solid',
    'nodelist':NodeId,
    'node_color':node_size,
    'font_color':'w'    
    }
    #颜色和大小都是根据该节点的度的大小来的
nx.draw(g,pos=pos,ax=ax,with_labels=True,**options)

在这里插入图片描述




从现在开始,
以下内容因为比较复杂,所以每个正规代码前都有些琐碎的知识点作为铺垫

一、最短距离用坐标分布图表示出来

先来补充些基础知识:

1.if-else的简写

1.通常写法

b=4
if b>4:
    print('对了')
else:
    print('错了')
 
   
2.简写

'对了' if b>4 else '错了'

2.for in循环的简写

q=[(a,b) for a in range(10) for b in range(10) if a>0 and a%2==0 and b%2==0]

这条语句的阅读顺序是 for a in range(10) --> for b in range(10) -->if a>0 and a%2==0 and b%2==0 -->(a,b)
也就是说for inif else组合在一起时就是从前往后读
q=[(a,b) for a in range(10) for b in range(10) if a>0 and a%2==0 and b%2==0]

print(q)
# [(2, 0), (2, 2), (2, 4), (2, 6), (2, 8), (4, 0), (4, 2), (4, 4), (4, 6), (4, 8), (6, 0), (6, 2), (6, 4), (6, 6), (6, 8), (8, 0), (8, 2), (8, 4), (8, 6), (8, 8)]
q=[(a+b) for a in range(10) for b in range(10) if a>0 and a%2==0 and b%2==0]

print(q)
# [2, 4, 6, 8, 10, 4, 6, 8, 10, 12, 6, 8, 10, 12, 14, 8, 10, 12, 14, 16]

3.reshape(-1)

import numpy as np
c=np.array([[1,2,3],[4,5,6]])
print('两行三列')
print(c.reshape(2,3))
[[1 2 3]
 [4 5 6]]

print('三行两列')
print(c.reshape(3,2))
[[1 2]
 [3 4]
 [5 6]]

print('我也不知道是几行,反正就是1列')
print(c.reshape(-1,1))
[[1]
 [2]
 [3]
 [4]
 [5]
 [6]]

print('我也不知道是几列,反正就是1行')
print(c.reshape(1,-1))
[[1 2 3 4 5 6]]

print('不分行列,就是一串数字')
print(c.reshape(-1))
[1 2 3 4 5 6]
z = np.array([[1, 2, 3, 4],  [5, 6, 7,8],  [9, 10, 11, 12],  [13, 14, 15, 16]])
print(z.reshape(-1)) 
输出:[ 1 2  3  4  5  6  7  8  9 10 11 12 13 14 15 16] 

4.关于np.array()

import networkx as nx
import numpy as np
G=nx.graph_atlas(100)

aa=[[nx.shortest_path_length(G,i,j) for j in G if i != j]for i in G]
bb=np.array([[nx.shortest_path_length(G,i,j) for j in G if i != j]for i in G])
cc=np.array([[nx.shortest_path_length(G,i,j) for j in G if i != j]for i in G]).reshape(-1)
dd=[nx.shortest_path_length(G,i,j) for i in G for j in G  if i != j]
print(aa)
print(bb)
print(cc)
print(dd)

cc和dd虽然有逗号上的区别,但事实上在用法上这两个没有丝毫的差别(日后求纠正)

在这里插入图片描述
5.绘制网络任意两点之间最短距离的分布图

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
G=nx.graph_atlas(100) #得到一幅网络图
dd=np.array([[nx.shortest_path_length(G,i,j) for j in G if i != j]for i in G]).reshape(-1) #求得任意两点之间的最短距离
bins=np.arange(-0.5,max(dd)+1.5,1.0) #根据最短距离里的最大值确定横坐标的取值范围
plt.hist(dd,bins=bins)

'''
bin=np.arange(0,60,2)得到[0,2,4,6,8...52,54,56,58]不包括60
所以bins=np.arange(-0.5,max(dd)+1.5,1.0)中是max(dd)+1.5而不是max(dd)+0.5
bins=np.arange(-0.5,max(dd)+1.5,1.0)得到[-0.5,0.5,1.5,2.5,3.5]
'''

在这里插入图片描述
6.关于plt.hist里的bins

bins:整数值或序列。如果bins为整数值,则bins为柱子个数,根据数据的取值范围和柱子个数bins计算每个柱子的范围值,柱宽=(x.max()-x.min())/bins。例:数据取值为[1,2,3,4,5,6],bins=6,柱宽=0.8333…,则每个柱子的范围分别为:[1,1.83),
[1.83,2.66)…,[5.17,6]
如果bins取值为序列,则该序列给出每个柱子的范围值(即边缘)。除最后一个柱子外,其他柱子的取值范围均为半开(左闭右开)。如:在一个数据共n=6个取值的情况下,若bins=range(1,n+2)即bins的取值为[1,2,3,4,5,6,7]。则每个柱子的范围为:[1,2),[2,3),…,[5,6),[6,7]。
在这里插入图片描述

在这里插入图片描述

8.回忆一下散点图的绘制
在这里插入图片描述
在这里插入图片描述

9.以下才是真正的核心内容

在这里插入图片描述




二、集聚系数坐标分布图

1.运用到了字典和列表的转换的知识,请看“字典与列表”专栏
在这里插入图片描述
2.hist也好scatter也罢,肚子里的东西都是列表: hist([列表],bins=5) , scatter([列表1],[列表2])
反正hist和scatter肚子里的列表更多的是喜欢[degree[i] for i in list(degree.keys())]这种复杂的形式出现,而不是简简单单的[1,2,3,4,5,6]

import matplotlib.pyplot as plt
cluster={0:0.15,1:0.33,2:0.24,3:0.66,4:0.66,5:0.5,6:0.5,7:1.0,8:0.5} #8个节点的集聚系数
degree={0:2,1:1,2:4,3:5,4:2,5:1,6:4,7:2,8:3}  #8个节点的度
plt.subplot(121)
plt.hist(list(cluster.values()),bins=5)
plt.subplot(122)
plt.scatter([degree[i] for i in list(degree.keys())],[cluster[i] for i in list(cluster.keys())]) #度与集聚系数的关系
'''你千万要熟练这种[degree[i] for i in list(degree.keys())]用法'''

在这里插入图片描述
在这里插入图片描述




三、ER随即网络坐标分布图

1.简单的绘制ER度分布图

import networkx as nx
G = nx.graph_atlas(100)
print(G.degree()) #[(0, 3), (1, 1), (2, 1), (3, 3), (4, 2), (5, 2)]
print(dict(G.degree())) #{0: 3, 1: 1, 2: 1, 3: 3, 4: 2, 5: 2}

我们要尝试输出G.degree()看看他是什么类型,然后再根据字典或者列表的特点互相转换
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt

##产生ER随即网络图
g=nx.erdos_renyi_graph(1000, 0.006,directed=False) 

degree=dict(nx.degree(g)) #度分布{0: 10, 1: 5, 2: 2, 3: 8,,,,997: 3, 998: 7, 999: 3}
degree=list(degree.values())  #[10,5,2,8,,,,3,7,3]
average_degree=np.mean(degree) #6.144
max_degree=max(degree) #16
print(max_degree)

bins=np.arange(-0.5,max(degree)+1.5,1.0)
plt.hist(degree,bins=bins,normed=1,facecolor='green',alpha=0.5)
plt.xlabel('degree')
plt.title('degree distribution')

在这里插入图片描述
2.绘制泊松分布
在这里插入图片描述
hist([列表1],[列表2]),scatter([列表1],[列表2])里面的列表可能是range(15)也可能是[degree[i] for i in list(degree.keys())],你必须熟悉这些用法

import scipy.stats
import matplotlib.pyplot as plt
k=0.5
print([scipy.stats.poisson.pmf(xi,k) for xi in range(15)])#泊松分布
plt.plot(range(15),[scipy.stats.poisson.pmf(xi,k) for xi in range(15)],'ro-')

在这里插入图片描述
在这里插入图片描述
3.以下才是真正的核心内容

import scipy.stats
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt

N=1000
krange=[0.5,1.0,2.0,np.log(N)] 
#设置4个平均度<k>来绘制ER图;在ER网络图中给出了平均度即可求p,p=<k>/(N-1)
#np.log(N)=6.90

for i in range(4):
    
    k=krange[i]
    p=1.0*k/(N-1) #求得ER图的p
    
    deg=[]
    for j in range(100):
        g=nx.erdos_renyi_graph(N,p,directed=False)
        deg+=dict(nx.degree(g)).values()
    #对于每个p我们都绘制100幅ER图,并把他们的度存储在deg里面

    plt.subplot(2,2,i+1)
    bins=np.arange(-0.5,max(deg)+0.5,1.0)
    plt.hist(deg,bins=bins,normed=1,facecolor='green',alpha=0.5)
    plt.plot(range(15),[scipy.stats.poisson.pmf(xi,k) for xi in range(15)],'ro-')
    plt.xlim(-1,15)
    plt.title('<k>=%s'%k)

在这里插入图片描述




四、ER网络的连通集团分布图

1.先补充些基础知识

import numpy as np

krange=np.arange(0.2,2*np.log(100),0.2)
print(krange)

print(np.log(100))#默认以e为底数
print(np.log10(100))

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.以下才是真正的核心内容

在这里插入图片描述




五、小世界网络及其特征统计量

在这里插入图片描述
在这里插入图片描述
(下面的计算用到了这些代码)
我们通过取不同的p来得到不同的p对应的网络的集聚系数和最短距离
我们发现在圈主的地方具有“高集聚系数,低平均距离”的小世界特性

在这里插入图片描述
根据上面得到的prange,drange,crange就可以绘图了

plt.plot(prange,drange) #可以看最短距离随着p的变化情况
plt.plot(prange,crange) #可以看平均集聚系数随着p的变化

ratio=[crange[i]/drange[i] for i in range(len(crange))] #ratio是集聚系数和距离的比值
plt.plot(prange,ratio) #就可以看c/d随着p的变化情况

还需要对横纵坐标处理一下就可以得到下图:
在这里插入图片描述
完整代码如下:(这个太麻烦,仅供了解了)
在这里插入图片描述




六、.如何统计100幅图片的平均值

①如何统计100幅随即网络的平均度、平均集聚系数、平均最短距离、平均最大联通集团

N=100
pro=[0.2,0.4,0.6,0.8,1.0,1.2,1.4,1.6]

Avg_deg=[]
Avg_cls=[]
Avg_spl=[]
Avg_gcc=[]

for p in pro:
    avg_deg=[]
    avg_cls=[]
    avg_spl=[]
    avg_gcc=[]
    
    for _ in range(100):
        g=nx.erdos_renyi_graph(N,p,directed=False) #根据每一个p与N绘制一个随即网络图
        
        avg_deg.append(np.mean(nx.degree(g).values()))
        avg_cls.append(nx.average_clustering(g))
        avg_gcc.append( max([len(x) for x in nx.connected_components(g)] )
        avg_spl.append(nx.average_shorteest_path_length(g))
        
    Avg_deg.append(np.mean(avg_deg))
    Avg_cls.append(np.mean(avg_cls))
    Avg_spl.append(np.mean(avg_spl))
    Avg_gcc.append(np.mean(avg_gcc))

'''avg_deg里面存放着100个随即网络图的平均度
   avg_cls里面存放着100个随即网络图的平均集聚系数
   avg_gcc里面存放着100个随即网络图的最大连通集团
   avg_spl里面存放着100个随即网络图的平均最短距离
'''


在这里插入图片描述

③如何统计100次实验的平均数据
已知我们有一个函数,suspect_infect_recovery(g, sources, beta, gamma),g是一个网络,sources是一个列表涵盖了这个网络最先得了传染病的那个节点,beta=0.3是感染概率,gamma=1是恢复概率;这个函数可以返回一个state,state里面记录了本次传染病盛行后各个节点得状态是“I”还是“R”还是“S”(I是感染,R是感染后恢复,S是未感染)

g=nx.karate_club_graph() #空手道俱乐部

res=[[] for i in g] #res事实上就是[[], [], [], [], []...]
for _ in range(100): #让g中的每一个节点都循环100次得到较为客观的值
    for i in g:
        state=suspect_infect_recovery(g, [i], 0.3, 1)#让g中的每一个节点都做一次sources(第一个被感染的人)
        s=sum([1 for i in state if state[i] !="S"])#统计共有多少人受到了感染
        res[i].append(s)  #res[i]就是列表中的列表,它当然可以调用列表的方法
#此时的res就是[[24, 16, 5, 24, 24..],[21, 8, 25, 15, 7..]...]
impact=[sum(r)/len(r) for r in res] #让g中的每一个节点都循环100次再做平均得到一个客观的值
#impact就是[18.02, 15.69, 17.07, 14.68...]的样子
Impact_sort=sorted([(i,impact[i]) for i in range(len(impact))],key=lambda x:x[1],reverse=True)
for i in Impact_sort:
    print(i)

在这里插入图片描述

七、无标度网络的相关分析

1.set()函数
在这里插入图片描述
2.bipartite.projected_graph(B, nodes=)
g=bipartite.projected_graph(B, nodes=)。以1-N 3-N为例,1和3有共同的邻居,经过二分图的投影1-3相连。g=bipartite.projected_graph(B, nodes=)也就是提取B和nodes里面有共同邻居的那些节点组成连边

from networkx import nx
from networkx.algorithms import bipartite
M=nx.Graph()
M.add_edges_from([(0,'A'),(1,'N'),(3,'N'),(4,'P'),(5,'B')])
#1-N 3-N所以1和3有共同的邻居,经过二分图的投影1-3相连
G = bipartite.projected_graph(M, [0,1,3,4,5])
print(list(G))
print(list(G.edges()))

在这里插入图片描述
3.plt.loglog是双对数坐标,不做强制了解

import matplotlib.pyplot as plt
x = [2**i for i in range(4,14)]
y = [i**2 for i in x]

plt.loglog(x,y,'ro',basex=2,basey=2)
plt.show()

在这里插入图片描述
4.抛砖引玉

 from networkx import nx
from networkx.algorithms import bipartite
import matplotlib.pyplot as plt

M=nx.Graph()
M.add_edges_from([(0,'A'),(1,'N'),(3,'N'),(4,'P'),(5,'B'),(6,'C'),(7,"N"),(8,'B')])
#以1-N 3-N为例,1和3有共同的邻居,经过二分图的投影1-3相连

G = bipartite.projected_graph(M, [0,1,3,4,5,6,7,8])
deg_dist=nx.degree_histogram(G)
plt.loglog(range(0,len(deg_dist)),deg_dist)
#事实上,对于plt.loglog是不需要任何参数的,plt.loglog(x,y,'o')就可以了,默认以10为底
print(list(G))
print(list(G.edges()))
print(nx.degree(G))#统计出每个节点的度
print(deg_dist)#[3,2,3]知度为0的有三个,度为1的有2个,度为2的有三个

在这里插入图片描述
在这里插入图片描述
5.以下才是真正的核心内容

对下面代码的注解:
mec设置标记边缘颜色 在这里插入图片描述

在这里插入图片描述




八、社团划分

①本节内容

from networkx import nx
import random

N=128#网络规模
C=4#社团数量
zin=14#社团内连边数
zout=2#社团外连边数
n=int(N/C)#每个社团的节点数为32

nodes=[]
nall=[]
for a in ['a','b','c','d']:
    xx=[]
    for i in range(n):
        xx.append(a+str(i))
    nodes+=xx
    nall.append(xx)
#nodes为['a0','a1'...'b0','b1'...'c0','c1'...'d0','d1'...]
#nall为[['a0','a1'...],['b0','b1'...],['c0','c1'...],['d0','d1'...]]
pin=1.0*zin/(n-1)/2 #以pin的概率产生社团内连边   
pout=1.0*zout/(3*n-1)/2 #以pout的概率产生社团外连边  

g=nx.Graph()

for nc in nall:
    for i in nc:
        for j in nc:#社团内连边
            if i==j:
                continue
            p=random.random()
            if p<pin:
                g.add_edge(i,j)
        for j in set(nodes)-set(nc):#社团外连边
            p=random.random()
            if p<pout:
                g.add_edge(i,j)
                
pos=nx.layout.spring_layout(g)
nx.draw(g,pos,node_size=200)   

在这里插入图片描述
你只需要修改最后两条代码为:

state={i:'0' for i in g} #我们先给网络g里面的节点设置一个state属性,并且这些节点的state属性都是一个初始值'0'
for nc in nall:
    for i in nc:
        state[i]=i[0] #a社团的的state就是'a';b社团的state就是'b'
colors={'a':'blue','b':'yellow','c':'red','d':'green'}
color=[colors[state[u]] for u in g] #不同的属性赋予不同的颜色

pos=nx.layout.spring_layout(g)
nx.draw(g,pos=pos,node_color=color,node_size=200,alpha=0.9,edgecolors='k') 

就可以绘出四种社团颜色的代码:
在这里插入图片描述
②本节内容摘抄的思想
在这里插入图片描述
上幅图给了a、b、c、d四个社团,每个社团有32个节点,请你给我统计出两个列表,
一个是[‘a0’,‘a1’…‘b0’,‘b1’…‘c0’,‘c1’…‘d0’,‘d1’…],另一个是[[‘a0’,‘a1’…],[‘b0’,‘b1’…],[‘c0’,‘c1’…],[‘d0’,‘d1’…]]

nodes=[]
nall=[]
for a in ['a','b','c','d']:
    xx=[]
    for i in range(32):
        xx.append(a+str(i))
    nodes+=xx
    nall.append(xx)
    
#nodes为['a0','a1'...'b0','b1'...'c0','c1'...'d0','d1'...]
#nall为[['a0','a1'...],['b0','b1'...],['c0','c1'...],['d0','d1'...]]

如何根据不同的社团绘制不同的颜色?

state={i:'0' for i in g} #我们先给网络g里面的节点设置一个state属性,并且一开始所有节点的state属性都是一个初始值'0'
for nc in nall:
    for i in nc:
        state[i]=i[0] #a社团的的state就是'a';b社团的state就是'b'
colors={'a':'blue','b':'yellow','c':'red','d':'green'}
color=[colors[state[u]] for u in g] #不同的属性赋予不同的颜色

pos=nx.layout.spring_layout(g)
nx.draw(g,pos=pos,node_color=color,node_size=200,alpha=0.9,edgecolors='k') 

就可以绘出四种社团颜色的代码:
在这里插入图片描述




九、疾病传播动力学

在这里插入图片描述

import random
from networkx import nx

def suspect_infect_recovery(G,sources,beta,gamma):
    state={i:'S' for i in G}#G中每个节点都设置为未感染
    for s in sources:
        state[s]='I' #sources里面的设置为感染节点
    flag=False #flag何时为True呢?当没有感染结点的时候
    
    while True:  #(while True:就是永远循环下去)
        flag=True
        state_temp=state.copy() #复制字典state给state_temp
        for i in G:
            if state[i]=="S":
                nbs=sum([1 for j in G.neighbors(i) if state[j] =="I"]) #当i是未感染时,那就统计他有多少个感染的邻居
                if nbs==0:
                    continue
                if random.random()<(1-(1-beta)**nbs):#(1-beta)的nbs次方就是i节点在有nbs个邻居感染的情况下仍然未感染概率
                    state_temp[i]="I"
            elif state[i]=="I":
                flag=False #flag如果为False就是还存在感染节点的意思,此时仍不能跳出循环
                if random.random()<gamma:
                    state_temp[i]="R"
            #也就是说每循环一遍就有未感染的因为邻居而有可能受到感染,也有感染的变成未感染的
        state=state_temp.copy()
        if flag: 
            break  #也就是当flag为True时就是跳出循环了
    return state

beta=0.3#感染概率
gamma=1#恢复概率
g=nx.karate_club_graph() #空手道俱乐部
state=suspect_infect_recovery(g,[1],beta,gamma)
print("各个节点的状态:",state)
print("总感染数:",sum([1 for i in state if state[i] !='S']))                 

pos=nx.layout.spring_layout(g)
colors={"R":'b',"I":'r',"S":'g'}
color=[colors[state[u]] for u in g]#根据节点的status给它相应的颜色
nx.draw(g,pos=pos,node_color=color,with_labels=True,node_size=300)  

在这里插入图片描述
在这里插入图片描述

(代码解说在这幅图下面)
在这里插入图片描述

import random
from networkx import nx

def suspect_infect_recovery(G,sources,beta,gamma):
    state={i:'S' for i in G}#G中每个节点都设置为未感染
    for s in sources:
        state[s]='I' #sources里面的设置为感染节点
    flag=False #flag何时为True呢?当没有感染结点的时候
    
    while True:  #(while True:就是永远循环下去)
        flag=True
        state_temp=state.copy() #复制字典state给state_temp
        for i in G:
            if state[i]=="S":
                nbs=sum([1 for j in G.neighbors(i) if state[j] =="I"]) #当i是未感染时,那就统计他有多少个感染的邻居
                if nbs==0:
                    continue
                if random.random()<(1-(1-beta)**nbs):#(1-beta)的nbs次方就是i节点在有nbs个邻居感染的情况下仍然未感染概率
                    state_temp[i]="I"
            elif state[i]=="I":
                flag=False #flag如果为False就是还存在感染节点的意思,此时仍不能跳出循环
                if random.random()<gamma:
                    state_temp[i]="R"
            #也就是说每循环一遍就有未感染的因为邻居而有可能受到感染,也有感染的变成未感染的
        state=state_temp.copy()
        if flag: 
            break  #也就是当flag为True时就是跳出循环了
    return state

beta=0.3#感染概率
gamma=1#恢复概率
g=nx.karate_club_graph() #空手道俱乐部
pos=nx.layout.spring_layout(g)
res=[[] for i in g] #res事实上就是[[], [], [], [], []...]
for _ in range(100): #让g中的每一个节点都循环100次得到较为客观的值
    for i in g:
        state=suspect_infect_recovery(g, [i], beta, gamma)#让g中的每一个节点都做一次sources(第一个被感染的人)
        s=sum([1 for i in state if state[i] !="S"])#统计共有多少人受到了感染
        res[i].append(s)
#此时的res就是[[24, 16, 5, 24, 24..],[21, 8, 25, 15, 7..]...]
impact=[sum(r)/len(r) for r in res] #让g中的每一个节点都循环100次再做平均得到一个客观的值
#impact就是[18.02, 15.69, 17.07, 14.68...]的样子
nx.draw(g,pos=pos,node_color=impact,with_labels=True,node_size=300)
Impact_sort=sorted([(i,impact[i]) for i in range(len(impact))],key=lambda x:x[1],reverse=True)
for i in Impact_sort:
    print(i)

在这里插入图片描述
在这里插入图片描述




十、PageRank

简单来讲:

import networkx as nx
G = nx.graph_atlas(100)
pageRank_list = nx.pagerank(G)
print("pageRank值是:", pageRank_list)

计算得到了每个点的PR值
在这里插入图片描述

具体来讲
在这里插入图片描述

# -*- coding: utf-8 -*-
import networkx as nx

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

edges = [("A", "B"), ("A", "C"), ("A", "D"), ("B", "A"), ("B", "D"), ("C", "A"), ("D", "B"), ("D", "C")]
# 有向图之间的边的关系

for edge in edges:
    G.add_edge(edge[0], edge[1])
#或者G.add_edges_from(edges)

pageRank_list = nx.pagerank(G, alpha=1)
print("pageRank值是:", pageRank_list)

得到的结果如下:

pageRank值是: {'A': 0.33333396911621094, 'B': 0.22222201029459634, 'C': 0.22222201029459634, 'D': 0.22222201029459634}

(0.3333,0.2222,0.2222,0.2222)也就是对应着 A、B、C、D 四个页面最终平衡状态下的影响力。你能看出 A 页面相比于其他页面来说权重更大,也就是 PR 值更高。而 B、C、D 页面的 PR 值相等。

Ex:
已知一个网络矩阵如下,利用PageRank算法,请计算这个网络每个节点的pr值,并根据pr值的大小控制节点大小绘制网络图
在这里插入图片描述

import networkx as nx
import matplotlib.pyplot as plt
from networkx.algorithms.link_analysis import pagerank

G = nx.Graph()

with open( 'Karate_club.txt', 'r' )as file: ##5,10
    lines = file. readlines( )
for i in range( len(lines)):
    lines[i] = lines[i].strip('\n').split(' ')
    for j in range(len( lines[i])):
        if lines[i][j] == '1':

            G.add_edge(i + 1, j + 1)


pr=nx.pagerank(G)
print(pr)
layout = nx.spring_layout(G)
nx.draw(G, pos=layout, node_size=[i * 6000 for i in pr.values()],node_color='g',with_labels=True)
plt.show()

在这里插入图片描述
在这里插入图片描述

  • 11
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你的甲乙丙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值