% my leach code based on fuzzy logical method
clear;
%% 参数的初始化
xm=100;
ym=100; % 传感区域范围
n=100; %节点总数
p=0.1; %簇头概率
% 能量模型初始化数据
E0=1;%初始能量
Elec=50e-9;%发送、接收能量,每bit
Efs=10e-12;%耗散能量,每bit
Emp=0.0013e-13;%融合能耗,每bit
do = sqrt( Efs/Emp );
cc=0.8;%融合率
rmax=1000;%轮数设置
MaxDis_CH_Node = sqrt( (xm-0)^2 + (ym-0)^2 ); %簇头广播范围
CM=25;%控制信息大小
DM=4000;%数据信息大小
figure(1);% 显示图片
for i=1:1:n
S(i).xd=rand(1,1)*xm;
S(i).yd=rand(1,1)*ym;
S(i).G=0;%每一个周期结束后,重新设置为0
S(i).E=E0;%节点的初始能量
S(i).type='N';%节点的类型为普通
plot(S(i).xd,S(i).yd,'o');
hold on;%保持所畫的圖像
end
%% 计算网关节点与其他节点的距离, 找出节点与网关的最小距离
MinDist_Node_Sink = zeros(1,n);
Sink(1).xd = 0; Sink(1).yd = 0;
Sink(2).xd = 0; Sink(2).yd = ym;
Sink(3).xd = xm; Sink(3).yd = ym;
Sink(4).xd = xm; Sink(4).yd = 0;
for i = 1: n
TempDist_Node_Sink = zeros(1,4);
for j = 1 : 4
TempDist_Node_Sink(j) = sqrt( (Sink(j).xd - S(i).xd)^2 + ( Sink(j).yd - S(i).yd )^2 );
end
MinDist_Node_Sink(i) = min(TempDist_Node_Sink);
end
%%
first_dead_Round = 0; %第一个死亡节点出现的轮数
flag_first_dead=0; % 记录第一个死亡节点
half_dead_Round = 0;
flag_half_dead = 0;
Round_Alive_Num = zeros( 1,rmax+1 ); %每轮存活节点数目记录
RoundCluster = zeros( 1,rmax ); %记录每轮簇头节点数目
Remaining_En = zeros(1,rmax);
%% 开始
for r = 1:1:rmax
% 如果轮数为一个周期的整数倍, 则将S(i).G 设置为0 ,即所有节点都没有成为簇头节点
if( r>=2 )
if ( Remaining_En(r-1) == 0 )
continue;
end
end
r+1;
if( mod(r,round(1/p))==0 )
for i = 1:n
S(i).G = 0;
end
end
hold off; % 每一轮重新绘制图片
figure(1);
%% 死亡节点标记为红色
dead = 0;
for i = 1:n
if( S(i).E <= 0 )
plot( S(i).xd, S(i).yd, 'red.' );
S(i).E = 0; % 死亡节点剩余能量为0
dead = dead +1;
if( dead == 1 && flag_first_dead == 0 ) % 标记第一个死亡节点
first_dead_Round = r;
flag_first_dead = 1;
end
if( dead == (n/2) && flag_half_dead == 0 )
half_dead_Round = r;
flag_half_dead = 1;
end
hold on;
else
S(i).type = 'N';
plot( S(i).xd, S(i).yd, 'o' );
hold on;
end
Remaining_En(r) = Remaining_En(r) + S(i).E; % 第r 轮总剩余能量
end
Round_Alive_Num(r+1) = n - dead; %记录第 r 轮 存活节点个数
%% 成簇阶段,寻找簇头节点,并计算簇头与基站的距离
cluster = 0;% 每一轮开始前 将簇头数目重置为 0;
for i = 1:n
if( S(i).E > 0 )
if( S(i).G <= 0 )
temp_rand = rand;
if( temp_rand <= (p/(1-p*mod( r, round(1/p)))) )
S(i).type = 'C';
S(i).G = round(1/p) - 1;
cluster = cluster + 1;
C(cluster).xd = S(i).xd;
C(cluster).yd = S(i).yd;
plot(S(i).xd,S(i).yd, 'k*'); % 绘制当前簇头节点
C(cluster).id = i; %簇头的 id 记录
Packet_length( cluster ) = 1;
end
end
end
end
RoundCluster(r) = cluster; % 记录当前轮 成为簇头的节点数目
Node_Cluster = zeros(1,n); % 节点i 选择的簇头id
Dist = zeros( 1,cluster ); % 节点到簇头的距离
for i = 1:n
if ( S(i).E > 0 && S(i).type == 'N' )
Min_Dist = sqrt( ( S(i).xd-C(1).xd )^2 + ( S(i).yd-C(1).yd )^2 ); % 节点到簇头的距离
Min_Dist_Cluster = 1;
for c = 2:1:cluster
Temp_Min_Dist = sqrt( ( S(i).xd-C(c).xd )^2 + ( S(i).yd-C(c).yd )^2 );
if( Temp_Min_Dist < Min_Dist )
Min_Dist = Temp_Min_Dist;
Min_Dist_Cluster = c;
end
end
Node_Cluster(i) = C(Min_Dist_Cluster).id;%节点i 归属的簇头节点的序号
Packet_length( Min_Dist_Cluster ) = Packet_length( Min_Dist_Cluster ) + 1;
Er = Elec * CM * cluster; %簇员节点接收簇头节点发送的控制信息时的能耗
% 簇员节点发送数据到簇头节点时的能耗
if ( Min_Dist < do )
Et = Elec * ( CM + DM ) + Efs * ( CM + DM ) * (Min_Dist)^2;
else
Et = Elec * ( CM + DM ) + Emp * ( CM + DM ) * ( Min_Dist)^4;
end
S(i).E = S(i).E - Et - Er;
end
end
%% 簇头接收数据的能耗
for c = 1:cluster
CER = Elec * Packet_length( c ) * ( CM + DM );
% 簇头发送数据的能耗: 广播簇头信息, 转发融合数据
% 簇头广播成簇信息的能耗,全网广播
if( MaxDis_CH_Node < do )
CET1 = Elec * CM + Efs * CM * MaxDis_CH_Node *MaxDis_CH_Node ;
else
CET1 = Elec * CM + Emp * CM * MaxDis_CH_Node *MaxDis_CH_Node *MaxDis_CH_Node *MaxDis_CH_Node;
end
% 簇头将数据融合后转发的能耗
Dis_CH_Sink = min ( MinDist_Node_Sink( C(c).id ) );
if( Dis_CH_Sink < do )
CET2 = Elec * DM * cc * Packet_length( c ) + Efs * DM * cc * Packet_length( c ) * Dis_CH_Sink * Dis_CH_Sink;
else
CET2 = Elec * DM * cc *Packet_length( c ) + Emp * DM * cc * Packet_length( c ) * Dis_CH_Sink * Dis_CH_Sink * Dis_CH_Sink * Dis_CH_Sink;
end
% 簇头节点的剩余能量计算
S( C(c).id ).E = S( C( c ).id ).E -CET1 - CET2 - CER;
end
end
figure(2);
plot(Round_Alive_Num);
figure(3);
plot(RoundCluster);
figure(4);
plot(Remaining_En);
评论2