LEACH协议python仿真及分析改进

LEACH协议python仿真及分析改进

wf

1.修改及测试代码

1.1 LEACH路由场景文件的生成

在这里插入图片描述

绿色小圆圈代表站点,随机生成100个

1.2 SINK结点

蓝色代表SINK结点,中间位置

1.3 设置簇头

紫色代表簇头结点,根据T(n)阈值进行选取,第一轮时簇头选取情况

1.4 一般节点加入簇

第一轮时结点加入簇

1.4 死亡节点

当能量小于0,节点死亡。

1.5 簇头数目

随着节点能量的减少,节点进入死亡期,可活动的节点越来越少,产生簇头越来越难。大多时间都是0簇头,其他非死亡节点不能正常工作。

1.6 死亡节点

1.7 能量消耗

1.7.1

1.7.2

2. 改进

2.1 上述算法

在(1/p)轮每阶段中簇头不重复的节点上产生,使每个节点多有机会成为簇头,使能量消耗均分。(1/p)后,每个非死亡节点有都会有机会成为簇头,这样可以避免,有的节点成为簇点后,能量依然充足,还可以胜任簇头工作。

2.2 缺点

由于簇头的产生就有随机性,产生的簇头不一定是最优的。
可能会出现在偏僻的地方,周围没有站点。或者簇头产生
过于密集,导致其他站点与簇头通信距离增加,需要消耗更大的能量。或者生成的簇头不合理,出现在一个簇的偏远地方。

从能量消耗的图中看出,总能量出现负值。这是由于一个节点本身能量很少,有选为簇头,致使在模拟中出现负值,在实际中,就会出现,由于组头死亡,整个不簇能正常通信。

从簇头数目图中看出,当节点稀疏且少时,选取簇头算法非常不利。

2.3 改进

2.3.1 负能量问题

设置能量阈值,当低于一定能量时,不可再选为簇头。

与1.6图相比,图中可以看出可以减缓死亡数目。

2.3.2 簇头节点密集问题

簇头之间加入距离阈值,在一个簇头范围内不可再产生簇头。

阈值设置为4个单位。

阈值设置为8个单位。

2.3.3 簇头孤立点

当一定时间段内(即所有节点都加入到簇后),簇头检测加入本簇的节点数目,当少于一定数目时,将此簇解散,令簇头变成普通节点,加入邻近的簇头。

参考

  1. 基于NS2的LEACH协议仿真与分析

附录

  1. 仿真环境 jupyter notebook
  2. 仿真代码
import matplotlib.pyplot  as plt
import random
import math
import numpy as np
import cv2 as cv
xm=500;
ym=500;
sink_x=round(0.5*xm);
sink_y=round(0.5*ym);

n=100;
p=0.2;#20%的簇头

E0=0.02;
ETX=50*0.000000000001;
ERX=50*0.000000000001;
Efs=10*0.000000000001;
EDA=5*0.000000000001;

cc=0.6;
rmax=1000;
CM=32;
DM=4000;

class S:
    def __init__(self):
        pass
img0 = np.ones((500, 500, 3), np.uint8)*255 #生成一个空灰度图像
img=img0.copy()
Sc=[]
s_x=[]
s_y=[]
for i in range(0,n,1):
    s=S()
    s.xd=round(random.random()*xm);
    s.yd=round(random.random()*ym);
    s.G=0;
    s.E=E0;
    s.type='N';
    #plt.plot(s.xd,s.yd,'o');
    s_x.append(s.xd)
    s_y.append(s.yd)
    Sc.append(s)
    cv.circle(img,(Sc[i].xd,Sc[i].yd), 3, (0,255,0), 4);
# plt.scatter(s_x,s_y,color=['blue'])
plt.imshow(img)
s=S()
s.xd=sink_x;
s.yd=sink_y;
Sc.append(s)
cv.circle(img,(Sc[n].xd,Sc[n].yd), 4, (0,0,255), 8);
plt.imshow(img)
img1=img.copy()
flag_first_dead=0;
Dead=[0 for i in range(rmax)]
CH_Num=[0 for i in range(rmax)]
dead=0
img=img1.copy()

