目录
- 仿真结果
- python代码
- 代码文件
仿真结果
随机生成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传感器