文章目录

  • 一、理论基础
  • 二、分簇过程
  • 三、MATLAB程序实现
  • 四、参考文献

固定簇半径的分簇协议HEED matlab代码_代码

二、分簇过程

固定簇半径的分簇协议HEED matlab代码_代码_02

三、MATLAB程序实现
%% 清空环境变量
clear;
clc;
% 传感器节点区域100×100
xm = 100;
ym = 100;
% 基站坐标
sink.x = 0.5*xm;
sink.y = 0.5*ym;
% 节点总数100
NodeNums = 100;
% 节点成为簇头的初始概率和概率阈值
Cprob = 0.05;
pmin = 0.04;
packetLength = 4000;      % 数据包长度
ctrPacketLength = 100;    % 控制包长度
% 初始能量(最大能量) 0.3J
Eo = 0.3;
% 发送能耗RTX = 接收能耗ERX = 50nJ/bit
ETX=50*10^(-9);
ERX=50*10^(-9);
% 发射放大器类型
Efs=10*10^(-12);
Emp=0.0013*10^(-12);
% 数据聚合能量
EDA=5*10^(-9);
% 最大轮数
rmax = 5;
% the time of round
Tr=20;
distanceBroad = sqrt(Tr^2+Tr^2);
% 临界距离
do = sqrt(Efs/Emp);
% 节点类型
NON_CH = 0;         % 普通节点
TENT_CH = 1;        % 临时簇头
FINAL_CH = 2;       % 最终簇头

figure(1);
%% 传感器节点的随机分布
for i = 1:NodeNums
    Node(i).xd = rand(1,1)*xm;
    Node(i).yd = rand(1,1)*ym;
    Node(i).RE = Eo;                  % 节点能量
    Node(i).NumNbr = 0;               % 邻居节点数
    Node(i).AMRP = Node(i).NumNbr;    % 平均可达能级
    Node(i).CH = 0;                   % 簇头
    Node(i).role = NON_CH;            % 节点角色
    plot(Node(i).xd, Node(i).yd, 'o', sink.x, sink.y, '*r');
    hold on;
    title 'Wireless Sensor Network';
    xlabel 'X-coordinates';
    ylabel 'Y-coordinates';
    legend('节点', '基站');
end
hold off;
%% 计算每个节点的邻居节点集
for i = 1:NodeNums
    count = 0;  % 计数器:用于统计每个节点的邻居节点总数
    for j = 1:NodeNums
        if j ~= i
            dist = sqrt((Node(i).xd-Node(j).xd).^2 + (Node(i).yd-Node(j).yd).^2);   % 节点i与节点j距离的平方
            if dist < distanceBroad  % 如果此距离小于广播半径,则可认为j是i的邻居节点
                count = count +1;
                Node(i).Nbr(count) = j; % j是i的一个邻居节点
            end
        end
        if j == NodeNums % 说明循环到了最后一个节点
            Node(i).NumNbr = count;     % 节点i的邻居节点个数count
        end
    end
end