C=[]#存储簇头信息
packet_To_BS=[]
flag_first_dead=0;
Dead=[0 for i in range(rmax)]
CH_Num=[0 for i in range(rmax)]


img=img1.copy()

C=[]#存储簇头信息
R=[]#存储每轮每个节点的剩余能量


for r in range(0,rmax,1):
#         r+1 #显示轮数
        print('r:',r)
        if  r%round(1/p)==0:
            for i in range(0,n,1):
                Sc[i].G=0;
        cluster=0;#%初始簇頭數為0
        dead=0;#%初始死亡節點數為0
        packet_To_BS=[]
        img=img0.copy()
        for i in range(0,n,1):
            if Sc[i].E<=0 :
#                 plt.plot(Sc[i].xd,Sc[i].yd,'red .');
#                 print((Sc[i].xd,Sc[i].yd))
                cv.circle(img,(Sc[i].xd,Sc[i].yd), 3, (255,0,0),4);
                dead=dead+1;
                Sc[i].type='D'
            else:
                Sc[i].type='N';
#               plt.plot(Sc[i].xd,Sc[i].yd,'o');
                cv.circle(img, (Sc[i].xd,Sc[i].yd),3, (0,255,0),4)
            
#             ## 记录第一个死亡的结点
#             if dead==1:
#                 if flag_first_dead==0:
#                     first_dead=r;
#                     flag_first_dead=1;# save ltest, first_dead;
#             else:
#                 Sc[i].type='N';
# #               plt.plot(Sc[i].xd,Sc[i].yd,'o');
#                 cv.circle(img, (Sc[i].xd,Sc[i].yd),1, (0,255,0),4)
#         plt.plot(Sc[n].xd,Sc[n].yd,'x');#%繪製基站
        cv.circle(img, (Sc[n].xd,Sc[n].yd),4, (0,0,255),8)
        Dead[r]=dead;# %每輪有死亡節點數
#         print('r:dead',r,':',Dead[r]);
         #save ltest, Dead(r+1);%將此數據存入ltest文件
        ###设置簇头
        for i in range(0,n,1):
            if Sc[i].E>0:
                if Sc[i].G<=0:
                    temp_rand=random.random();   
#                     print(temp_rand,'----------------',(p/(1-p*(r%round(1/p)))))
                    if temp_rand<=(p/(1-p*(r%round(1/p)))):
                        Sc[i].type='C';#%此節點為此輪簇頭
                        Sc[i].G=round(1/p)-1;#%S(i).G設置為大於0,此週期不能再被選擇為簇頭
                        cluster=cluster+1;#%簇頭數加1
                        c=S()
                        c.xd=Sc[i].xd;
                        c.yd=Sc[i].yd;#%將此節點標誌為簇頭
#                         print((c.xd,c.yd),'设置为簇头');
                        #plot(Sc[i].xd,Sc[i].yd,'k*');#%繪製此簇頭
                        cv.circle(img,(Sc[i].xd,Sc[i].yd), 3, (255,0,255),4);
                        distance=math.sqrt((Sc[i].xd-(Sc[n].xd))**2+(Sc[i].yd-(Sc[n].yd))**2);#%簇頭到基站的距離
                        c.distance=distance;#%標誌為此簇頭的距離
                        c.id=i; #%此簇頭的節點id
                        C.append(c);
                        packet_To_BS.append(1);#%發送到基站的數據包數為1  
        CH_Num[r]=cluster; #%每輪的簇頭數
                #save ltest,CH_Num(r+1);#%保存每輪簇頭數到ltest
        img1=img.copy()
        for i in range(0,n,1):
            if Sc[i].type=='N' and Sc[i].E>0 and cluster>0:#%對每個能量大於0且非簇頭節點
                min_dis=math.sqrt((Sc[i].xd-(C[0].xd))**2+(Sc[i].yd-(C[0].yd))**2);#%計算此節點到簇頭1的距離
                min_dis_cluster=0;
                for c in range(1,cluster,1):
                    temp=math.sqrt((Sc[i].xd-(C[c].xd))**2+(Sc[i].yd-(C[c].yd))**2);
                    if temp<min_dis:
                        min_dis=temp;
                        min_dis_cluster=c;
                cv.line(img1, (Sc[i].xd, Sc[i].yd), (C[min_dis_cluster].xd, C[min_dis_cluster].yd), (0,125,0), 1)
