资讯详情

无线传感器网络: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'] = False  class BaseStation:  # 定义基站类     x=0     y=0  class SensorNode:  # 传感器节点的定义     xd=0     yd=0     d=0     Rc = 0     temp_rand=0     type = 'N'     selected = 'N'     power = 0     CH = 0     flag = 1     N = []     Num_N = 0     FN = []     Num_FN = 0     CN = []     Num_CN = 0     num_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()*xm
    node.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 = 0
    if alive_ima_leach[r] == 0:
        stop = r
        f = 1
        break
    for 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 = 0
        Node[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 = 2
            Eavg = 0  # 系统节点平均能量
            m = 0     # 存活节点个数
            for j in range(n):
                if Node[i].flag != 0:
                    Eavg = Eavg + Node[i].power
                    m = m + 1
            if m != 0:
                Eavg = Eavg / n  # 计算系统节点平均能量
            else:
                break
            if 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 = -1
                count = count + 1
                final_CH.append(i)      # 加入簇头节点集合
                # 广播自成为簇头
                distanceBroad = (Node[i].Rc ** 2 + Node[i].Rc ** 2) ** 0.5
                if (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 = 0
        for j in range(n):
            if i != j:
                dist = ((Node[i].xd-Node[j].xd)**2+(Node[i].yd-Node[j].yd)**2)**0.5
                if dist < Node[i].Rc:
                    cnt = cnt + 1
                    Node[i].N[cnt] = j
                    # if len(Node[i].N)<cnt:
                    # Node[i].N.append(j)
                    # else:
                    # Node[i].N[cnt-1] = j
            if j == n:
                Node[i].Num_N = cnt
    # 计算前邻节点集
    for i in range(n):
        cnt = 0
        for j in range(Node[i].Num_N):
            ne = Node[i].N[j]
            if Node[ne].d < Node[i].d:
                cnt = cnt + 1
                Node[i].FN[cnt] = ne
            if j == Node[i].Num_N:
                Node[i].Num_FN = cnt
    # 计算前簇头节点集
    for i in range(count):
        cnt = 0
        for 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 + 1
                Node[final_CH[i]].CN[cnt] = fne
            if 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.5
                if dist < Node[final_CH[j]].Rc:    # 满足条件1
                    E[j] = (Node[final_CH[j]].power-Emin)/Node[final_CH[j]].num_join
            if 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.5
                if 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.5
                    min_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 * ctrPacketLength
                    Node[final_CH[min_index]].num_join = Node[final_CH[min_index]].num_join + 1
                else:
                    # 节点发送加入簇的消息
                    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 * ctrPacketLength
                    Node[final_CH[max_index]].Rc = Rmax * Node[final_CH[max_index]].power / E0
                    Node[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.5
                if 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
        标签: e0e1e2传感器cnt传感器fn传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台