clear;%清除内存变量
xm=100;%x轴范围
ym=100;%y轴范围
sink.x=0.5*xm;%基站x轴
sink.y=0.5*ym;%基站y轴
n=100;%节点总数
rmax=3000;%轮数
CM=32;%控制信息大小
DM=4000;%数据信息大小
p=0.1;%簇头概率
E0=0.5;%初始能量
ETX=50*0.000000001;%传输能量,每bit
ERX=50*0.000000001;%接收能量,每bit
Efs=10*0.000000000001;%自由空间能量,每bit
Emp=0.0013*0.000000000001;%衰减空间能量,每bit
EDA=5*0.000000000001;%融合能耗,每bit
a=1;%高能量节点超出一节点能量的百分比
d0=sqrt(Efs/Emp);%门限值,假如d<d0,采用自由空间环境下的能量消耗模型,d>d0,则采用多径
S(n+1).xd=sink.x;
S(n+1).yd=sink.y;
for i=1:1:n
S(i).xd=rand(1,1)*xm;%随机生成节点坐标
S(i).yd=rand(1,1)*ym;
S(i).G=0;%用于判断是否成为簇头
S(i).E=E0*(1+rand*a);
S(i).type='N';%节点类型
S(i).distance=sqrt((S(i).xd-(S(n+1).xd))^2+(S(i).yd-(S(n+1).yd))^2);%计算该节点与基站之间的距离
end
countCHs=0;%计算簇头
cluster=1;
flag_first_dead=0;%标志第1个节点死亡
flag_teenth_dead=0;%标志第10个节点死亡
flag_all_dead=0;%标志所有节点死亡
dead=0;
allive=n;
first_dead=0;%出现第1个死亡节点的轮次
teenth_dead=0;
all_dead=0;
packet_to_BS=0;%发送到基站的数据包
packet_to_CH=0;%发送到簇头的数据包
for r=0:1:rmax
if(mod(r,round(1/p))==0) %每过1/p个轮(即一个周期),将S(i).G恢复为0
for i=1:1:n
S(i).G=0;
end
end
%检查有无死亡节点
dead=0;
for i=1:1:n
if(S(i).E<=0)
dead=dead+1;
end
end
if(dead==1) %第1个节点死亡
if(flag_first_dead==0)
first_dead=r;
flag_first_dead=1;
end
end
if(dead==10) %第10个节点死亡
if(flag_teenth_dead==0)
teenth_dead=r;
flag_teenth_dead=1;
end
end
if(dead==n) %第n个节点死亡
if(flag_all_dead==0)
all_dead=r;
flag_all_dead=1;
end
end
%将所有节点类型恢复为普通节点,计算总能量
Et=0;
for i=1:1:n
if(S(i).E>0)
S(i).type='N';
Et=Et+S(i).E;
end
end
STATISTICS.ET(r+1)=Et;
STATISTICS.DEAD(r+1)=dead;
STATISTICS.ALLIVE(r+1)=allive-dead;
%基站收集所有节点位置信息及剩余能量
for i=1:1:n
if(S(i).E>0)
if(S(i).distance>d0)
S(i).E=S(i).E-(ETX*CM+Emp*CM*(S(i).distance*S(i).distance*S(i).distance*S(i).distance));
end
if(S(i).distance<=d0)
S(i).E=S(i).E-(ETX*CM+Efs*CM*(S(i).distance*S(i).distance));
end
end
end
%簇头选举
countCHs=0;%计算簇头
cluster=1;%表示簇头时使用
for i=1:1:n
if(S(i).E>0)
if(S(i).G<=0)
S(i).rand=rand;%取一个随机数
if(S(i).rand<=(p/(1-p*mod(r,round(1/p)))))
S(i).tpye='C';%当选簇头
countCHs=countCHs+1;
S(i).G=round(1/p)-1;%在本周期内使其不再当选为簇头
C(cluster).id=i;
C(cluster).xd=S(i).xd;
C(cluster).yd=S(i).yd;
distance=S(i).distance;
C(cluster).distance=S(i).distance;
cluster=cluster+1;
%该簇头向基站发送数据
if(distance>d0)
S(i).E=S(i).E-((ETX+EDA)*(DM+CM)+Emp*(DM+CM)*(distance*distance*distance*distance));
end
if(distance<=d0)
S(i).E=S(i).E-((ETX+EDA)*(DM+CM)+Efs*(DM+CM)*(distance*distance));
end
packet_to_BS=packet_to_BS+1;
%簇头广播成簇消息
S(i).E=S(i).E-(ETX*CM+Efs*CM*xm*ym);
end
end
end
end
STATISTICS.COUNTCHS(r+1)=countCHs;
%簇内成员
for i=1:1:n
if(S(i).type=='N' && S(i).E>0)
if(cluster-1>=1) %如果存在簇头
%接收簇头消息
S(i).E=S(i).E-ERX*CM*(cluster-1);
%寻找最近的簇头,先假定距离基站最近
min_dis=sqrt((S(i).xd-S(n+1).xd)^2+(S(i).yd-S(n+1).yd)^2);
min_dis_cluster=0;
for c=1:1:cluster-1
if(min_dis>sqrt((S(i).xd-C(c).xd)^2+(S(i).yd-C(c).yd)^2))
min_dis=sqrt((S(i).xd-C(c).xd)^2+(S(i).yd-C(c).yd)^2);
min_dis_cluster=c;
end
end
%假如距离基站最近
if(min_dis_cluster==0)
if(min_dis>d0)
S(i).E=S(i).E-(ETX*(DM+CM)+Emp*(DM+CM)*(min_dis*min_dis*min_dis*min_dis));
end
if(min_dis<=d0)
S(i).E=S(i).E-(ETX*(DM+CM)+Efs*(DM+CM)*(min_dis*min_dis));
end
packet_to_BS=packet_to_BS+1;
end
%另一种可能,向簇头发送信息
if(min_dis_cluster>0)
%节点先发送加入信息
if(min_dis>d0)
S(i).E=S(i).E-(ETX*CM+Emp*CM*(min_dis*min_dis*min_dis*min_dis));
end
if(min_dis<=d0)
S(i).E=S(i).E-(ETX*CM+Efs*CM*(min_dis*min_dis));
end
%簇头接收加入信息,并为节点分配时隙
S(C(min_dis_cluster).id).E=S(C(min_dis_cluster).id).E-ERX*CM;
if(min_dis>d0)
S(C(min_dis_cluster).id).E=S(C(min_dis_cluster).id).E-(ETX*CM+Emp*CM*(min_dis*min_dis*min_dis*min_dis));
end
if(min_dis<=d0)
S(C(min_dis_cluster).id).E=S(C(min_dis_cluster).id).E-(ETX*CM+Efs*CM*(min_dis*min_dis));
end
%节点接收分配到的时隙,发送数据给簇头
S(i).E=S(i).E-ERX*CM;
if(min_dis>d0)
S(i).E=S(i).E-(ETX*DM+Emp*DM*(min_dis*min_dis*min_dis*min_dis));
end
if(min_dis<=d0)
S(i).E=S(i).E-(ETX*DM+Efs*DM*(min_dis*min_dis));
end
%簇头接收数据并融合
S(C(min_dis_cluster).id).E=S(C(min_dis_cluster).id).E-(ERX+EDA)*DM;
packet_to_CH=packet_to_CH+1;
%簇头最后将信息发送至基站
if(min_dis>d0)
S(C(min_dis_cluster).id).E=S(C(min_dis_cluster).id).E-(ETX*DM+Emp*DM*(C(min_dis_cluster).distance*C(min_dis_cluster).distance*C(min_dis_cluster).distance*C(min_dis_cluster).distance));
end
if(min_dis<=d0)
S(C(min_dis_cluster).id).E=S(C(min_dis_cluster).id).E-(ETX*DM+Efs*DM*(C(min_dis_cluster).distance*C(min_dis_cluster).distance));
end
packet_to_BS=packet_to_BS+1;
end
end
%如果不存在簇头,则直接向基站发送
if(cluster-1<1)
if(S(i).distance>d0)
S(i).E=S(i).E-(ETX*DM+Emp*DM*(S(i).distance*S(i).distance*S(i).distance*S(i).distance));
end
if(S(i).distance<=d0)
S(i).E=S(i).E-(ETX*DM+Efs*DM*(S(i).distance*S(i).distance));
end
packet_to_BS=packet_to_BS+1;
end
end
end
STATISTICS.PACKETS_TO_CH(r+1)=packet_to_CH;
STATISTICS.PACKETS_TO_BS(r+1)=packet_to_BS;
end
r=0:rmax;
subplot(2,2,1);
plot(r,STATISTICS.DEAD);
title("dead");
subplot(2,2,2);
plot(r,STATISTICS.COUNTCHS);
title("簇头数");
subplot(2,2,3);
plot(r,STATISTICS.PACKETS_TO_BS);
title("data");
subplot(2,2,4);
plot(r,STATISTICS.ET);
title("总能量");
[first_dead,teenth_dead,all_dead]