#                 if min_dis_cluster>=len(packet_To_BS):
#                     packet_To_BS.append(1);
#                 else:
#                 print('cu',min_dis_cluster)
#                 print('len:',len(packet_To_BS))
                packet_To_BS[min_dis_cluster]=packet_To_BS[min_dis_cluster]+1;#%將此節點加入的簇
                Er1=ERX*CM*(cluster+1);#%此節點接收各個簇頭的控制信息
                #%此節點加入的簇的簇頭時隙控制信息的總接收能耗
                Et1=ETX*(CM+DM)+Efs*(CM+DM)*min_dis*min_dis;#%此節點發送加入信息和發送數據信息
#                 #%到簇頭的能耗
                Sc[i].E=Sc[i].E-Er1-Et1;#%此輪後的剩餘能量
        for c in  range(0,cluster,1):#%各個簇頭
#             packet_To_BS(c);#%簇頭需發送到基站的數據包個數
            CEr1=ERX*CM*(packet_To_BS[c]-1);#%收到此簇各個節點加入信息的能耗
            CEr2=ERX*DM*(packet_To_BS[c]-1);#%收到此簇各個節點數據信息的能耗
            CEt1=ETX*CM+Efs*CM*(math.sqrt(xm*ym/25.0))*(math.sqrt(xm*ym/25.0));#%此簇頭廣播成簇信息的能耗
            CEt2=(ETX+EDA)*DM*cc*packet_To_BS[c]+Efs*DM*cc*packet_To_BS[c]*C[c].distance*C[c].distance/25.0;#%簇頭將所以數據融合後發往基站的能耗
            Sc[C[c].id].E=Sc[C[c].id].E-CEr1-CEr2-CEt1-CEt2;#%此輪後簇頭的剩餘能量
        for i in range(0,n,1):
#             if Sc[i].type=='N':
#                 print('站点_',i,":",Sc[i].E)
#             else:
#                 print('簇头_',i,":",Sc[i].E)
            R.append(Sc[i].E);#  %每輪每節點的剩餘能量
#     #% save ltest,R(r+1,i);%保存此數據到ltest
  1. 负能量改进
flag_first_dead=0;
Dead=[0 for i in range(rmax)]
CH_Num=[0 for i in range(rmax)]


img=img1.copy()

C=[]#存储簇头信息
R=[]#存储每轮每个节点的剩余能量


for r in range(0,rmax,1):
#         r+1 #显示轮数
        print('r:',r)
        if  r%round(1/p)==0:
            for i in range(0,n,1):
                Sc[i].G=0;
        cluster=0;#%初始簇頭數為0
        dead=0;#%初始死亡節點數為0
        packet_To_BS=[]
        img=img0.copy()
        for i in range(0,n,1):
            if Sc[i].E<=0 :
#                 plt.plot(Sc[i].xd,Sc[i].yd,'red .');
#                 print((Sc[i].xd,Sc[i].yd))
                cv.circle(img,(Sc[i].xd,Sc[i].yd), 3, (255,0,0),4);
                dead=dead+1;
                Sc[i].type='D'
            else:
                Sc[i].type='N';
#               plt.plot(Sc[i].xd,Sc[i].yd,'o');
                cv.circle(img, (Sc[i].xd,Sc[i].yd),3, (0,255,0),4)
            
