%% 清空环境变量
clc;
clear;
%% 参数设置
xm = 100; % x轴范围
ym = 100; % y轴范围
sink.x = 50; % 基站x轴
sink.y = 150; % 基站y轴
n = 100; % 节点总数
p = 0.1; % 簇头比例
E0 = 0.5; % 初始能量
Eelec = 50*10^(-9);
ETX = 50*10^(-9); % 传输消耗能量,每bit
ERX = 50*10^(-9); % 接收消耗能量,每bit
Efs = 10*10^(-12); % 自由空间
Emp = 0.0013*10^(-12); % 多路径衰减
d0 = sqrt(Efs/Emp); % 距离阈值
EDA = 5*10^(-9); % 融合能耗,每bit
rmax = 1500; % 防止簇头过早死亡,需定期更换簇头,即为总轮数
CM = 100; % 控制信息大小,包含自己簇内需要转发的总的数据包个数
DM = 4000; % 要传输的信息大小,一个数据包Bit
w = 0.6;
alpha = 1;
beta = 2;
%%
for i = 1:n
figure(1);
%随机产生节点
S1(i).xd = rand(1,1)*xm;
S2(i).xd = S1(i).xd;
S3(i).xd = S2(i).xd;
S1(i).yd = rand(1,1)*ym;
S2(i).yd = S1(i).yd;
S3(i).yd = S2(i).yd;
S1(i).G = 0; % 若为0,标示当前节点可为簇头,每一周期全部置为0,重新指定全部簇头
S2(i).G = 0;
S3(i).G = 0;
S1(i).E = E0; % 设置初始化能量为E0
S2(i).E = E0;
S3(i).E = E0;
Elast(i) = S1(i).E;
S1(i).type = 'N'; % 节点类型为普通型
S2(i).type = 'N';
S3(i).type = 'N';
plot(S1(i).xd, S1(i).yd, 'bo');
hold on; % 保持所画的图像
end % 为每个节点随机分配坐标,并设置初始化能量为E0,节点类型为普通型
S1(n+1).xd = sink.x;
S1(n+1).yd = sink.y;
S2(n+1).xd = sink.x;
S2(n+1).yd = sink.y;
S3(n+1).xd = sink.x;
S3(n+1).yd = sink.y;
plot(S1(n+1).xd, S1(n+1).yd, 'x'); % 绘制基站节点
%%%%%%%%%%%%%%%%LEACH-ANT%%%%%%%%%%%%%%
% 死亡节点标志
flag_first_dead = 0;
flag_teenth_dead = 0;
flag_all_dead = 0;
% 死亡节点数
first_dead1 = 0;
teenth_dead1 = 0;
all_dead1 = 0;
% 活动节点数
alive1 = n;
% 传输到基站和簇头的比特计数器
packets_TO_BS1 = 0;
packets_TO_CH1 = 0;
Etotal = 0;
%% 迭代
for r = 0:rmax
r
% 如果轮数正好是一个周期的整数倍,则设置S(i).E为0---此时所有节点均参见竞争
if mod(r,round(1/p)) == 0 % round一个四舍五入函数
for i = 1:n
S1(i).G = 0;
end
end
cluster = 0; % 初始化簇头为0
dead = 0; % 初始死亡节点数0
Eavg = 0;
%%
for i = 1:n
if S1(i).E <= 0
dead = dead+1; % 节点死亡后变为红色,死亡节点数加一
if dead == 1 && flag_first_dead == 0
first_dead1 = r; % 第一个节点的死亡轮数
flag_first_dead = 1;
end
if dead == 0.1*n && flag_teenth_dead == 0
teenth_dead1 = r;
flag_teenth_dead = 1;
end
if dead == n && flag_all_dead == 0
all_dead1 = r;
flag_all_dead = 1;
end
else
S1(i).type = 'N';
Eavg = Eavg+S1(i).E;
end
end
Eavg = Eavg/n;
STATISTICS.DEAD1(r+1) = dead; % 每轮死亡节点数
STATISTICS.ALIVE1(r+1) = alive1-dead; % 每轮存活节点数
%% 获取簇头节点数组
for i = 1:n
Elast(i) = S1(i).E;
if S1(i).E > 0 && Eavg > 0
if S1(i).G <= 0
temp_rand = rand; % 取一个随机数
if temp_rand <= p/(1-p*mod(r,round(1/p)))*(S1(i).E/(w*Elast(i)+(1-w)*Eavg))
S1(i).type = 'C'; % 此节点为此轮簇头节点
S1(i).G = round(1/p)-1; % S(i).G设置为大于0,此周期不能再被选为簇头节点
cluster = cluster+1; % 簇头数加1
C(cluster).xd = S1(i).xd;
C(cluster).yd = S1(i).yd; % 将此节点标志为簇头
distance = sqrt((S1(i).xd-S1(n+1).xd)^2+(S1(i).yd-S1(n+1).yd)^2); % 簇头到基站的距离
C(cluster).distance = distance; % 标志位此簇头到基站的距离
C(cluster).id = i; % 此簇头节点的id
distanceBroad = sqrt(xm*xm+ym*ym);
if distanceBroad > d0
S1(i).E = S1(i).E- (Eelec*CM + Emp*CM*distanceBroad^4);
Etotal = Etotal + (Eelec*CM + Emp*CM*distanceBroad^4);
else
S1(i).E = S1(i).E- (Eelec*CM + Efs*CM*distanceBroad^2);
Etotal = Etotal + (Eelec*CM + Efs*CM*distanceBroad^2);
end
% plot(S1(i).xd, S1(i).yd, 'r*');
% hold on;
% 簇头发数据到基站
% if distance > d0
% S1(i).E = S1(i).E- ((Eelec+EDA)*DM+Emp*DM*distance^4);
% else
% S1(i).E = S1(i).E- ((Eelec+EDA)*DM+Efs*DM*distance^2);
% end
end
end
end
end
%% 普通节点选择簇头
for i = 1:n
if S1(i).type == 'N'&&S1(i).E > 0
if cluster > 0
min_dis = sqrt((S1(i).xd-C(1).xd)^2+(S1(i).yd-C(1).yd)^2); % 计算此节点到簇头1的距离
min_dis_cluster = 1; % 初始设置到簇头1的距离最近
for c = 2:cluster
temp = sqrt((S1(i).xd-C(c).xd)^2+(S1(i).yd-C(c).yd)^2);
if temp < min_dis
min_dis = temp;
min_dis_cluster = c;
end
end
% plot(S1(i).xd, S1(i).yd, 'bo');
% hold on;
% plot([S1(i).xd; S1(C(min_dis_cluster).id).xd], [S1(i).yd; S1(C(min_dis_cluster).id).yd], 'k--');
% hold on;
% 接收簇头发来的广播的消耗
S1(i).E = S1(i).E - Eelec*CM;
Etotal = Etotal+Eelec*CM;
% 加入簇
if min_dis > d0
S1(i).E = S1(i).E- (ETX*(DM+CM) + Emp*(DM+CM)*min_dis^4);
Etotal = Etotal+(ETX*(DM+CM) + Emp*(DM+CM)*min_dis^4);
else
S1(i).E = S1(i).E- (ETX*(DM+CM) + Efs*(DM+CM)*min_dis^2);
Etotal = Etotal+(ETX*(DM+CM) + Efs*(DM+CM)*min_dis^2);
end
packets_TO_CH1 = packets_TO_CH1+1;
% 簇头接收
S1(C(min_dis_cluster).id).E = S1(C(min_dis_cluster).id).E-((ERX+EDA)*DM+ERX*CM);
Etotal = Etotal+((ERX+EDA)*DM+ERX*CM);
% 如果只有一个簇头
if cluster == 1
dist = sqrt((C(1).xd-sink.x)^2+(C(1).yd-sink.y)^2);
if dist > d0
S1(C(1).id).E = S1(C(1).id).E-(ETX*DM + Emp*DM*dist^4);
Etotal = Etotal+(ETX*DM + Emp*DM*dist^4);
else
S1(C(1).id).E = S1(C(1).id).E-(ETX*DM + Efs*DM*dist^2);
Etotal = Etotal+(ETX*DM + Efs*DM*dist^2);
end
packets_TO_BS1 = packets_TO_BS1+1;
end
else % 无簇头选出
dist = sqrt((S1(i).xd-S1(n+1).xd)^2+(S1(i).yd-S1(n+1).yd)^2);
if dist > d0
S1(i).E = S1(i).E- (ETX*DM + Emp*DM*dist^4);
Etotal = Etotal+(ETX*DM + Emp*DM*dist^4);
else
S1(i).E = S1(i).E- (ETX*DM + Efs*DM*dist^2);
Etotal = Etotal+(ETX*DM + Efs*DM*dist^2);
end
packets_TO_BS1 = packets_TO_BS1+1;
end
end
end
%% 簇头路由生成
if cluster > 1
[Route, D] = ACCHRA1(S1, C, cluster, sink.x, sink.y, Eelec, Efs, Emp, DM, Eavg);
order = [C([Route]).id];
for i = 1:cluster-1
if i == 1
S1(order(i)).pos =