无线传感器网络:LEACH路由协议优化python仿真代码
目录
- 仿真结果
- python代码
- 代码文件
实验采用 python 模拟运行对改进后的算法IMP_LEACH ,同时将仿真结果与经典LEACH 算法进行比较。实验中用到的参数与 参考文章相同。
仿真结果
生成基站以及随机生成400个WSN节点
存活节点数量比较、剩余能量比较:
死亡节点比例比较
死亡节点比例比较
python代码
import numpy as np
import matplotlib.pyplot as plt
import random# 解决中文显示问题
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = Falseclass BaseStation: # 定义基站类x=0y=0class SensorNode: # 定义传感器节点xd=0yd=0d=0Rc = 0temp_rand=0type = 'N'selected = 'N'power = 0CH = 0flag = 1N = []Num_N = 0FN = []Num_FN = 0CN = []Num_CN = 0num_join = 0# 初始化参数
xm = 100 # x轴范围
ym = 100 # y轴范围
sink = BaseStation()
sink.x = 50 # 基站x轴
sink.y = 125 # 基站y轴
n = 400 # 节点总数
p = 0.08 # 簇头概率
Eelec = 50*(10**(-9))
Efs=10*(10**(-12))
Emp=0.0013*(10**(-12))
ED=5*(10**(-9))
d0 = 87
packetLength = 4000
ctrPacketLength = 100
rmax = 2000 # 迭代次数
E0 = 0.5 # 初始能量
Emin = 0.001 # 节点存活所需的最小能量
Rmax = 15 # 初始通信距离## 节点随机分布
fig1 = plt.figure(dpi=80)
plt.grid(linestyle="dotted")
Node = []
plt.scatter(sink.x, sink.y,marker='*',s=200)
for i in range(n):node = SensorNode()node.xd = random.random()*xmnode.yd = random.random()*ym # 随机产生100个点node.d = ((node.xd-sink.x)**2+(node.yd-sink.y)**2)**0.5 # 节点距基站的距离node.Rc = Rmax # 节点的通信距离node.temp_rand = random.random() # rand为(0,1)的随机数node.type = 'N' # 进行选举簇头前先将所有节点设为普通节点node.selected = 'N' # ’O':当选过簇头,N:没有node.power = E0 # 初始能量node.CH = 0 # 保存普通节点的簇头节点,-1代表自己是簇头node.flag = 1 # 1代表存活;0代表死亡node.N = [0 for _ in range(n) ] # 邻居节点集node.Num_N = 0 # 邻居节点集个数node.FN = [0 for _ in range(n)] # 前邻节点集node.Num_FN = 0 # 前邻节点集个数node.CN = [0 for _ in range(n)] # 前簇头节点集node.Num_CN = 0 # 前簇头节点集个数Node.append(node)plt.scatter(node.xd, node.yd,marker='o')
plt.legend(['基站', '节点'])
plt.xlabel('x', fontdict={"family": "Times New Roman", "size": 15})
plt.ylabel('y', fontdict={"family": "Times New Roman", "size": 15})# save data
flag = 1
################IMP_LEACH##################
# 迭代
alive_ima_leach = np.zeros((rmax, 1)) # 每轮存活节点数
re_ima_leach = np.zeros((rmax, 1)) # 每轮节点总能量
for r in range(rmax):final_CH=[]for i in range(n):if Node[i].flag != 0:re_ima_leach[r] = re_ima_leach[r]+Node[i].power # 更新总能量alive_ima_leach[r] = alive_ima_leach[r]+1 # 更新存活节点f = 0if alive_ima_leach[r] == 0:stop = rf = 1breakfor i in range(n):Node[i].type = 'N' # 进行选举簇头前先将所有节点设为普通节点Node[i].selected = 'N'Node[i].temp_rand = random.random() # 节点取一个(0,1)的随机值,与p比较Node[i].Rc = Rmax*Node[i].power/E0 # 节点的通信距离Node[i].CH = 0Node[i].N = np.zeros(n) # 邻居节点集Node[i].Num_N = 0 # 邻居节点集个数Node[i].FN = np.zeros(n) # 前邻节点集Node[i].Num_FN = 0 # 前邻节点集个数Node[i].CN = np.zeros(n) # 前簇头节点集Node[i].Num_CN = 0 # 前簇头节点集个数Node[i].num_join = 1 # 簇成员的个数# 簇头选举count = 0 # 簇头个数for i in range(n):if Node[i].selected == 'N' and Node[i].flag != 0:if Node[i].d > d0:alpha = 4 # 能量损失指数else:alpha = 2Eavg = 0 # 系统节点平均能量m = 0 # 存活节点个数for j in range(n):if Node[i].flag != 0:Eavg = Eavg + Node[i].powerm = m + 1if m != 0:Eavg = Eavg / n # 计算系统节点平均能量else:breakif Node[i].temp_rand <= (p / (1 - p * (r % round(1 / p)) * (Node[i].power / Eavg) ** (1 / alpha))) and \Node[i].d > Node[i].Rc:Node[i].type = 'C' # 节点类型为簇头Node[i].selected = 'O' # 该节点标记'O',说明当选过簇头Node[i].CH = -1count = count + 1final_CH.append(i) # 加入簇头节点集合# 广播自成为簇头distanceBroad = (Node[i].Rc ** 2 + Node[i].Rc ** 2) ** 0.5if (distanceBroad > d0):Node[i].power = Node[i].power - (Eelec * ctrPacketLength + Emp * ctrPacketLength * (distanceBroad ** 4))else:Node[i].power = Node[i].power - (Eelec * ctrPacketLength + Efs * ctrPacketLength * distanceBroad ** 2)else:Node[i].type = 'N' # 节点类型为普通# 计算邻居节点集合for i in range(n):cnt = 0for j in range(n):if i != j:dist = ((Node[i].xd-Node[j].xd)**2+(Node[i].yd-Node[j].yd)**2)**0.5if dist < Node[i].Rc:cnt = cnt + 1Node[i].N[cnt] = j# if len(Node[i].N)<cnt:# Node[i].N.append(j)# else:# Node[i].N[cnt-1] = jif j == n:Node[i].Num_N = cnt# 计算前邻节点集for i in range(n):cnt = 0for j in range(Node[i].Num_N):ne = Node[i].N[j]if Node[ne].d < Node[i].d:cnt = cnt + 1Node[i].FN[cnt] = neif j == Node[i].Num_N:Node[i].Num_FN = cnt# 计算前簇头节点集for i in range(count):cnt = 0for j in range(Node[i].Num_FN):fne = Node[final_CH[i]].FN[j]if fne != 0 and Node[fne].d < Node[final_CH[i]].d and Node[fne].CH == -1:cnt = cnt + 1Node[final_CH[i]].CN[cnt] = fneif j == Node[i].Num_FN:Node[final_CH[i]].Num_CN = cnt# 加入簇for i in range(n):if Node[i].type == 'N' and Node[i].power > 0:E = np.zeros(count)for j in range(count):dist = ((Node[i].xd-Node[final_CH[j]].xd)**2+(Node[i].yd-Node[final_CH[j]].yd)**2)**0.5if dist < Node[final_CH[j]].Rc: # 满足条件1E[j] = (Node[final_CH[j]].power-Emin)/Node[final_CH[j]].num_joinif len(E)>0:max_value, max_index = np.max(E),np.argmax(E)else:max_value, max_index = 0,0# 节点发送加入簇的消息if len(final_CH) != 0:dist = ((Node[i].xd - Node[final_CH[max_index]].xd) ** 2 + (Node[i].yd - Node[final_CH[max_index]].yd) ** 2) ** 0.5if dist > Node[final_CH[max_index]].Rc: # 不满足条件1,选择最近的簇头加入Length = np.zeros(count)for j in range(count):Length[j] = ((Node[i].xd - Node[final_CH[j]].xd) ** 2 + (Node[i].yd - Node[final_CH[j]].yd) ** 2) ** 0.5min_value, min_index = np.min(Length), np.argmin(Length)Node[i].CH = final_CH[min_index]# 节点发送加入簇的消息Node[i].power = Node[i].power - (Eelec * ctrPacketLength + Efs * ctrPacketLength * (dist ** 2))# 簇头接收消息Node[final_CH[min_index]].power = Node[final_CH[min_index]].power - Eelec * ctrPacketLengthNode[final_CH[min_index]].num_join = Node[final_CH[min_index]].num_join + 1else:# 节点发送加入簇的消息Node[i].power = Node[i].power - (Eelec * ctrPacketLength + Efs * ctrPacketLength * (dist ** 2))# 簇头接收消息Node[final_CH[max_index]].power = Node[final_CH[max_index]].power - Eelec * ctrPacketLengthNode[final_CH[max_index]].Rc = Rmax * Node[final_CH[max_index]].power / E0Node[i].CH = final_CH[max_index]Node[final_CH[max_index]].num_join = Node[final_CH[max_index]].num_join + 1# 能量模型# 发送数据for i in range(n):if Node[i].flag != 0:if Node[i].type == 'N' and Node[i].CH != 0: # 普通节点dist = ((Node[i].xd - Node[Node[i].CH].xd) ** 2 + (Node[i].yd - Node[Node[i].CH].yd) ** 2) ** 0.5if dist > d0:Node[i].power = Node[i].power - (Eelec * packetLength + Emp * packetLength * (dist ** 4))else:Node[i].power = Node[i].power - (Eelec * packetLength + Efs * packetLength * (dist ** 2))else: # 簇头节点Node[i].power = Node[i].power - (Eelec + ED) * packetLength # 簇头接收数据if Node[i].d <= Node[i].Rc:Node[i].power = Node[i].power - (Eelec * packetLength + Efs * packetLength * (Node[i].d ** 2))else:if Node[i].Num_CN == 0:if Node[i].d > d0:Node[i].power = Node[i].power - (Eelec * packetLength + Emp * packetLength * (Node[i].d ** 4))else:Node[i].power = Node[i].power - (Eelec * packetLength + Efs * packetLength * (Node[i].d ** 2))else:# 选择中继节点dis = np.zeros((Node[i].Num_CN, 1))# 计算前簇头节点距基站的距离for j in range(Node[i].Num_CN):dis[j] = Node[Node[i].CN[j]].dindex = np.argsort(dis)di = dis[index]# 中继转发for j in range(Node[i].Num_CN):Node[i].power = Node[i].power - di[j] / np.sum(di) * (Eelec * packetLength + Emp * packetLength * (di[Node[i].Num_CN + 1 - j] ** 2))for i in range(n):if Node[i].power < Emin:Node[i].flag = 0final_CH = []
if f == 0:stop = rmax# load data.mat 节点复位
for i in range(n):# Node[i].temp_rand = random.random() # rand为(0,1)的随机数Node[i].type = 'N' # 进行选举簇头前先将所有节点设为普通节点Node[i].selected = 'N' # ’O':当选过簇头,N:没有Node[i].power = E0 # 初始能量Node[i].CH = 0 # 保存普通节点的簇头节点,-1代表自己是簇头Node[i].flag = 1 # 1代表存活;0代表死亡Node[i].N = [0 for _ in range(n) ] # 邻居节点集Node[i].Num_N = 0 # 邻居节点集个数Node[i].FN = [0 for _ in range(n)] # 前邻节点集Node[i].Num_FN = 0 # 前邻节点集个数Node[i].CN = [0 for _ in range(n)] # 前簇头节点集Node[i].Num_CN = 0 # 前簇头节点集个数
################LEACH##################
alive_leach = np.zeros((rmax, 1)) # 每轮存活节点数
re_leach = np.zeros((rmax, 1)) # 每轮节点总能量
for r in range(rmax):for i in range(n):if Node[i].flag != 0:re_leach[r] = re_leach[r]+Node[i].poweralive_leach[r] = alive_leach[r]+1f = 0if alive_leach[r] == 0:stop = rf = 1breakfor i in range(n):Node[i].type = 'N' # 进行选举簇头前先将所有节点设为普通节点Node[i].selected = 'N'Node[i].temp_rand = random.random() #节点取一个(0,1)的随机值,与p比较for i in range(n):if Node[i].selected == 'N' and Node[i].flag != 0:# if Node[i].type=='N' #只对普通节点进行选举,即已经当选簇头的节点不进行再选举if Node[i].temp_rand <= (p/(1-p*(r%round(1/p)))): # 选取随机数小于等于阈值,则为簇头Node[i].type = 'C' # 节点类型为蔟头Node[i].selected = 'O' # 该节点标记'O',说明当选过簇头Node[i].CH = -1# 广播自成为簇头distanceBroad = (xm * xm + ym * ym) ** 0.5if distanceBroad > d0:Node[i].power = Node[i].power - (Eelec * ctrPacketLength + Emp * ctrPacketLength * (distanceBroad ** 4))else:Node[i].power = Node[i].power - (Eelec * ctrPacketLength + Efs * ctrPacketLength * (distanceBroad ** 2))else:Node[i].type = 'N' # 节点类型为普通# 判断最近的簇头结点,如何去判断,采用距离矩阵yy = np.zeros((n,n))Length = np.zeros((n,n))for i in range(n):if Node[i].type == 'N' and Node[i].flag != 0:for j in range(n):if Node[j].type == 'C' and Node[j].flag != 0: # 计算普通节点到簇头的距离Length[i, j] = ((Node[i].xd - Node[j].xd) ** 2 + (Node[i].yd - Node[j].yd) ** 2) ** 0.5else:Length[i, j] = float('inf')dist, index = np.min(Length[i, :]), np.argmin(Length[i, :]) # 找到距离簇头最近的簇成员节点# 加入这个簇if Length[i, index] < d0:Node[i].power = Node[i].power - (Eelec * ctrPacketLength + Efs * ctrPacketLength * (Length[i, index] ** 2))else:Node[i].power = Node[i].power - (Eelec * ctrPacketLength + Emp * ctrPacketLength * (Length[i, index] ** 4))Node[i].CH = index# 接收簇头发来的广播的消耗Node[i].power = Node[i].power - Eelec * ctrPacketLength# 对应簇头接收确认加入的消息Node[index].power = Node[index].power - Eelec * ctrPacketLengthyy[i, index] = 1else:Length[i, :] = float('inf')for i in range(n):if Node[i].flag != 0:if Node[i].type == 'C':number = np.sum(yy[:, i]) # 统计簇头节点i的成员数量# 簇头接收普通节点发来的数据Node[i].power = Node[i].power-(Eelec+ED)*packetLength# 簇头节点向基站发送数据len = ((Node[i].xd-sink.x)**2+(Node[i].yd-sink.y)**2)**0.5if len < d0:Node[i].power = Node[i].power-((Eelec+ED)*packetLength+Efs*packetLength*(len**2))else:Node[i].power = Node[i].power-((Eelec+ED)*packetLength+Emp*packetLength*len**4)else:# 普通节点向簇头发数据len = Length[i, Node[i].CH]if len < d0:Node[i].power = Node[i].power - (Eelec * packetLength + Efs * packetLength * len ** 2)else:Node[i].power = Node[i].power - (Eelec * packetLength + Emp * packetLength * len ** 4)for i in range(n):if Node[i].power < 0:Node[i].flag = 0
if f == 0:stop = rmax
## 绘图显示
fig4 = plt.figure(dpi=80)
plt.plot(range(rmax), alive_ima_leach, c='r',linewidth=2)
plt.plot(range(rmax), alive_leach, c='b', linewidth=2)
plt.legend(['IMP_LEACH', 'LEACH'])
plt.xlabel('轮数')
plt.ylabel('存活节点数')
fig5 = plt.figure(dpi=80)
plt.plot(range(rmax), re_ima_leach, c='r',linewidth=2)
plt.plot(range(rmax), re_leach, c='b', linewidth=2)
plt.legend(['IMP_LEACH', 'LEACH'])
plt.xlabel('轮数')
plt.ylabel('系统总能量')
fig6 = plt.figure(dpi=80)
for r in range(rmax):if alive_ima_leach[r] >= n:a1 = rif alive_leach[r] >= n:a2 = rif alive_ima_leach[r] >= (1-0.1)*n:b1 = rif alive_leach[r] >= (1-0.1)*n:b2 = rif alive_ima_leach[r] >= (1-0.2)*n:c1 = rif alive_leach[r] >= (1-0.2)*n:c2 = rif alive_ima_leach[r] >= (1-0.5)*n:d1 = rif alive_leach[r] >= (1-0.5)*n:d2 = rif alive_ima_leach[r] > 0:e1 = rif alive_leach[r] > 0:e2 = r
y=[[a1, a2],[b1, b2],[c1, c2],[d1, d2],[e1, e2]]
y=np.array(y)
x=np.arange(5)
width = 0.36
plt.bar(x-width/2,y[:,0],width=width)
plt.bar(x+width/2,y[:,1],width=width)
plt.xticks(range(5),['0', '10', '20', '50', '100'])
plt.legend(['IMP_LEACH', 'LEACH'])
plt.xlabel('死亡比例')
plt.ylabel('循环轮数')plt.show()
代码文件
LEACH路由协议优化python仿真代码
无线传感器网络:LEACH路由协议优化python仿真代码相关推荐
- flooding matlab仿真,无线传感器网络flooding路由协议MATLAB仿真.doc
PAGE 摘 要 无线传感器网络是计算机科学技术的一个新的研究领域,是传感器技术.嵌入式计算技术.分布式信息处理技术和无线通信技术相结合的产物.与传统网络相比,无线传感器网络具有造价低.功耗低.布局灵 ...
- 无线传感器网络WSN覆盖优化问题
目录 一.相关基础 1 相关概念 2 相关分类 2.1 按节点部署方式分类 2.2 按覆盖目标分类 2.3 按网络中的传感器类型分类 2.4 传感器种类 2.5 地形分类 3 评价指标 3.1 覆盖率 ...
- 【LEACH协议】基于matlab无线传感器网络LEACH与DEEC协议【含Matlab源码 2187期】
⛄一. 简介 1 引言 WSN 由能感知外部环境的传感器节点以自组网的形式构成,是一种分布式无线传感器网络.随着科技的进步和现代生活的需求,由于 WSN 的远程控制.信息即时传播以及低功耗等众多优点, ...
- 基于均衡优化算法的无线传感器网络三维覆盖优化
文章目录 一.理论基础 1.种群初始化 2.均衡池 3.浓度更新 4.EO算法伪代码 二.仿真实验与分析 1.函数测试与数值分析 2.WSN三维覆盖优化 三.参考文献 一.理论基础 均衡优化(Equi ...
- 基于RSS和TOA两种方法的无线传感器网络定位测量算法matlab仿真
up目录 一.理论基础 二.核心程序 三.测试结果 一.理论基础 无线传感器网络(Wireless Sensor Networks, WSN)是一种分布式传感网络,它的末梢是可以感知和检查外部世界的传 ...
- 基于无线Mesh网络OLSR路由协议的MATLAB仿真
目录 一.理论基础 二.核心程序 三.测试结果 一.理论基础 无线Mesh网络其也可以称为无线网状网络或者无线多跳网络,其具有动态自组织.自配置.易于维护等优点,同时还具备成本较低,系统运行稳定的优势 ...
- 【神经网络】(10) Resnet18、34 残差网络复现,附python完整代码
各位同学好,今天和大家分享一下 TensorFlow 深度学习中如何搭载 Resnet18 和 Resnet34 残差神经网络,残差网络利用 shotcut 的方法成功解决了网络退化的问题,在训练集和 ...
- spin协议 matlab 仿真,无线传感网络高效路由协议设计
1 引言 无线传感器网络是一种无基础设施的无线网络,它综合了传感器技术.嵌入式计算技术.分布式信息处理技术和无线通信技术,能够协作地实时监测.感知和采集网络分布区域内的各种环境或监测对象的信息,并对这 ...
- 【WSN】基于改进鲸鱼算法算法实现无线传感器网络wsn节点部署优化matlab源码
1 算法介绍 1.1 wsn模型 1.2 鲸鱼算法 鲸鱼优化算法(WOA),该算法模拟了座头鲸的社会行为,并引入了气泡网狩猎策略. 1.1 灵感 鲸鱼被认为是世界上最大的哺乳动物.一头成年鲸可以长达 ...
- NUAA无线传感器网络 复习重点整理
鸣谢 授课老师:郝洁老师 个人主页 在cdsn博主:Matts Tian 基础上修改.添加 Matts Tian 体系结构 什么是无线传感器网络? 无线传感器网络(Wireless sensor ne ...
最新文章
- 实验6 触发器的使用
- 使用javaHelp制作java swing帮助文档
- Python 进阶_OOP 面向对象编程_类属性和方法
- C++ 使用静态变量和静态方法统计学生分数和学生个数
- mysql根据某个字段的不同状态的值进行统计
- html细边框表格代码,html中表格细边框的四种实现及其比较.doc
- mysql架构 视频_企业常见MySQL架构应用实战(高可用集群系统+调优经验)视频课程...
- eclipse鼠标变十了_Eclipse在过去十年中的主要成就
- LeetCode之最大正方形
- ctf音频yinxie_ctf-图片隐写术
- 181021词霸有道扇贝每日一句
- 【题解】PTA-Python题库 浙大版《Python 程序设计》题目集题解索引
- Exchange2010删除指定账户指定主题邮件
- 小米10开始抓取日志怎么关闭_日志MIUI 10 9.5.22 内测更新资讯
- win10系统让图片打开方式为照片查看器
- 深度Deepin20 安装软件的依赖问题(sudo apt --fix-broken install)
- Python——第五天Beer
- python语言进行生日悖论分析--随机试验方法
- John F. Kennedy的就职演说(在线收听)
- 【Python】什么是递归函数?