#             ## 记录第一个死亡的结点
#             if dead==1:
#                 if flag_first_dead==0:
#                     first_dead=r;
#                     flag_first_dead=1;# save ltest, first_dead;
#             else:
#                 Sc[i].type='N';
# #               plt.plot(Sc[i].xd,Sc[i].yd,'o');
#                 cv.circle(img, (Sc[i].xd,Sc[i].yd),1, (0,255,0),4)
#         plt.plot(Sc[n].xd,Sc[n].yd,'x');#%繪製基站
        cv.circle(img, (Sc[n].xd,Sc[n].yd),4, (0,0,255),8)
        Dead[r]=dead;# %每輪有死亡節點數
#         print('r:dead',r,':',Dead[r]);
         #save ltest, Dead(r+1);%將此數據存入ltest文件
        ###设置簇头
        for i in range(0,n,1):
            if Sc[i].E>0.005:
                if Sc[i].G<=0:
                    temp_rand=random.random();   
#                     print(temp_rand,'----------------',(p/(1-p*(r%round(1/p)))))
                    if temp_rand<=(p/(1-p*(r%round(1/p)))):
                        Sc[i].type='C';#%此節點為此輪簇頭
                        Sc[i].G=round(1/p)-1;#%S(i).G設置為大於0,此週期不能再被選擇為簇頭
                        cluster=cluster+1;#%簇頭數加1
                        c=S()
                        c.xd=Sc[i].xd;
                        c.yd=Sc[i].yd;#%將此節點標誌為簇頭
#                         print((c.xd,c.yd),'设置为簇头');
                        #plot(Sc[i].xd,Sc[i].yd,'k*');#%繪製此簇頭
                        cv.circle(img,(Sc[i].xd,Sc[i].yd), 3, (255,0,255),4);
                        distance=math.sqrt((Sc[i].xd-(Sc[n].xd))**2+(Sc[i].yd-(Sc[n].yd))**2);#%簇頭到基站的距離
                        c.distance=distance;#%標誌為此簇頭的距離
                        c.id=i; #%此簇頭的節點id
                        C.append(c);
                        packet_To_BS.append(1);#%發送到基站的數據包數為1  
        CH_Num[r]=cluster; #%每輪的簇頭數
                #save ltest,CH_Num(r+1);#%保存每輪簇頭數到ltest
        img1=img.copy()
        for i in range(0,n,1):
            if Sc[i].type=='N' and Sc[i].E>0 and cluster>0:#%對每個能量大於0且非簇頭節點
                min_dis=math.sqrt((Sc[i].xd-(C[0].xd))**2+(Sc[i].yd-(C[0].yd))**2);#%計算此節點到簇頭1的距離
                min_dis_cluster=0;
                for c in range(1,cluster,1):
                    temp=math.sqrt((Sc[i].xd-(C[c].xd))**2+(Sc[i].yd-(C[c].yd))**2);
                    if temp<min_dis:
                        min_dis=temp;
                        min_dis_cluster=c;
                cv.line(img1, (Sc[i].xd, Sc[i].yd), (C[min_dis_cluster].xd, C[min_dis_cluster].yd), (0,125,0), 1)
#                 if min_dis_cluster>=len(packet_To_BS):
#                     packet_To_BS.append(1);
#                 else:
#                 print('cu',min_dis_cluster)
#                 print('len:',len(packet_To_BS))
                packet_To_BS[min_dis_cluster]=packet_To_BS[min_dis_cluster]+1;#%將此節點加入的簇
                Er1=ERX*CM*(cluster+1);#%此節點接收各個簇頭的控制信息
                #%此節點加入的簇的簇頭時隙控制信息的總接收能耗
                Et1=ETX*(CM+DM)+Efs*(CM+DM)*min_dis*min_dis;#%此節點發送加入信息和發送數據信息
#                 #%到簇頭的能耗
                Sc[i].E=Sc[i].E-Er1-Et1;#%此輪後的剩餘能量
        for c in  range(0,cluster,1):#%各個簇頭
