基于改进蚁群算法的WSN路由优化研究

文章目录

一、理论基础

1、LEACH

请参考文献[1]。

2、LEACH-ANT

针对LEACH存在的缺陷,改进点主要有以下两点:

(1)阈值公式

首先改进LEACH协议的簇首选举规则。修改阈值 T i T_i Ti​的生成公式为: T i = { p 1 − p × ( r m o d ( 1 / p ) ) ( E i , c u r r e n t E i , t o t a l ) α ( E i , c u r r e n t E a v e ) β , i ∈ G 0 o t h e r w i s e (1) T_i=\begin{dcases}\frac{p}{1-p×(rmod(1/p))}\left(\frac{E_{i,current}}{E_{i,total}}\right)^\alpha \left(\frac{E_{i,current}}{E_{ave}}\right)^\beta,i∈G\\0\quad\quad\quad\quad\quad \quad\quad\quad\quad\quad otherwise\end{dcases}\tag{1} Ti​=⎩⎪⎨⎪⎧​1−p×(rmod(1/p))p​(Ei,total​Ei,current​​)α(Eave​Ei,current​​)β,i∈G0otherwise​(1)其中, E i , c u r r e n t E_{i,current} Ei,current​表示 i i i节点当前的能量, E i , t o t a l E_{i,total} Ei,total​表示节点的总能量, E i , a v e E_{i,ave} Ei,ave​表示网络中所有节点的平均能量, α \alpha α、 β \beta β为修正因子,取值范围为 1 ≤ α ≤ β ≤ 2 1≤\alpha≤\beta≤2 1≤α≤β≤2。

(2)能见度系数(启发函数)

其次,将蚁群算法中的能见度系数 η i j = 1 / d i j \eta_{ij}=1/d_{ij} ηij​=1/dij​更改为由距离和节点剩余能量共同决定;加入系数 α \alpha α ,主要是由于无线电传输模型中信号的衰减反比于距离的三次方,这里系数 γ \gamma γ可以在3~4间取值。 μ \mu μ为矫正系数,表示无线电信号在信道中的传播质量,一般 μ ≤ 1 \mu≤1 μ≤1。新的能见度系数 η i j = μ × 1 d i j   γ × E i , c u r r e n t E a v e (2) \eta_{ij}=\mu×\frac{1}{d_{ij}^{\,\gamma}}×\frac{E_{i,current}}{E_{ave}}\tag{2} ηij​=μ×dijγ​1​×Eave​Ei,current​​(2)

3、LEACH-IACA

(1)簇首建立阶段

阈值 T ( n ) T(n) T(n)的计算公式如下: T ( n ) = { p 1 − p [ r m o d ( 1 / p ) ] ⋅ E c u r r e n t ω E l a s t + ( 1 − ω ) E a v g , i f   n ∈ G 0 , o t h e r w i s e (3) T(n)=\begin{dcases}\frac{p}{1-p[rmod(1/p)]}\boldsymbol\cdot\frac{E_{current}}{\omega E_{last}+(1-\omega)E_{avg}},if\, n∈G\\0,otherwise\end{dcases}\tag{3} T(n)=⎩⎨⎧​1−p[rmod(1/p)]p​⋅ωElast​+(1−ω)Eavg​Ecurrent​​,ifn∈G0,otherwise​(3)式中, p p p表示簇首在所有节点中所占的百分比; r r r是选举轮数; G G G表示本轮循环中未当选过簇首的节点集合; E c u r r e n t E_{current} Ecurrent​表示本轮节点的剩余能量; E l a s t E_{last} Elast​表示上轮该节点的剩余能量; E a v g E_{avg} Eavg​表示当前所有节点的平均剩余能量,公式如下: E a v g = ∑ i = 1 n E i n (4) E_{avg}=\frac{\displaystyle\sum_{i=1}^nE_i}{n}\tag{4} Eavg​=ni=1∑n​Ei​​(4)

(2)簇间传输阶段

参考文献[3]4.2.2部分内容。

二、仿真与分析

基于改进蚁群算法的WSN路由优化研究

图1 存活节点个数

基于改进蚁群算法的WSN路由优化研究

图2 簇头接收数据包的数量

基于改进蚁群算法的WSN路由优化研究

图3 基站接收数据包的数量

具体代码如下:

%% 清空环境变量
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;

%% 迭代
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);
                    else
                        S1(i).E = S1(i).E- (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;
                % 加入簇
                if min_dis > d0
                    S1(i).E = S1(i).E- (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);
                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);
                % 如果只有一个簇头
                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);
                    else
                        S1(C(1).id).E = S1(C(1).id).E-(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);
                else
                    S1(i).E = S1(i).E- (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 = 0;    % pos=0 表示位于起点
            else
                S1(order(i)).pos = 1;     % pos=0 表示位于中间
            end         
            S1(order(i)).dis = sqrt((S1(order(i)).xd-S1(order(i+1)).xd)^2+(S1(order(i)).yd-S1(order(i+1)).yd)^2);
%             S1(order(i)).dis = D(Route(i), Route(i+1));
%             plot([S1(order(i)).xd; S1(order(i+1)).xd], [S1(order(i)).yd; S1(order(i+1)).yd], 'o-');
%             hold on;
        end
%         plot([S1(order(cluster)).xd; sink.x], [S1(order(cluster)).yd; sink.y], 'o-');
%         hold on;
%         plot(sink.x, sink.y, '*');
        S1(order(cluster)).pos = 2;      % pos=2 表示位于终点
        S1(order(cluster)).dis = sqrt((S1(order(cluster)).xd-sink.x)^2+(S1(order(cluster)).yd-sink.y)^2);
        for i = 1:cluster
%             if S1(order(i)).E > 0 
                % 起点
                if S1(order(i)).pos == 0
                    if S1(order(i)).dis > d0
                        ETx = (Eelec+EDA)*DM + Emp*DM*S1(order(i)).dis^4;
                    else
                        ETx = (Eelec+EDA)*DM + Efs*DM*S1(order(i)).dis^2;
                    end
                    S1(order(i)).E = S1(order(i)).E - ETx;
                    packets_TO_CH1 = packets_TO_CH1+1;
                end
                % 中间节点
                if S1(order(i)).pos == 1
                    ERx = (EDA+ETX)*DM;
                    if S1(order(i)).dis > d0
                        ETx = (Eelec+EDA)*DM + Emp*DM*S1(order(i)).dis^4;
                    else
                        ETx = (Eelec+EDA)*DM + Efs*DM*S1(order(i)).dis^2;
                    end
                    S1(order(i)).E = S1(order(i)).E - ETx;
                    packets_TO_CH1 = packets_TO_CH1+1;
                end
                % 终点
                if S1(order(i)).pos == 2
                    ERx = (EDA+ETX)*DM;
                    if S1(order(i)).dis > d0
                        ETx = (Eelec+EDA)*DM + Emp*DM*S1(order(i)).dis^4;
                    else
                        ETx = (Eelec+EDA)*DM + Efs*DM*S1(order(i)).dis^2;
                    end
                    S1(order(i)).E = S1(order(i)).E-ETx;
                    packets_TO_BS1 = packets_TO_BS1+1;
                end
%             end
        end
    end
    STATISTICS.PACKETS_TO_CH1(r+1) = packets_TO_CH1;
    STATISTICS.PACKETS_TO_BS1(r+1) = packets_TO_BS1;
end
%%%%%%%%%%%%%%%%LEACH%%%%%%%%%%%%%%
% 死亡节点标志
flag_first_dead = 0;
flag_teenth_dead = 0;
flag_all_dead = 0;
% 死亡节点数
first_dead2 = 0;
teenth_dead2 = 0;
all_dead2 = 0;
% 活动节点数
alive2 = n;
% 传输到基站和簇头的比特计数器
packets_TO_BS2 = 0;
packets_TO_CH2 = 0;
%% 迭代
for r = 0:rmax
    r
    % 如果轮数正好是一个周期的整数倍,则设置S(i).E为0---此时所有节点均参见竞争
    if mod(r,round(1/p)) == 0          % round一个四舍五入函数
        for i = 1:n
            S2(i).G = 0;
        end
    end
    cluster = 0;         % 初始化簇头为0
    dead = 0;            % 初始死亡节点数0
    % 重新绘制整体节点
    %%
    for i = 1:n
        if S2(i).E <= 0
            dead = dead+1;     % 节点死亡后变为红色,死亡节点数加一
            if dead == 1 && flag_first_dead == 0
                first_dead2 = r;       % 第一个节点的死亡轮数
                flag_first_dead = 1;
            end
            if dead == 0.1*n && flag_teenth_dead == 0
                teenth_dead2 = r;
                flag_teenth_dead = 1;
            end
            if dead == n && flag_all_dead == 0
                all_dead2 = r;
                flag_all_dead = 1;
            end
        else
            S2(i).type = 'N';
        end
    end
    STATISTICS.DEAD2(r+1) = dead;              % 每轮死亡节点数
    STATISTICS.ALIVE2(r+1) = alive2-dead;     % 每轮存活节点数
    %% 获取簇头节点数组
    for i = 1:n
        if S2(i).E > 0
            if S2(i).G <= 0   
                temp_rand = rand;    % 取一个随机数
                if temp_rand <= p/(1-p*mod(r,round(1/p)))  
                    S2(i).type = 'C';                    % 此节点为此轮簇头节点
                    S2(i).G = round(1/p)-1;       % S(i).G设置为大于0,此周期不能再被选为簇头节点
                    cluster = cluster+1;            % 簇头数加1
                    C(cluster).xd = S2(i).xd;
                    C(cluster).yd = S2(i).yd;        % 将此节点标志为簇头
                    distance = sqrt((S2(i).xd-S2(n+1).xd)^2+(S2(i).yd-S2(n+1).yd)^2);   % 簇头到基站的距离
                    C(cluster).distance = distance;    % 标志位此簇头到基站的距离
                    C(cluster).id = i;                          % 此簇头节点的id
                    distanceBroad = sqrt(xm*xm+ym*ym);
                    % 簇头广播
                    if distanceBroad > d0
                        S2(i).E = S2(i).E- (Eelec*CM + Emp*CM*distanceBroad^4);
                    else
                        S2(i).E = S2(i).E- (Eelec*CM + Efs*CM*distanceBroad^2);
                    end
                    % 簇头发数据到基站
                    if distance > d0
                        S2(i).E = S2(i).E- ((Eelec+EDA)*DM+Emp*DM*distance^4);
                    else
                        S2(i).E = S2(i).E- ((Eelec+EDA)*DM+Efs*DM*distance^2);
                    end
                    packets_TO_BS2 = packets_TO_BS2+1;
                end
            end
        end
    end
    %% 普通节点选择簇头
    for i = 1:n
        if S2(i).type == 'N'&&S2(i).E > 0     
            if cluster > 0
                min_dis = inf;   % 计算此节点到簇头1的距离
                min_dis_cluster = 0;    % 初始设置到簇头1的距离最近
                for c = 1:cluster
                    temp = sqrt((S2(i).xd-C(c).xd)^2+(S2(i).yd-C(c).yd)^2);
                    if temp < min_dis
                        min_dis = temp;
                        min_dis_cluster = c;
                    end
                end
                % 接收簇头发来的广播的消耗
                S2(i).E = S2(i).E - ERX*CM;
                % 加入簇
                if min_dis > d0
                    S2(i).E = S2(i).E- (ETX*(DM+CM) + Emp*(DM+CM)*min_dis^4);
                else
                    S2(i).E = S2(i).E- (ETX*(DM+CM) + Efs*(DM+CM)*min_dis^2);
                end
                % 簇头接收
                S2(C(min_dis_cluster).id).E = S2(C(min_dis_cluster).id).E-((ERX+EDA)*DM+ERX*CM);
                packets_TO_CH2 = packets_TO_CH2+1;
            else   % 无簇头选出
                dist = sqrt((S2(i).xd-S2(n+1).xd)^2+(S2(i).yd-S2(n+1).yd)^2);
                if dist > d0
                    S2(i).E = S2(i).E- (ETX*DM + Emp*DM*dist^4);
                else
                    S2(i).E = S2(i).E- (ETX*DM + Efs*DM*dist^2);
                end
                packets_TO_BS2 = packets_TO_BS2+1;
            end
        end
    end
    STATISTICS.PACKETS_TO_CH2(r+1) = packets_TO_CH2;
    STATISTICS.PACKETS_TO_BS2(r+1) = packets_TO_BS2;
end
%%%%%%%%%%%%%%%%LEACH-ANT%%%%%%%%%%%%%%
% 死亡节点标志
flag_first_dead = 0;
flag_teenth_dead = 0;
flag_all_dead = 0;
% 死亡节点数
first_dead3 = 0;
teenth_dead3 = 0;
all_dead3 = 0;
% 活动节点数
alive3 = n;
% 传输到基站和簇头的比特计数器
packets_TO_BS3 = 0;
packets_TO_CH3 = 0;
%% 迭代
for r = 0:rmax
    r
    % 如果轮数正好是一个周期的整数倍,则设置S(i).E为0---此时所有节点均参见竞争
    if mod(r,round(1/p)) == 0          % round一个四舍五入函数
        for i = 1:n
            S3(i).G = 0;
        end
    end
    cluster = 0;         % 初始化簇头为0
    dead = 0;            % 初始死亡节点数0
    Eavg = 0;
    % 重新绘制整体节点
    %%
    for i = 1:n
        if S3(i).E <= 0
            dead = dead+1;     % 节点死亡后变为红色,死亡节点数加一
            if dead == 1 && flag_first_dead == 0
                first_dead3 = r;       % 第一个节点的死亡轮数
                flag_first_dead = 1;
            end
            if dead == 0.1*n && flag_teenth_dead == 0
                teenth_dead3 = r;
                flag_teenth_dead = 1;
            end
            if dead == n && flag_all_dead == 0
                all_dead3 = r;
                flag_all_dead = 1;
            end
        else
            S3(i).type = 'N';
            Eavg = Eavg+S3(i).E;
        end
    end
    Eavg = Eavg/n;
    STATISTICS.DEAD3(r+1) = dead;              % 每轮死亡节点数
    STATISTICS.ALIVE3(r+1) = alive2-dead;     % 每轮存活节点数
    %% 获取簇头节点数组
    for i = 1:n
        if S3(i).E > 0
            if S3(i).G <= 0   
                temp_rand = rand;    % 取一个随机数
                if temp_rand <= p/(1-p*mod(r,round(1/p)))*(S3(i).E/E0)^alpha*(S3(i).E/Eavg)^beta  
                    S3(i).type = 'C';                    % 此节点为此轮簇头节点
                    S3(i).G = round(1/p)-1;       % S(i).G设置为大于0,此周期不能再被选为簇头节点
                    cluster = cluster+1;            % 簇头数加1
                    C(cluster).xd = S3(i).xd;
                    C(cluster).yd = S3(i).yd;        % 将此节点标志为簇头
                    distance = sqrt((S3(i).xd-S3(n+1).xd)^2+(S3(i).yd-S3(n+1).yd)^2);   % 簇头到基站的距离
                    C(cluster).distance = distance;    % 标志位此簇头到基站的距离
                    C(cluster).id = i;                          % 此簇头节点的id
                    distanceBroad = sqrt(xm*xm+ym*ym);
                    % 簇头广播
                    if distanceBroad > d0
                        S2(i).E = S2(i).E- (Eelec*CM + Emp*CM*distanceBroad^4);
                    else
                        S2(i).E = S2(i).E- (Eelec*CM + Efs*CM*distanceBroad^2);
                    end
                end
            end
        end
    end
    %% 普通节点选择簇头
    for i = 1:n
        if S3(i).type == 'N'&&S3(i).E > 0     
            if cluster > 0
                min_dis = sqrt((S3(i).xd-C(1).xd)^2+(S3(i).yd-C(1).yd)^2);   % 计算此节点到簇头1的距离
                min_dis_cluster = 1;    % 初始设置到簇头1的距离最近
                for c = 2:cluster
                    temp = sqrt((S3(i).xd-C(c).xd)^2+(S3(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;
                % 接收簇头发来的广播的消耗
                S3(i).E = S3(i).E - Eelec*CM;
                % 加入簇
                if min_dis > d0
                    S3(i).E = S3(i).E- (ETX*(DM+CM) + Emp*(DM+CM)*min_dis^4);
                else
                    S3(i).E = S3(i).E- (ETX*(DM+CM) + Efs*(DM+CM)*min_dis^2);
                end
                packets_TO_CH3 = packets_TO_CH3+1;
                % 簇头接收
                S3(C(min_dis_cluster).id).E = S3(C(min_dis_cluster).id).E-((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
                        S3(C(1).id).E = S3(C(1).id).E-(ETX*DM + Emp*DM*dist^4);
                    else
                        S3(C(1).id).E = S3(C(1).id).E-(ETX*DM + Efs*DM*dist^2);
                    end
                    packets_TO_BS3 = packets_TO_BS3+1;
                end
            else   % 无簇头选出
                dist = sqrt((S3(i).xd-S3(n+1).xd)^2+(S3(i).yd-S3(n+1).yd)^2);
                if dist > d0
                    S3(i).E = S3(i).E- (ETX*DM + Emp*DM*dist^4);
                else
                    S3(i).E = S3(i).E- (ETX*DM + Efs*DM*dist^2);
                end
                packets_TO_BS3 = packets_TO_BS3+1;
            end
        end
    end
    %% 簇头路由生成
    if cluster > 1
        [Route, D] = ACCHRA(S3, C, cluster, sink.x, sink.y, Eavg);
        order = [C([Route]).id];      
        for i = 1:cluster-1
            if i == 1
                S3(order(i)).pos = 0;    % pos=0 表示位于起点
            else
                S3(order(i)).pos = 1;     % pos=0 表示位于中间
            end         
            S3(order(i)).dis = sqrt((S3(order(i)).xd-S3(order(i+1)).xd)^2+(S3(order(i)).yd-S3(order(i+1)).yd)^2);
%             S1(order(i)).dis = D(Route(i), Route(i+1));
%             plot([S1(order(i)).xd; S1(order(i+1)).xd], [S1(order(i)).yd; S1(order(i+1)).yd], 'o-');
%             hold on;
        end
%         plot([S1(order(cluster)).xd; sink.x], [S1(order(cluster)).yd; sink.y], 'o-');
%         hold on;
%         plot(sink.x, sink.y, '*');
        S3(order(cluster)).pos = 2;      % pos=2 表示位于终点
        S3(order(cluster)).dis = sqrt((S3(order(cluster)).xd-sink.x)^2+(S3(order(cluster)).yd-sink.y)^2);
        for i = 1:cluster
%             if S1(order(i)).E > 0 
                % 起点
                if S3(order(i)).pos == 0
                    if S3(order(i)).dis > d0
                        ETx = (Eelec+EDA)*DM + Emp*DM*S3(order(i)).dis^4;
                    else
                        ETx = (Eelec+EDA)*DM + Efs*DM*S3(order(i)).dis^2;
                    end
                    S3(order(i)).E = S3(order(i)).E - ETx;
                end
                % 中间节点
                if S3(order(i)).pos == 1
                    ERx = (EDA+ETX)*DM;
                    if S3(order(i)).dis > d0
                        ETx = (Eelec+EDA)*DM + Emp*DM*S3(order(i)).dis^4;
                    else
                        ETx = (Eelec+EDA)*DM + Efs*DM*S3(order(i)).dis^2;
                    end
                    S3(order(i)).E = S3(order(i)).E - ETx;
                    packets_TO_CH3 = packets_TO_CH3+1;
                end
                % 终点
                if S3(order(i)).pos == 2
                    ERx = (EDA+ETX)*DM;
                    if S1(order(i)).dis > d0
                        ETx = (Eelec+EDA)*DM + Emp*DM*S3(order(i)).dis^4;
                    else
                        ETx = (Eelec+EDA)*DM + Efs*DM*S3(order(i)).dis^2;
                    end
                    S3(order(i)).E = S3(order(i)).E-ETx;
                    packets_TO_BS3 = packets_TO_BS3+1;
                end
%             end
        end
    end
    STATISTICS.PACKETS_TO_CH3(r+1) = packets_TO_CH3;
    STATISTICS.PACKETS_TO_BS3(r+1) = packets_TO_BS3;
end
%% 绘图比较
figure;
r = 0:rmax;
plot(r, STATISTICS.ALIVE1, 'r', r, STATISTICS.ALIVE3, 'g', r, STATISTICS.ALIVE2, 'b', 'linewidth', 2);
legend('LEACH-IACA', 'LEACH-ANT', 'LEACH');
xlabel '时间(轮)'; ylabel '存活节点数/个';
grid on;
figure;
r = 0:rmax;
plot(r, STATISTICS.PACKETS_TO_CH1, 'r', r, STATISTICS.PACKETS_TO_CH3, 'g',...
    r, STATISTICS.PACKETS_TO_CH2, 'b', 'linewidth', 2);
legend('LEACH-IACA', 'LEACH-ANT', 'LEACH');
xlabel '时间(轮)'; ylabel '簇头接收数据包的数量/个';
grid on;
figure;
r = 0:rmax;
plot(r, STATISTICS.PACKETS_TO_BS1, 'r', r, STATISTICS.PACKETS_TO_BS3, 'g',...
    r, STATISTICS.PACKETS_TO_BS2, 'b', 'linewidth', 2);
legend('LEACH-IACA', 'LEACH-ANT', 'LEACH');
xlabel '时间(轮)'; ylabel '基站接收数据包的数量/个';
grid on;

三、参考文献

[1] Heinzelman W R , Chandrakasan A , Balakrishnan H . Energy-Efficient Protocol for Wireless Microsensor Networks[C]// hicss. IEEE Computer Society, 2000.
[2] 郦元宏, 王泽民. 基于蚁群算法的LEACH协议在WSN中的研究[J]. 声学与电子工程, 2017, 000(003):37-39.
[3] 方正. 基于改进蚁群算法的WSN路由优化研究[D].重庆邮电大学,2020.

上一篇:Visual C++免注册调用大漠插件


下一篇:达梦(DM)数据库Linux部署安装