%% 分簇阶段
for r = 1:rmax
%     % 死亡节点总数
%     dead = 0;
%     % 计算节点死亡数目
%     for i = 1:NodeNums
%         if Node(i).RE <= 0  % 统计节点死亡数目
%             dead = dead + 1;
%         end
%     end
%     if dead == NodeNums  % 节点全部死亡退出循环
%         break;
%     end
    s = 0;
    % 第一步:初始化
    for i = 1:NodeNums
        Node(i).RE = Eo;
        Node(i).CHprob = max(Cprob*(Node(i).RE/Eo), pmin);
        Node(i).AMRP = Node(i).NumNbr;    % 平均可达能级
        Node(i).CH = 0;
        Node(i).role = NON_CH;                     % 节点角色
        Node(i).stop = 1;
        s = s + Node(i).stop;
    end
    % 第二步:迭代,直至节点概率为1或节点死亡(能量耗尽)
    while s ~= 0
        s = 0;
        for i = 1:NodeNums
            Node(i).CHprob = max(Cprob*(Node(i).RE/Eo), pmin);
        end
        for i = 1:NodeNums
            if Node(i).RE > 0 && Node(i).CHprob <= 1
                flag0 = 0;
                flag1 = 0;
                for j = 1:Node(i).NumNbr
                    neighbor = Node(i).Nbr(j);
                    if Node(neighbor).role == TENT_CH
                        flag0 = 1;
                        if Node(i).AMRP > Node(neighbor).AMRP
                            flag1 = 1;
                        end
                    end
                end
                % 自身是临时簇头
                if Node(i).role == TENT_CH
                    if flag0 == 1 && flag1 == 0  % 周围有临时簇头且自身的AMRP值最小
                        if Node(i).CHprob == 1      % 概率为1
                            Node(i).CH = -1;
                            Node(i).RE = Node(i).RE-(ETX*ctrPacketLength+Efs*ctrPacketLength*distanceBroad^2);
                            % 邻居节点接收消息
                            for j = 1:Node(i).NumNbr
                                neighbor = Node(i).Nbr(j);
                                Node(neighbor).RE = Node(neighbor).RE-ERX*ctrPacketLength;
                            end
                        end
                    end
                end
                % 邻居节点无临时簇头
                if flag0 == 0
                    if rand <= Node(i).CHprob
                        Node(i).role = TENT_CH;
                        Node(i).RE = Node(i).RE-(ETX*ctrPacketLength+Efs*ctrPacketLength*distanceBroad^2);
                        % 邻居节点接收消息
                        for j = 1:Node(i).NumNbr
                            neighbor = Node(i).Nbr(j);
                            Node(neighbor).RE = Node(neighbor).RE-ERX*ctrPacketLength;
                        end
                    end
                end
                % 备选簇头状态
                if Node(i).CHprob < 1
                    Node(i).role = TENT_CH;
                    Node(i).RE = Node(i).RE-(ETX*ctrPacketLength+Efs*ctrPacketLength*distanceBroad^2);
                    x = Node(i).AMRP;
                    for j = 1:Node(i).NumNbr
                        neighbor = Node(i).Nbr(j);
                        Node(neighbor).RE = Node(neighbor).RE-ERX*ctrPacketLength;
                        if Node(neighbor).role ~= NON_CH    % 簇头节点
                            if Node(i).AMRP > Node(neighbor).AMRP   % AMRP值更小
                                Node(i).role = NON_CH;      % 改为普通节点
                                Node(i).CH = neighbor;       % 加入该候选簇头
                                Node(i).AMRP = Node(neighbor).AMRP;
                            end
                        end
                    end
                    Node(i).AMRP = x;
                else    % 最终簇头状态
                    Node(i).role = FINAL_CH;
                    Node(i).CH = -1;
                    Node(i).RE = Node(i).RE-(ETX*ctrPacketLength+Efs*ctrPacketLength*distanceBroad^2);
                    for j = 1:Node(i).NumNbr
                        neighbor = Node(i).Nbr(j);
                        Node(neighbor).RE = Node(neighbor).RE-ERX*ctrPacketLength;
                    end
                end
            else
                Node(i).stop = 0;
            end
            s = s+Node(i).stop;
            Node(i).CHprob = min(Node(i).CHprob * 2, 1);
        end
    end
    %% 第三,处理孤儿节点
    for i = 1:NodeNums
        if Node(i).RE > 0
            if Node(i).role ~= FINAL_CH
                flag = 0;
                for j = 1:Node(i).NumNbr
                    neighbor = Node(i).Nbr(j);
                    if Node(neighbor).role ~= NON_CH    % 簇头节点
                        flag = 1;
                        y = Node(i).AMRP;
                        if Node(i).AMRP > Node(neighbor).AMRP   % AMRP值更小
                            Node(i).role = NON_CH;      % 改为普通节点
                            Node(i).CH = neighbor;       % 加入该候选簇头
                            Node(i).AMRP = Node(neighbor).AMRP;
                        end
                    end
                end
                if flag == 0
                    Node(i).CH = -1;
                    Node(i).role = FINAL_CH;
                else
                    Node(i).AMRP = y;
                end
            end
        end
    end
    figure(r+1)
    %% 画出分簇图
    for i = 1:NodeNums
        if Node(i).role ~= NON_CH
            plot(Node(i).xd, Node(i).yd, '*'); % 簇头节点以*标记
            hold on
            text(Node(i).xd, Node(i).yd, num2str(i));
        else
            plot(Node(i).xd, Node(i).yd, 'o');   %普通节点以o标记
            text(Node(i).xd, Node(i).yd, num2str(i));
            hold on
            plot([Node(Node(i).CH).xd; Node(i).xd], [Node(Node(i).CH).yd; Node(i).yd]);  % 将节点与簇头连起来,即加入簇头集合
            hold on
        end
    end
end

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.

其中一个分簇如图所示:固定簇半径的分簇协议HEED matlab代码_代码_03

HEED分簇图

四、参考文献

[1] Younis O , Fahmy S . HEED: A Hybrid, Energy-Efficient, Distributed Clustering Approach for Ad Hoc Sensor Networks[J]. IEEE Transactions on Mobile Computing, 2004, 3(4):366-379.