#             packet_To_BS(c);#%簇頭需發送到基站的數據包個數
            CEr1=ERX*CM*(packet_To_BS[c]-1);#%收到此簇各個節點加入信息的能耗
            CEr2=ERX*DM*(packet_To_BS[c]-1);#%收到此簇各個節點數據信息的能耗
            CEt1=ETX*CM+Efs*CM*(math.sqrt(xm*ym/25.0))*(math.sqrt(xm*ym/25.0));#%此簇頭廣播成簇信息的能耗
            CEt2=(ETX+EDA)*DM*cc*packet_To_BS[c]+Efs*DM*cc*packet_To_BS[c]*C[c].distance*C[c].distance/25.0;#%簇頭將所以數據融合後發往基站的能耗
            Sc[C[c].id].E=Sc[C[c].id].E-CEr1-CEr2-CEt1-CEt2;#%此輪後簇頭的剩餘能量
        for i in range(0,n,1):
#             if Sc[i].type=='N':
#                 print('站点_',i,":",Sc[i].E)
#             else:
#                 print('簇头_',i,":",Sc[i].E)
            R.append(Sc[i].E);#  %每輪每節點的剩餘能量
#     #% save ltest,R(r+1,i);%保存此數據到ltest
  1. 簇头密集问题
flag_first_dead=0;
Dead=[0 for i in range(rmax)]
CH_Num=[0 for i in range(rmax)]


img=img1.copy()

C=[]#存储簇头信息
R=[]#存储每轮每个节点的剩余能量


for r in range(0,1,1):
#         r+1 #显示轮数
        print('r:',r)
        if  r%round(1/p)==0:
            for i in range(0,n,1):
                Sc[i].G=0;
        cluster=0;#%初始簇頭數為0
        dead=0;#%初始死亡節點數為0
        packet_To_BS=[]
        img=img0.copy()
        for i in range(0,n,1):
            if Sc[i].E<=0 :
#                 plt.plot(Sc[i].xd,Sc[i].yd,'red .');
#                 print((Sc[i].xd,Sc[i].yd))
                cv.circle(img,(Sc[i].xd,Sc[i].yd), 3, (255,0,0),4);
                dead=dead+1;
                Sc[i].type='D'
            else:
                Sc[i].type='N';
#               plt.plot(Sc[i].xd,Sc[i].yd,'o');
                cv.circle(img, (Sc[i].xd,Sc[i].yd),3, (0,255,0),4)
            
#             ## 记录第一个死亡的结点
#             if dead==1:
#                 if flag_first_dead==0:
#                     first_dead=r;
#                     flag_first_dead=1;# save ltest, first_dead;
#             else:
#                 Sc[i].type='N';
# #               plt.plot(Sc[i].xd,Sc[i].yd,'o');
#                 cv.circle(img, (Sc[i].xd,Sc[i].yd),1, (0,255,0),4)
#         plt.plot(Sc[n].xd,Sc[n].yd,'x');#%繪製基站
        cv.circle(img, (Sc[n].xd,Sc[n].yd),4, (0,0,255),8)
        Dead[r]=dead;# %每輪有死亡節點數
#         print('r:dead',r,':',Dead[r]);
         #save ltest, Dead(r+1);%將此數據存入ltest文件
        ###设置簇头
        for i in range(0,n,1):
            if Sc[i].E>0.0001:
                if Sc[i].G<=0:
                    temp_rand=random.random();   
#                     print(temp_rand,'----------------',(p/(1-p*(r%round(1/p)))))
                    if temp_rand<=(p/(1-p*(r%round(1/p)))):
                        min_dis=40
                        for c in range(0,cluster,1):
                            temp=math.sqrt((Sc[i].xd-(C[c].xd))**2+(Sc[i].yd-(C[c].yd))**2);
                            if temp<min_dis:
                                min_dis=temp;
                        if min_dis<40:
                            continue;
                        
                        Sc[i].type='C';#%此節點為此輪簇頭
                        Sc[i].G=round(1/p)-1;#%S(i).G設置為大於0,此週期不能再被選擇為簇頭
                        cluster=cluster+1;#%簇頭數加1
                        c=S()
                        c.xd=Sc[i].xd;
                        c.yd=Sc[i].yd;#%將此節點標誌為簇頭
#                         print((c.xd,c.yd),'设置为簇头');
                        #plot(Sc[i].xd,Sc[i].yd,'k*');#%繪製此簇頭
                        cv.circle(img,(Sc[i].xd,Sc[i].yd), 3, (255,0,255),4);
                        distance=math.sqrt((Sc[i].xd-(Sc[n].xd))**2+(Sc[i].yd-(Sc[n].yd))**2);#%簇頭到基站的距離
                        c.distance=distance;#%標誌為此簇頭的距離
                        c.id=i; #%此簇頭的節點id
                        C.append(c);
                        packet_To_BS.append(1);#%發送到基站的數據包數為1  
        CH_Num[r]=cluster; #%每輪的簇頭數
                #save ltest,CH_Num(r+1);#%保存每輪簇頭數到ltest
        img1=img.copy()
        for i in range(0,n,1):
            if Sc[i].type=='N' and Sc[i].E>0 and cluster>0:#%對每個能量大於0且非簇頭節點
                min_dis=math.sqrt((Sc[i].xd-(C[0].xd))**2+(Sc[i].yd-(C[0].yd))**2);#%計算此節點到簇頭1的距離
                min_dis_cluster=0;
                for c in range(1,cluster,1):
                    temp=math.sqrt((Sc[i].xd-(C[c].xd))**2+(Sc[i].yd-(C[c].yd))**2);
                    if temp<min_dis:
                        min_dis=temp;
                        min_dis_cluster=c;
                cv.line(img1, (Sc[i].xd, Sc[i].yd), (C[min_dis_cluster].xd, C[min_dis_cluster].yd), (0,125,0), 1)
#                 if min_dis_cluster>=len(packet_To_BS):
#                     packet_To_BS.append(1);
#                 else:
#                 print('cu',min_dis_cluster)
#                 print('len:',len(packet_To_BS))
                packet_To_BS[min_dis_cluster]=packet_To_BS[min_dis_cluster]+1;#%將此節點加入的簇
                Er1=ERX*CM*(cluster+1);#%此節點接收各個簇頭的控制信息
                #%此節點加入的簇的簇頭時隙控制信息的總接收能耗
                Et1=ETX*(CM+DM)+Efs*(CM+DM)*min_dis*min_dis;#%此節點發送加入信息和發送數據信息
#                 #%到簇頭的能耗
                Sc[i].E=Sc[i].E-Er1-Et1;#%此輪後的剩餘能量
        for c in  range(0,cluster,1):#%各個簇頭
#             packet_To_BS(c);#%簇頭需發送到基站的數據包個數
            CEr1=ERX*CM*(packet_To_BS[c]-1);#%收到此簇各個節點加入信息的能耗
            CEr2=ERX*DM*(packet_To_BS[c]-1);#%收到此簇各個節點數據信息的能耗
            CEt1=ETX*CM+Efs*CM*(math.sqrt(xm*ym/25.0))*(math.sqrt(xm*ym/25.0));#%此簇頭廣播成簇信息的能耗
            CEt2=(ETX+EDA)*DM*cc*packet_To_BS[c]+Efs*DM*cc*packet_To_BS[c]*C[c].distance*C[c].distance/25.0;#%簇頭將所以數據融合後發往基站的能耗
            Sc[C[c].id].E=Sc[C[c].id].E-CEr1-CEr2-CEt1-CEt2;#%此輪後簇頭的剩餘能量
        for i in range(0,n,1):
#             if Sc[i].type=='N':
#                 print('站点_',i,":",Sc[i].E)
#             else:
#                 print('簇头_',i,":",Sc[i].E)
            R.append(Sc[i].E);#  %每輪每節點的剩餘能量
#     #% save ltest,R(r+1,i);%保存此數據到ltest
  1. 簇孤立点
flag_first_dead=0;
Dead=[0 for i in range(rmax)]
CH_Num=[0 for i in range(rmax)]


img=img1.copy()

C=[]#存储簇头信息
R=[]#存储每轮每个节点的剩余能量


for r in range(0,1,1):
#         r+1 #显示轮数
        print('r:',r)
        if  r%round(1/p)==0:
            for i in range(0,n,1):
                Sc[i].G=0;
        cluster=0;#%初始簇頭數為0
        dead=0;#%初始死亡節點數為0
        packet_To_BS=[]
        img=img0.copy()
        for i in range(0,n,1):
            if Sc[i].E<=0 :
#                 plt.plot(Sc[i].xd,Sc[i].yd,'red .');
#                 print((Sc[i].xd,Sc[i].yd))
                cv.circle(img,(Sc[i].xd,Sc[i].yd), 3, (255,0,0),4);
                dead=dead+1;
                Sc[i].type='D'
            else:
                Sc[i].type='N';
#               plt.plot(Sc[i].xd,Sc[i].yd,'o');
                cv.circle(img, (Sc[i].xd,Sc[i].yd),3, (0,255,0),4)
            
#             ## 记录第一个死亡的结点
#             if dead==1:
#                 if flag_first_dead==0:
#                     first_dead=r;
#                     flag_first_dead=1;# save ltest, first_dead;
#             else:
#                 Sc[i].type='N';
# #               plt.plot(Sc[i].xd,Sc[i].yd,'o');
#                 cv.circle(img, (Sc[i].xd,Sc[i].yd),1, (0,255,0),4)
#         plt.plot(Sc[n].xd,Sc[n].yd,'x');#%繪製基站
        cv.circle(img, (Sc[n].xd,Sc[n].yd),4, (0,0,255),8)
        Dead[r]=dead;# %每輪有死亡節點數
#         print('r:dead',r,':',Dead[r]);
         #save ltest, Dead(r+1);%將此數據存入ltest文件
        ###设置簇头
        for i in range(0,n,1):
            if Sc[i].E>0.0001:
                if Sc[i].G<=0:
                    temp_rand=random.random();   
#                     print(temp_rand,'----------------',(p/(1-p*(r%round(1/p)))))
                    if temp_rand<=(p/(1-p*(r%round(1/p)))):
                        min_dis=40
                        for c in range(0,cluster,1):
                            temp=math.sqrt((Sc[i].xd-(C[c].xd))**2+(Sc[i].yd-(C[c].yd))**2);
                            if temp<min_dis:
                                min_dis=temp;
                        if min_dis<40:
                            continue;
                        
                        Sc[i].type='C';#%此節點為此輪簇頭
                        Sc[i].G=round(1/p)-1;#%S(i).G設置為大於0,此週期不能再被選擇為簇頭
                        cluster=cluster+1;#%簇頭數加1
                        c=S()
                        c.xd=Sc[i].xd;
                        c.yd=Sc[i].yd;#%將此節點標誌為簇頭
#                         print((c.xd,c.yd),'设置为簇头');
                        #plot(Sc[i].xd,Sc[i].yd,'k*');#%繪製此簇頭
                        cv.circle(img,(Sc[i].xd,Sc[i].yd), 3, (255,0,255),4);
                        distance=math.sqrt((Sc[i].xd-(Sc[n].xd))**2+(Sc[i].yd-(Sc[n].yd))**2);#%簇頭到基站的距離
                        c.distance=distance;#%標誌為此簇頭的距離
                        c.id=i; #%此簇頭的節點id
                        C.append(c);
                        packet_To_BS.append(1);#%發送到基站的數據包數為1  
        CH_Num[r]=cluster; #%每輪的簇頭數
                #save ltest,CH_Num(r+1);#%保存每輪簇頭數到ltest
        img1=img.copy()
        for i in range(0,n,1):
            if Sc[i].type=='N' and Sc[i].E>0 and cluster>0:#%對每個能量大於0且非簇頭節點
                min_dis=math.sqrt((Sc[i].xd-(C[0].xd))**2+(Sc[i].yd-(C[0].yd))**2);#%計算此節點到簇頭1的距離
                min_dis_cluster=0;
                for c in range(1,cluster,1):
                    temp=math.sqrt((Sc[i].xd-(C[c].xd))**2+(Sc[i].yd-(C[c].yd))**2);
                    if temp<min_dis:
                        min_dis=temp;
                        min_dis_cluster=c;
                cv.line(img1, (Sc[i].xd, Sc[i].yd), (C[min_dis_cluster].xd, C[min_dis_cluster].yd), (0,125,0), 1)
#                 if min_dis_cluster>=len(packet_To_BS):
#                     packet_To_BS.append(1);
#                 else:
#                 print('cu',min_dis_cluster)
#                 print('len:',len(packet_To_BS))
                packet_To_BS[min_dis_cluster]=packet_To_BS[min_dis_cluster]+1;#%將此節點加入的簇
                Er1=ERX*CM*(cluster+1);#%此節點接收各個簇頭的控制信息
                #%此節點加入的簇的簇頭時隙控制信息的總接收能耗
                Et1=ETX*(CM+DM)+Efs*(CM+DM)*min_dis*min_dis;#%此節點發送加入信息和發送數據信息
#                 #%到簇頭的能耗
                Sc[i].E=Sc[i].E-Er1-Et1;#%此輪後的剩餘能量
        img2=img1.copy()
        for c in range(0,cluster,1):
            if packet_To_BS[c]<=1:
                C[c].type='N'
                min_dis=500;
                for c0 in range(0,cluster,1):
                    if c0==c:
                        continue;
                    temp=math.sqrt((C[c].xd-(C[c0].xd))**2+(C[c].yd-(C[c0].yd))**2);
                    if temp<min_dis:
                        min_dis=temp;
                        min_dis_cluster=c0;
                print(min_dis_cluster)
                print(c)
                cv.circle(img2, (C[c].xd,C[c].yd),3, (0,255,0),4)
                cv.line(img2, (C[c].xd, C[c].yd), (C[min_dis_cluster].xd, C[min_dis_cluster].yd), (0,125,0), 1)
                
        
        for c in  range(0,cluster,1):#%各個簇頭
#             packet_To_BS(c);#%簇頭需發送到基站的數據包個數
            CEr1=ERX*CM*(packet_To_BS[c]-1);#%收到此簇各個節點加入信息的能耗
            CEr2=ERX*DM*(packet_To_BS[c]-1);#%收到此簇各個節點數據信息的能耗
            CEt1=ETX*CM+Efs*CM*(math.sqrt(xm*ym/25.0))*(math.sqrt(xm*ym/25.0));#%此簇頭廣播成簇信息的能耗
            CEt2=(ETX+EDA)*DM*cc*packet_To_BS[c]+Efs*DM*cc*packet_To_BS[c]*C[c].distance*C[c].distance/25.0;#%簇頭將所以數據融合後發往基站的能耗
            Sc[C[c].id].E=Sc[C[c].id].E-CEr1-CEr2-CEt1-CEt2;#%此輪後簇頭的剩餘能量
        for i in range(0,n,1):
#             if Sc[i].type=='N':
#                 print('站点_',i,":",Sc[i].E)
#             else:
#                 print('簇头_',i,":",Sc[i].E)
            R.append(Sc[i].E);#  %每輪每節點的剩餘能量
#     #% save ltest,R(r+1,i);%保存此數據到ltest

CEr2=ERXDM(packet_To_BS[c]-1);#%收到此簇各個節點數據信息的能耗
CEt1=ETXCM+EfsCM*(math.sqrt(xmym/25.0))(math.sqrt(xmym/25.0));#%此簇頭廣播成簇信息的能耗
CEt2=(ETX+EDA)DMcc
packet_To_BS[c]+EfsDMcc*packet_To_BS[c]C[c].distanceC[c].distance/25.0;#%簇頭將所以數據融合後發往基站的能耗
Sc[C[c].id].E=Sc[C[c].id].E-CEr1-CEr2-CEt1-CEt2;#%此輪後簇頭的剩餘能量
for i in range(0,n,1):

if Sc[i].type==‘N’:

print(‘站点_’,i,":",Sc[i].E)

else:

print(‘簇头_’,i,":",Sc[i].E)

        R.append(Sc[i].E);#  %每輪每節點的剩餘能量

#% save ltest,R(r+1,i);%保存此數據到ltest


























  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值